基于stm32F1音樂頻譜
單片機源程序如下:
- #include "led.h"
- #include "delay.h"
- #include "key.h"
- #include "sys.h"
- #include "lcd.h"
- #include "usart.h"
- #include "adc.h"
- #include "stm32_dsp.h"
- #include <math.h>
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- #define DOUBLE_COLOR 1 //是否為雙色屏,若為雙色屏則改為1
- #define NPT 64 //FFT采樣點數
- #define GREEN_STOP_TIME 15 //綠色點頂端停頓時間,值越大時間越長
- #define GREEN_SUB_SPEED 100 //綠色點下移速度,值越大速度越慢
- #define RED_SUB_SPEED 50 //紅色頻柱向下縮短速度,值越大速度越慢
- uint32_t ADC_DataNum=0; //ADC采樣點數
- uint32_t RedTime=0; //紅色點下移時間變量
- #if DOUBLE_COLOR
- uint32_t GreenTime=0; //綠色點下移時間變量
- uint32_t GreenStopTime[32]={0}; //綠色點頂端停頓時間數據
- #endif
- volatile uint8_t ADC_TimeOutFlag=1; //ADC定時采樣時間到標志
- extern __IO uint16_t ADCConvertedValue; //ADC采樣值
- extern int LCD_COLOR;
- long lBUFMAG[NPT+NPT/2]; //存儲求模后的數據
- long lBUFOUT[NPT];//FFT輸出序列
- long lBUFIN[NPT];//FFT輸入系列
- uint8_t fftHightRedBuf[NPT/2]={0}; //紅色頻柱高度數組
- uint8_t DisplayRedDataBuf[32*8]={0}; //紅色顯示緩沖區
- #if DOUBLE_COLOR
- uint8_t fftHightGreenBuf[NPT/2]={0}; //綠色頻點高度數組
- uint8_t DisplayGreenDataBuf[32*8]={0}; //綠色顯示緩沖區
- #endif
- u16 color_tab[16]={DARKBLUE,BLUE,LIGHTBLUE,GREEN,LIGHTGREEN,RED,BRED,BRRED,BLACK,YELLOW,CYAN,MAGENTA,GRAYBLUE,LGRAYBLUE,BROWN,LGRAY};
- void music_fft_main(uint8_t *RedNewHeight,uint8_t *GreenNewHeight)
- {
- int BarWidth = 8;
- int i=0;
- int j=0;
- static uint8_t RedOldHeight[32] = {0};
- static uint8_t GreenOldHeight[32] = {0};
- for(i=0;i<32;i++)
- {
- //清除之前的綠色方塊
- //LCD_COLOR = LCD_COLOR_BLACK;
-
- LCD_Fill(GreenOldHeight[i],(BarWidth+2)*i,GreenOldHeight[i]+3,(BarWidth+2)*i+BarWidth,WHITE);
- //顯示當前的綠色方塊
- LCD_Fill(GreenNewHeight[i],(BarWidth+2)*i,GreenNewHeight[i]+3,(BarWidth+2)*i+BarWidth,color_tab[16-j]);
- //顯示紅色柱
- if(RedNewHeight[i]>RedOldHeight[i]){//如果當前的綠色柱子高度比之前的大則補齊綠色柱子
- LCD_Fill(RedOldHeight[i],(BarWidth+2)*i,RedNewHeight[i],(BarWidth+2)*i+BarWidth,color_tab[j]);
- }else{//如果當前顯示的綠色柱子高度小于之前的柱子則需要將多余的綠色柱子用背景色填充
- LCD_Fill(RedNewHeight[i],(BarWidth+2)*i,RedOldHeight[i],(BarWidth+2)*i+BarWidth,WHITE);
- }
- //將新數據保存
- RedOldHeight[i] = RedNewHeight[i];
- GreenOldHeight[i] = GreenNewHeight[i];
- if(j>=15)
- j=0;
- j++;
- }
- }
- void powerMag(long nfill)
- { int32_t lX,lY;
- uint32_t i;
- for (i=0; i < nfill; i++)
- {
- lX= (lBUFOUT[i]<<16)>>16; /* sine_cosine --> cos */
- lY= (lBUFOUT[i] >> 16); /* sine_cosine --> sin */
- {
- float X= 64*((float)lX)/32768;
- float Y = 64*((float)lY)/32768;
- float Mag = sqrt(X*X+ Y*Y)/nfill; // 先平方和,再開方
- lBUFMAG[i] = (long)(Mag*65536);
- }
- }
- }
- int main(void)
- {uint32_t i=0;
- delay_init(); //延時函數初始化
- NVIC_Configuration(); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
- uart_init(9600); //串口初始化為9600
- LED_Init(); //LED端口初始化
- TIM2_Configuration();
- TIM2_NVIC_Configuration();
- FFT_RCC_Configuration();
- FFT_GPIO_Configuration();
- FFT_DMA_Init();
- FFT_ADC_Init();
- LCD_Init();
- // BACK_COLOR=BLACK;
- TIM_Cmd(TIM2, ENABLE);
- ADC_SoftwareStartConvCmd(ADC1, DISABLE);
-
- while(1)
- {
- if(ADC_TimeOutFlag){
- #if DOUBLE_COLOR
- GreenTime++;
- #endif
- RedTime++;
- ADC_TimeOutFlag=0;
- if(ADC_DataNum<NPT){//采樣點沒有達到所要求的點
- // ADC1->CR2 |= 0x00500000;//
- ADC_SoftwareStartConvCmd(ADC1, ENABLE);
- while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
- /* Clear channel1 transfer complete flag */
- DMA_ClearFlag(DMA1_FLAG_TC1);
- // ADC1->CR2 &= 0xFFAFFFFF;//
- ADC_SoftwareStartConvCmd(ADC1, DISABLE);
- lBUFIN[ADC_DataNum]=ADCConvertedValue<<16;
- ADC_DataNum++;
- }else{
- TIM_Cmd(TIM2, DISABLE);
- ADC_DataNum=0;
- cr4_fft_64_stm32(lBUFOUT,lBUFIN,NPT);//調用STM32的DSP庫作FFT變換
- powerMag(NPT);//計算頻點幅值
- //更新紅色點的高度
- for(i=0;i<NPT/2;i++){
- if((uint8_t)(lBUFMAG[i])>fftHightRedBuf[i]){
- fftHightRedBuf[i]=(lBUFMAG[i]);
- }
- #if DOUBLE_COLOR
- //刷新綠色點高度
- if(fftHightRedBuf[i]>=fftHightGreenBuf[i]){
- fftHightGreenBuf[i]=fftHightRedBuf[i];
- GreenStopTime[i]=GREEN_STOP_TIME;//綠點停頓時間
- if(fftHightRedBuf[i]>=235){
- fftHightGreenBuf[i]=235;
- fftHightRedBuf[i]=235;
- }
- }
- #else
- if(fftHightRedBuf[i]>=239){
- fftHightRedBuf[i]=239;
- }
- #endif
- }
- //顯示紅色柱子
- music_fft_main(fftHightRedBuf,fftHightGreenBuf);
- //顯示綠色點
- #if DOUBLE_COLOR
- //綠色點下移
- if((GreenTime>GREEN_SUB_SPEED)){ //綠色點下降間隔時間
- GreenTime=0;
- for(i=0;i<NPT/2;i++){
- if((fftHightGreenBuf[i]!=0)&&(GreenStopTime[i]==0)){
- fftHightGreenBuf[i]--;
- }
- }
- }
- #endif
- //紅色下移
- if(RedTime>RED_SUB_SPEED){
- RedTime=0;
- for(i=0;i<NPT/2;i++){
- if((fftHightRedBuf[i]!=0)){
- fftHightRedBuf[i]--;
- }
- }
- }
- //綠色點停頓時間減一
- #if DOUBLE_COLOR
- for(i=0;i<NPT/2;i++){
- if(GreenStopTime[i]!=0){
- GreenStopTime[i]--;
- }
- }
- #endif
- TIM_Cmd(TIM2, ENABLE);
- }
- }
- }
- }
-
-
- void TIM2_IRQHandler(void)
- {
- if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){
- // TIM2->SR = (uint16_t)~TIM_FLAG_Update;
- TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update); //清中斷
- ADC_TimeOutFlag=1;
- }
- }
復制代碼
所有資料51hei提供下載:
基于STM32戰艦版的音樂頻譜.zip
(3.64 MB, 下載次數: 255)
2017-12-29 21:10 上傳
點擊文件名下載附件
|