1、基于STM32的音樂噴泉
文章目錄
- 1、基于STM32的音樂噴泉
- Introduction
- 引言
- 1、系統概述
- 1.1、設計任務
- 1.2、設計要求
- 2、 方案設計
- 2.1、芯片選擇方案
- 2.2、 系統概述:
- 2.3、系統總體設計思路
- 2.4、各功能模塊程式實作原理分析
- 2.4.1.水泵驅動模塊
- 2.4.2輸入音頻功率放大模塊
- 3 、STM32性能介紹及硬體設計
- 3.1、 STM32單片機性能介紹
- 3.2、音樂噴泉系統硬體設計\
- 4、 系統程式
- 4.1、主程式設計如下
- 4.2 主程式內容
- 5、系統除錯及分析
- 5.1、系統除錯
- 5.2、除錯現象及分析
- 5.3、測驗結果
Introduction
With the improvement of people’s living standards and the yearning to build a green city, musical fountains have become an important product in the leisure and entertainment industry with their unique charm and special functions, and more and more musical fountains have been built. According to the current development status of musical fountains, a small musical fountain control system with STM32F103C8T6 microcontroller as the core is introduced. Gives a simple single-chip control circuit, analyzes the audio output circuit and input circuit; introduces the principle of obtaining the spray pool data that determines the action of the spray pool from the audio signal of a specific structure; gives the main program block diagram and the use of program control To control the pattern. The audio signal also affects the changes in the brightness of the light. So that the flickering of the lights and the water posture of the fountain change with the rhythm of the music.
引言
隨著人們生活水平的提高和建立綠色城市的向往,音樂噴泉以其獨特的魅力和特殊的功能,愈來愈成為休閑娛樂產業中的一項重要產品,音樂噴泉的興建也越來越多,根據目前音樂噴泉的發展現狀,介紹了一個以STM32F103C8T6單片機為核心的小型音樂噴泉控制系統,給出了一個簡潔的單片機控制電路,分析了音頻輸出電路和輸入電路;介紹了從特定構造的音頻信號中獲得決定噴池動作的噴池資料的原理;給出了主程式框圖和采用程式控制來控制花型,音頻信號還影響燈光光線明暗的變化,從而使燈光的閃爍和噴泉水姿隨音樂節奏而變化,
1、系統概述
1.1、設計任務
用STM32設計一個噴泉音樂盒
1.2、設計要求
基于STM32單片機音樂噴泉設計 音樂盒播放器頻譜彩燈電子設計
-
1.可以播放電腦、手機、MP3里面的音樂,
-
2.產品具有8個LED頻譜彩燈,隨音樂變化閃爍,
-
3.音樂停止,噴水電機停止作業,
-
4.AD對音頻信號的采集,轉換為數字信號給單片機PWM控制水泵,實作水柱高低變化,
2、 方案設計
2.1、芯片選擇方案
STM32單片機是整個溫度控制系統的核心部分,因為對溫度控制器具有較高的要求,例如高執行速度,高控制精度,高穩定性以及高靈敏度等,所以選擇一個具有較高性能而又經濟的單片機就成為必然,本設計選用屬于STM32系列的STM32F103C8T6單片機作為控制電路的核心部件,該單片機屬于ST意法半導體公司生產的32位高性能、低成本、低功耗的增強型系列單片機,它的內核采用的是ARM公司最新研發的Cortex-M3架構,該內核是專門設計于滿足用戶對高性能、低功耗和經濟實用的要求,
2.2、 系統概述:
STM32F103C8T6單片機有3個不同的時鐘源可供選擇用以驅動系統時鐘,分別為HSI振蕩器時鐘、HSE振蕩器時鐘和PLL時鐘,這些設備還具有2個二級時鐘源,分別是40KHz的低速內部RC和32.768KHz的低速外部時鐘源,可以用來驅動看門狗時鐘和RTC,任何一個時鐘源在不被使用時,都可以被獨立的關倍訓者開啟,以實作對系統功耗的優化,
2.3、系統總體設計思路
通過單片機程式來控制噴泉的水姿變化,成為一種新的噴泉藝術形式,單片機作為一種控制用微處理器,包含有基本的軟硬體資源,本文采用了單片機控制技術,給出了單片機控制電路,水泵控制電路,流水燈控制電路及部分單片機I/O口初始化程式,單片機的輸出通過數模轉換通過水泵驅動電路驅動水泵,通過變頻調速技術對電泵進行調速,實作程式控制噴泉的高度,不僅能夠進行多種水型切換,而且能控制噴泉水柱上下起伏,同時單片機通過I/O來控制LED燈的亮滅,實作了對噴泉的水、光協同控制,
2.4、各功能模塊程式實作原理分析
系統主要有STM32F103C8T6單片機和、音頻功率放大電流和水泵驅動電路等組成,
2.4.1.水泵驅動模塊
根據單片機的電流特性,不足以直接驅動水泵,有三極管的輸出特性,利用晶體管的飽和和截止特性構成開關電路,通過二級三極管電流放大實作對水泵控制,P20為高電平時基極與集電極之間反向偏置,不導通;當P20為低電平時,基極與集電極之間正向偏置,導通,電路作業,水泵作業作業,單片機只需要吸收嬌小的輸入電流,
2.4.2輸入音頻功率放大模塊
LM386是低電壓小功率音頻放大集成電路,采用8腳雙列直插式塑封包裝電路特點
-
1、外接元件極少,不需要用輸入耦合電容;
-
2、負反饋電路在內部,增益有兩種26db46db可供選用;
-
3、輸入級采用儀表用放大器的形式,帶有同相輸入和反響輸入兩個引腳4靜態功耗小,當電源電壓為6伏時,靜態功耗為24mw
1與8腳為增益調整端,當兩腳開路時,電壓放大數為20倍,當兩腳間接10uf電容時,電壓放大倍數為200倍;2腳為反相輸入端;3腳為同相輸入端;4腳為地端;5腳為輸出端;6腳為電源正端;7腳為旁路端;6腳與地之間接10uf電容可消除可能產生的自激震蕩,如無震蕩7腳可懸空不接,
3 、STM32性能介紹及硬體設計
3.1、 STM32單片機性能介紹
STM32它擁有的資源包括:48KB SRAM、256KB FLASH、2 個基本定時器、4 個通用定時器、2個高級定時器、2個DMA 控制器(共 12 個通道)、3 個SPI、2個IIC、5個串口、1個USB、1個CAN、3個12位ADC、1個12位DAC、1個SDIO介面及51 個通用IO口,該芯片性價比極高,
各個引腳說明如下:
-
PA0 作用1,按鍵 KEY_UP 2,可以做待機喚醒腳(WKUP) 3,可以接 DS18B20 傳感器介面(P2 設定)
-
PA1作用1,NRF24L01 介面 IRQ 信號 2,接 HS0038 紅外接收頭(P2 設定)
-
PA2 作用 作為W25Q64 的片選信號
-
PA3 作用 作為SD 卡介面的片選腳
-
PA4 作用 作為NRF24L01 介面的 CE 信號
-
PA5 作用 作為W25Q64、SD 卡和 NRF24L01 介面的 SCK 信號
-
PA6 作用 作為 W25Q64、SD 卡和 NRF24L01 介面的 MISO 信號
-
PA7 作用 作為 W25Q64、SD 卡和 NRF24L01 介面的 MOSI 信號
-
PA8 作用 作為 接 DS0 LED 燈(紅色)
-
PA9 作用 作為串口 1 TX 腳,默認連接 CH340 的 RX(P4 設定)
-
PA10 作用 作為串口 1 RX 腳,默認連接 CH340 的 TX(P4 設定)
-
PA11 作用 作為接 USB D-引腳
-
PA12 作用 作為接 USB D+引腳
-
PA13作用 作為JTAG/SWD 仿真介面,沒接任何外設
-
PA14 作用 作為JTAG/SWD 仿真介面,沒接任何外設
-
PA15 作用 作為1,JTAG 仿真口(JTDI) 2,PS/2 介面的 CLK 信號 3,接按鍵 KEY1
3.2、音樂噴泉系統硬體設計\
該程式所需要的電源電路,功率放大電路,音頻輸入電路,LED燈顯示電路,水泵驅動電路,次如下圖所示

