发 帖  
[问答] AVR单片机的音乐频谱,tft显示,32点FFT变换
255 AVR单片机 TFT FFT
分享
本帖最后由 一只耳朵怪 于 2018-6-26 10:54 编辑

实物图:
  
  



  • /*
  • * FFT.c
  • *
  • * Created: 2013/5/1 0:16:05
  • *  Author: zhanddkk
  • */
  • #include <math.h>
  • #include "../Include/FFT.h"
  • float sin_tab[FFT_N],cos_tab[FFT_N];
  • //-------------------------------------------//
  • //函数名:FFT初始化函数
  • //入口:void
  • //出口:void
  • //功能:建立sin()、cos()表
  • //-------------------------------------------//
  • void FFT_Init()
  • {
  •         uchar i;
  •         for (i=0;i<FFT_N;i++)
  •         {
  •                 sin_tab=sin(PI*2*i/FFT_N);
  •                 cos_tab=cos(PI*2*i/FFT_N);
  •         }
  • }
  • //-------------------------------------------//
  • //函数名:FFT运算函数
  • //入口:compx *xin:需要计算的FFT数据表结构体指针
  • //出口:void
  • //功能:FFT运算,最后得到峰值功率频谱
  • //-------------------------------------------//
  • void FFT(compx *xin)
  • {
  •         uchar i,j=0,k;
  •         uchar L,b,p;
  •         uchar Nv2,Nm1;
  •         float TR,TI;
  •         float tempData_rc,tempData_is,tempData_rs,tempData_ic;
  •         //float t;
  •         Nv2=FFT_N/2;                  //变址运算,即把自然顺序变成倒位序,采用雷德算法
  •         Nm1=FFT_N-1;
  •         //--倒序运算--//
  •         for(i=0;i<Nm1;i++)
  •         {
  •                 if(i<j)
  •                 {
  •                         TI=xin[j].real;
  •                         xin[j].real=xin.real;
  •                         xin.real=TI;
  •                 }
  •                 k=Nv2;
  •                 while(k<=j)
  •                 {
  •                         j=j-k;
  •                         k=k/2;
  •                 }
  •                 j=j+k;
  •         }
  •         //--基2的FFT蝶形运算--//
  •         for (L=1;L<=FFT_m;L++)                /* Loop_1 L是L级蝶形运算 (2^FFT_m=FFT_N)*/
  •         {                       
  •                 b=1<<(L-1);                                /* b=2^(L-1) b是进行蝶形运算的两个数据的距离 */
  •                 for (j=0;j<b;j++)                /* Loop_2 根据b进行三级的蝶形运算 */
  •                 {
  •                         p=1<<(FFT_m-L);                /* p=2^(FFT_m-L) 旋转因子计算 */
  •                         p*=j;
  •                         for (k=j;k<FFT_N;k+=(2*b))
  •                         {
  •                                 TR=xin[k].real;
  •                                 TI=xin[k].imag;
  •                                 tempData_rc=xin[k+b].real*cos_tab[p];
  •                                 tempData_is=xin[k+b].imag*sin_tab[p];
  •                                 tempData_rs=xin[k+b].real*sin_tab[p];
  •                                 tempData_ic=xin[k+b].imag*cos_tab[p];
  •                                 xin[k].real=xin[k].real+tempData_rc+tempData_is;
  •                                 xin[k].imag=xin[k].imag-tempData_rs+tempData_ic;
  •                                 xin[k+b].real=TR-tempData_rc-tempData_is;
  •                                 xin[k+b].imag=TI+tempData_rs-tempData_ic;
  •                         }                       
  •                 }
  •         }
  •         //--功率峰值计算--//
  •         for (i=1;i<=Nv2;i++)
  •         {
  •                 xin.real=(uint)sqrt(xin.real*xin.real+xin.imag*xin.imag)/(FFT_N/2);
  •         }      
  • }      





  • /*
  • * MusicSpectrum.c
  • *
  • * Created: 2013/4/30 19:34:05
  • *  Author: 詹磊
  • */
  • #include <avr/io.h>
  • #include <math.h>
  • #include "../Include/main.h"
  • #include "../Include/ADC.h"
  • #include "../Include/TFT.h"
  • #include "../Include/FFT.h"
  • #define MaxData                256
  • compx Data[ADC_ConversionsTime];
  • int lastData[16][2],temp[2];
  • uchar flag[16],speed1[16],speed2=10,Gain=10;
  • void DrawingColumnar(uchar x,uchar y,uchar Wide,uchar High,int Data,int FullData,uint ColumnarColor)
  • {
  •         uint i,tempData1,tempData2;
  •         uchar tempData;
  •         if (Data>FullData)
  •         {
  •                 Data=FullData;
  •         }
  •         tempData=High-(uint)High*Data/FullData;
  •         tempData1=tempData*Wide;
  •         tempData2=((uint)High)*Wide;
  •         y=159-y;
  •         TFT_RamAddSet(x,y-High,x+Wide-1,y);
  •         for (i=0;i<tempData1;i++)
  •         {
  •                 TFT_WriteByteDAT(BackgroundColor>>8);        //高八位
  •                 TFT_WriteByteDAT(BackgroundColor);                //低八位
  •         }
  •         for (i=tempData1;i<tempData2;i++)
  •         {
  •                 TFT_WriteByteDAT(ColumnarColor>>8);                //高八位
  •                 TFT_WriteByteDAT(ColumnarColor);                //低八位
  •         }
  • }
  • void FallColumnar(uchar x,uchar y,uint High,int pData1,int pData2,int FullData,uint Color1,uint Color2)
  • {
  •         uchar i,tempData1,tempData2;
  •         /*if (pData1>FullData)
  •         {
  •                 pData1=FullData;
  •         }
  •         if (pData2>FullData)
  •         {
  •                 pData2=FullData;
  •         }*/
  •         if (pData2>pData1)
  •         {
  •                 pData2=pData1;
  •         }
  •         tempData1=High-High*pData1/FullData+2;
  •         tempData2=High-High*pData2/FullData;
  •         y=159-y;
  •         TFT_RamAddSet(x,y-High,x,y);
  •         for (i=2;i<tempData1;i++)
  •         {
  •                 TFT_WriteByteDAT(BackgroundColor>>8);        //高八位
  •                 TFT_WriteByteDAT(BackgroundColor);                //低八位
  •         }
  •         TFT_WriteByteDAT(Color1>>8);        //高八位
  •         TFT_WriteByteDAT(Color1);                //低八位
  •         for (i=tempData1;i<tempData2;i++)
  •         {
  •                 TFT_WriteByteDAT(BackgroundColor>>8);        //高八位
  •                 TFT_WriteByteDAT(BackgroundColor);                //低八位
  •         }
  •         for (i=tempData2;i<High;i++)
  •         {
  •                 TFT_WriteByteDAT(Color2>>8);        //高八位
  •                 TFT_WriteByteDAT(Color2);                //低八位
  •         }
  • }
  • int main(void)
  • {
  •         uchar i;
  •         ADCInit();
  •         TFT_Init();
  •         FFT_Init();
  •         for (i=0;i<16;i++)
  •         {
  •                 speed1=0;
  •         }
  •         TFT_putstr(0,0,"------ZHAN LEI------\n----MusicSpectrum----\n-----2013/04/30-----",DataRed);               
  •     while(1)
  •     {
  •                 if (Time==0)
  •                 {
  •                         for (i=0;i<32;i++)
  •                         {
  •                                 /*
  •                                 Data.real=255+sin(PI*2*i/FFT_N)*20
  •                                                                 +sin(PI*2*i/FFT_N*2)*40
  •                                                                 +sin(PI*2*i/FFT_N*3)*80
  •                                                                 +sin(PI*2*i/FFT_N*4)*120
  •                                                                 +sin(PI*2*i/FFT_N*5)*110
  •                                                                 +sin(PI*2*i/FFT_N*6)*100
  •                                                                 +sin(PI*2*i/FFT_N*7)*90
  •                                                                 +sin(PI*2*i/FFT_N*7.9)*20;
  •                                 */
  •                                 Data.imag=0;                       
  •                                 Data.real=ADC_Buffer*Gain;                                               
  •                         }
  •                         ADCSRA        |=(1<<ADSC);                                                      
  •                 }
  •                 else
  •                 {
  •                         FFT(Data);
  •                         for (i=0;i<16;i++)
  •                         {
  •                                 temp[0]=Data[i+1].real;
  •                                 if (temp[0]>MaxData)
  •                                         temp[0]=MaxData;
  •                                 temp[1]=temp[0];//防止超量程
  •                                 if(temp[0]<lastData[0]-speed1)//上次的顶部位置-3>本次应该的位置
  •                                 {
  •                                         if (flag>20)
  •                                         {
  •                                                 speed1=4;
  •                                         }
  •                                         else
  •                                         {
  •                                                 flag++;
  •                                                 speed1=0;
  •                                         }
  •                                         temp[0]=lastData[0]-speed1;                                                                                                                                               
  •                                 }
  •                                 else
  •                                         flag=0;
  •                                 if (temp[1]<lastData[1]-speed2)
  •                                         temp[1]=lastData[1]-speed2;                                                                                                                       
  •                                 FallColumnar(i*8,0,60,temp[0],temp[1],256,DataGreen,DataYellow);
  •                                 lastData[0]=temp[0];
  •                                 lastData[1]=temp[1];
  •                         }
  •                 }                              
  •     }
  • }





  



下载:
    MusicSpectrum.rar  


0
2018-6-26 07:02:23   评论 邀请回答

只有小组成员才能发言,加入小组>>

38个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表