圖1.1電源電路圖如下圖

圖1.2 功率放大電路圖如下圖

圖1.3音頻輸入電路圖如下圖

圖1.4 LED電路圖如下圖

圖1.5 水泵驅動電路圖如下圖
4、 系統程式
4.1、主程式設計如下
音樂噴泉系統主要由單片機通過紅外通信控制,當其完成紅外信號,讀取資料,其資料的傳輸根據協議的內容,音樂噴泉系統程式需要完成以下的功能:
-
1、led燈隨音頻信號起伏;
-
2、水泵的噴水量隨音量的變化而變化,
程式流程圖如下:

圖1.5主程式流程設計圖
4.2 主程式內容
#include "main.h"
#include "stm32f1xx_hal.h"
/* USER CODE BEGIN Includes */
#include <math.h>
#include <stdio.h>
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
IWDG_HandleTypeDef hiwdg;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
//宏定義燈IO
#define LED0_0 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_RESET)
#define LED0_1 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET)
#define LED1_0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET)
#define LED1_1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET)
#define LED2_0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET)
#define LED2_1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET)
#define LED3_0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET)
#define LED3_1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET)
#define LED4_0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET)
#define LED4_1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET)
#define LED5_0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET)
#define LED5_1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET)
#define LED6_0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)
#define LED6_1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)
#define LED7_0 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)
#define LED7_1 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)
unsigned char PWM_falg=1;
uint8_t ch;
uint8_t ch_r;
//重寫這個函式,重定向printf函式到串口,意思就是說printf直接輸出到串口,其默認輸出到控制臺的
/*fputc*/
int fputc(int c, FILE * f)
{
ch=c;
HAL_UART_Transmit(&huart1,&ch,1,1000);//發送串口
return c;
}
//重定向scanf函式到串口 意思就是說接受串口發過來的資料,其默認是接受控制臺的資料
/*fgetc*/
int fgetc(FILE * F)
{
HAL_UART_Receive (&huart1,&ch_r,1,0xffff);//接收
return ch_r;
}
//#######################################################################################################//
//下面定義關于串口的
unsigned char Uart1_Buff[1024]; //串口1緩沖陣列
unsigned char Uart1_Count=0; //串口1累加變數
uint8_t aRxBuffer[3]; //定義一個暫存陣列
//下面定義關于定時器的
unsigned int Time4_ms=0;
//下面定義關于讀取ADC的
unsigned char Scan_Fre=0;
unsigned int ADC_Dat=0;
//下面定義啟停部分
unsigned char Open_Close=1;
unsigned char System_Count=0;
unsigned int Open_Flsh=0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM4_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM3_Init(void);
static void MX_IWDG_Init(void);
static void MX_USART1_UART_Init(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
struct Complex {
char real;//實部
char imag;//虛部
}; //構造復數結構
typedef struct Complex COMPLEX;
#define N 128 //FFT點數(長度)
#define PI2 128 //一周期分成128點
COMPLEX S[N]; //FFT復數陣列
unsigned char iw[128]={0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,10,11,11,12,12,12,13,13,14,14,14,15,15,15,16,16,16,17,17,17,17,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,23,24,24,24,24,25,25,25,25,25,26,26,26,26,26,27,27,27,27,27,27,28,28,28,28,28,29,29,29,29,29,29,30,30,30,30,30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31};
char costab[PI2]={
127,127,127,126,125,124,122,120,118,115,112,109,106,102,
98,94,90,85,81,76,71,65,60,54,48,43,37,31,24,18,12,6,0,
-6,-12,-18,-24,-31,-37,-43,-48,-54,-60,-65,-71,-76,-81,
-85,-90,-94,-98,-102,-106,-109,-112,-115,-118,-120,-122,
-124,-125,-126,-127,-127,-128,-127,-127,-126,-125,-124,
-122,-120,-118,-115,-112,-109,-106,-102,-98,-94,-90,-85,
-81,-76,-71,-65,-60,-54,-48,-43,-37,-31,-24,-18,-12,-6,0,
6,12,18,24,31,37,43,48,54,60,65,71,76,81,85,90,94,98,
102,106,109,112,115,118,120,122,124,125,126,127,127
//127,127,126,126,125,123,122,120,117,115,112,109,106,102,
//98,94,90,85,81,76,71,65,60,54,49,43,37,31,25,19,12,6,0,
//-6,-12,-19,-25,-31,-37,-43,-49,-54,-60,-65,-71,-76,-81,
//-85,-90,-94,-98,-102,-106,-109,-112,-115,-117,-120,-122,
//-123,-125,-126,-126,-127,-127,-127,-126,-126,-125,-123,
//-122,-120,-117,-115,-112,-109,-106,-102,-98,-94,-90,-85,
//-81,-76,-71,-65,-60,-54,-49,-43,-37,-31,-25,-19,-12,-6,
//0,6,12,19,25,31,37,43,49,54,60,65,71,76,81,85,90,94,98,
//102,106,109,112,115,117,120,122,123,125,126,126,127
};
char sintab[PI2]={
0,6,12,18,24,31,37,43,48,54,60,65,71,76,81,85,90,94,98,
102,106,109,112,115,118,120,122,124,125,126,127,127,128,
127,127,126,125,124,122,120,118,115,112,109,106,102,98,
94,90,85,81,76,71,65,60,54,48,43,37,31,24,18,12,6,0,-6,
-12,-18,-24,-31,-37,-43,-48,-54,-60,-65,-71,-76,-81,-85,
-90,-94,-98,-102,-106,-109,-112,-115,-118,-120,-122,-124,
-125,-126,-127,-127,-128 ,-127,-127,-126,-125,-124,-122,
-120,-118,-115,-112,-109,-106,-102,-98,-94,-90,-85,-81,
-76,-71,-65,-60,-54,-48,-43,-37,-31,-24,-18,-12,-6
//0,6,12,19,25,31,37,43,49,54,60,65,71,76,81,85,90,94,98,
//102,106,109,112,115,117,120,122,123,125,126,126,127,127,
//127,126,126,125,123,122,120,117,115,112,109,106,102,98,
//94,90,85,81,76,71,65,60,54,49,43,37,31,25,19,12,6,0,-6,
//-12,-19,-25,-31,-37,-43,-49,-54,-60,-65,-71,-76,-81,-85,
//-90,-94,-98,-102,-106,-109,-112,-115,-117,-120,-122,-123,
//-125,-126,-126,-127,-127,-127,-126,-126,-125,-123,-122,
//-120,-117,-115,-112,-109,-106,-102,-98,-94,-90,-85,-81,
//-76,-71,-65,-60,-54,-49,-43,-37,-31,-25,-19,-12,-6
};
/****************************************************
x:輸入資料實部,輸出資料實部(有符號數)
y:輸入資料虛部,輸出資料虛部(有符號數)
n:點數
*************************************************/
void fft(COMPLEX *XX,unsigned char n)
{//x[]為實部,y[]為虛部(全為0),n為點數
int tr,ti,p,q;
unsigned char i,j,k,qn,a,b,c,cen,zu,ge;
a=n-1;
for(i=0,j=0;i<a;i++)//回圈n-1次
{
if(i<j)
{
tr=XX[j].real;
XX[j].real=XX[i].real;
XX[i].real=tr;
ti=XX[j].imag;
XX[j].imag=XX[i].imag;
XX[i].imag=ti;
}//交換x[i]<->x[j],y[i]<->y[j]
k=n/2;
while(k<(j+1))
{
j=j-k;
k=k/2;
}
j=j+k;
}//此回圈把原序列變成2點奇偶序列
/****************************************/
for(i=1,j=1;i<8;i++)
{
j=2*j;//j=2^p
if(j>=n)break;
}
//2的i次方=n
cen=i; //如果n=8,則cen=3;
zu=n;
for(i=0;i<cen;i++) //層數(0,1,2)
{
zu=zu/2; //組數(4,2,1)
for(j=0;j<zu;j++) //第i 層中的第 j組
{
ge=(n/zu)/2;//一組中蝶形的個數(1,2,4)
for(k=0;k<ge;k++) //第 j 組中的第k個
{ //第 a 和第 b 個元素作蝶形運算,WNC
a=j*ge*2+k; //(0,2,4,6)(0,1,4,5)(0,1,2,3)
b=a+ge; //(ge=1,2,4)
c=k*zu; //(0,0,0,0)(0,2,0,2)(0,1,2,3)
qn=(PI2/n)*c;
//注意sign
tr=(XX[b].real*costab[qn]+XX[b].imag*sintab[qn])>>7;//由于正余弦表放大128倍,此處縮小128倍
ti=(XX[b].imag*costab[qn]-XX[b].real*sintab[qn])>>7;
p=XX[a].real;
q=XX[a].imag;
//蝶形運算
XX[a].real=(p+tr)>>1;//防止資料溢位
XX[a].imag=(q+ti)>>1;
XX[b].real=(p-tr)>>1;
XX[b].imag=(q-ti)>>1;
}
}
}
}
unsigned char FFTvaule[64];//輸出的頻譜值(轉換到0~31)
unsigned char TopPoint[64];//頂點值 [頂部的綠點]
unsigned char Keep[64]; //頂點停留
unsigned char LINE;
unsigned char ADC_Count;
//對fft資料進行處理
void FFTK()
{
unsigned char pt=0,j;
for(pt=0;pt<N;pt++)
{
S[pt].imag=0; //清零虛部
S[pt].real=(S[pt].real-128);//電壓轉換128
}
fft(S,N);//對當前資料進行傅立葉變換
FFTvaule[0]=0x00;
//處理頂點
for(pt=0;pt<N/2;pt++)
{
S[pt].real=sqrtf(S[pt].real*S[pt].real+S[pt].imag*S[pt].imag);//求模
if((unsigned char)(S[pt].real)<255)
FFTvaule[pt] =iw[(unsigned char)(S[pt].real)];
//處理頂點值
if(FFTvaule[pt]>=TopPoint[pt])
{
TopPoint[pt] = FFTvaule[pt]+1;
Keep[pt] = 12;
}
else if(TopPoint[pt]>1)
{
if(Keep[pt]) Keep[pt]--;
else
{
TopPoint[pt]--;
}
}
else
TopPoint[j] = 1;
}
}
//#######################################################################################################//
unsigned int Get_ADC()
{
unsigned int ADC_Back;
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,0xffff); //等待檢測結束
ADC_Back=((HAL_ADC_GetValue(&hadc1)));
HAL_ADC_Stop(&hadc1); //結束AD檢測
ADC_Dat=ADC_Back;
if(Open_Close==1)
{
if(Open_Flsh!=ADC_Dat)
{
if(Open_Flsh>ADC_Dat)
{
if(Open_Flsh-ADC_Dat >70)
{
System_Count++;
if(System_Count>=5)
{
System_Count=0;
Open_Close=0;
}
}
}
else
{
if(ADC_Dat-Open_Flsh >70)
{
System_Count++;
if(System_Count>=5)
{
System_Count=0;
Open_Close=0;
}
}
}
Open_Flsh=ADC_Dat;
}
}
else
{
if(Open_Flsh!=ADC_Dat)
{
if(Open_Flsh>ADC_Dat)
{
if(Open_Flsh-ADC_Dat <70)
{
System_Count++;
if(System_Count>=5)
{
System_Count=0;
Open_Close=1;
}
}
}
else
{
if(ADC_Dat-Open_Flsh <70)
{
System_Count++;
if(System_Count>=5)
{
System_Count=0;
Open_Close=1;
}
}
}
Open_Flsh=ADC_Dat;
}
}
return ADC_Back;
}
//#######################################################################################################//
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==&htim4)
{
Time4_ms++;
if(Time4_ms%80==0)
{
Time4_ms=0;
Scan_Fre =1;
GPIOC->ODR^=GPIO_PIN_13;
}
}
}
void LED_Dispose(unsigned char Dat_)
{
if(Dat_>31) LED0_0;
else LED0_1;
if(Dat_>62) LED1_0;
else LED1_1;
if(Dat_>93) LED2_0;
else LED2_1;
if(Dat_>124) LED3_0;
else LED3_1;
if(Dat_>155) LED4_0;
else LED4_1;
if(Dat_>186) LED5_0;
else LED5_1;
if(Dat_>217)LED6_0;
else LED6_1;
if(Dat_>240)LED7_0;
else LED7_1;
}
//#######################################################################################################//
void Debug_Output()
{
unsigned char Coun=0;
for(Coun=0;Coun<30;Coun++)
{
if(FFTvaule[0]<22)
{
LED0_1 ;
LED1_1 ;
LED2_1 ;
LED3_1 ;
LED4_1 ;
LED5_1 ;
LED6_1 ;
LED7_1 ;
HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_4);
PWM_falg=1;
}
else
{
if(PWM_falg==1)
{
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
PWM_falg=0;
}
if(FFTvaule[Coun]*257<65535) TIM3->CCR4 = FFTvaule[Coun]*257;
LED_Dispose(FFTvaule[Coun]);
}
printf("%d,",FFTvaule[Coun]);
}
printf("\r\n%d",ADC_Dat);
printf("%s","\r\n");
}
//#######################################################################################################//
/**
* @brief The application entry point.
* @main函式
* @retval None
*/
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
MX_GPIO_Init();
MX_TIM4_Init();
MX_ADC1_Init();
MX_TIM3_Init();
MX_IWDG_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim4);
HAL_UART_Transmit(&huart1,(unsigned char *)"System_Star\r\n",13,100);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
TIM3->CCR4 =0;
while (1)
{
Get_ADC();
if(Open_Close ==0)
{
for(ADC_Count=0;ADC_Count<N;ADC_Count++)
{
S[ADC_Count].real =Get_ADC()/4;
S[ADC_Count].imag =0;
}
FFTK(); //FFT
if(Scan_Fre==1)
{
Scan_Fre=0;
Debug_Output();
}
}
HAL_IWDG_Refresh(&hiwdg);
}
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* ADC1 init function */
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* IWDG init function */
static void MX_IWDG_Init(void)
{
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_32;
hiwdg.Init.Reload = 800;
if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* TIM3 init function */
static void MX_TIM3_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef sConfigOC;
htim3.Instance = TIM3;
htim3.Init.Prescaler = 63;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 1000;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_TIM_MspPostInit(&htim3);
}
/*定時器 TIM4 init function */
static void MX_TIM4_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim4.Instance = TIM4;
htim4.Init.Prescaler = 63;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 1000;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* USART1 init function */
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6
|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_SET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PA15 */
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB3 PB4 PB5 PB6
PB7 PB8 PB9 */
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6
|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void _Error_Handler(char *file, int line)
{
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
}
#endif /* USE_FULL_ASSERT */
5、系統除錯及分析
5.1、系統除錯
根據系統設計方案,本系統的除錯共分為三大部分:硬體除錯,軟體除錯和軟硬體聯調,由于在系統設計中采用模塊設計法,所以方便對各電路模塊功能進行逐級測驗:LED驅動模塊的除錯,資料存盤模塊的除錯,PC機通信模塊的除錯等,最后將各模塊組合后進行整體測驗,
5.2、除錯現象及分析
進入除錯狀態后應該在關鍵的地方設定斷點然后按步運行,同時觀察引數的變化,通過變化來判斷程式運行的程序即可找出程式中混亂的部分,進行改正,這需要對軟體熟練的掌握和對語言程式的很好的理解,實驗板搭建成功后,我們就進入了程式的設計和除錯階段,開始撰寫程式時很順利,但是后來在除錯程序中出現了很多的錯誤,比如定時器準確度的設定,子程式的呼叫問題,最困難的就是對沒步程式執行順序的分析,由于程式中一些陳述句的錯誤理解和執行順序的判斷失誤,讓我掉進了誤區,耽誤了很長時間,最后在同學的幫助下終于找到了錯誤的關鍵點,更正成功了,看來對程式的除錯能力我還需要加強,程式的除錯需要耐心,而且需要熟練掌握軟體的跟部分功能,
5.3、測驗結果

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/293004.html
標籤:其他
上一篇:cgb2106-day11
