找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2789|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

音樂(lè)頻譜FFT單片機(jī)源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:257569 發(fā)表于 2018-3-31 13:46 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
音樂(lè)頻譜單片機(jī)源程序如下:
  1. #include<STC12C5A60S2.H>
  2. #define uchar unsigned char
  3. #define uint unsigned int  
  4. #define  channel  0x01                          //設(shè)置AD通道為 P1.0
  5. //---------------------------------------------------------------------
  6. #define ADC_POWER   (1<<7)
  7. #define ADC_SPEEDHH (0x03<<5)
  8. #define ADC_START   (1<<3)
  9. #define PADCH       (1<<5)
  10. #define ADC_FLAG    (1<<4)

  11. sbit  SDA_R=P1^5;           //紅數(shù)據(jù)
  12. sbit  SDA_R_TOP=P1^4;  //上紅數(shù)據(jù)
  13. sbit  SDA_G=P1^3;           //綠數(shù)據(jù)       
  14. sbit  SDA_G_TOP=P1^2;  //上綠數(shù)據(jù)
  15. sbit  STCP=P1^6;       //STR
  16. sbit  SHCP=P1^7;       //CLK
  17. //---------------------------------------------------------------------
  18. //----------------------------------------------------------------------------------------------------------------------
  19. //放大128倍后的sin整數(shù)表(128)       
  20. code char SIN_TAB[128] = { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70, 75, 80, 85, 89, 94, 98, 102,

  21. 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126, 126, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112,

  22. 108, 105, 102, 98, 94, 89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30,

  23. -36, -42, -48, -54, -59, -65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121,

  24. -123, -124, -125, -126, -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102,

  25. -98, -94, -89, -85, -80, -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6 };

  26. //放大128倍后的cos整數(shù)表(128)
  27. code char COS_TAB[128] = { 127, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112, 108, 105, 102, 98, 94,

  28. 89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30, -36, -42, -48, -54, -59,

  29. -65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121, -123, -124, -125, -126, -

  30. 126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102, -98, -94, -89, -85, -80,

  31. -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6, 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70,

  32. 75, 80, 85, 89, 94, 98, 102, 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126 };

  33. //采樣存儲(chǔ)序列表
  34. code char LIST_TAB[128] = { 0, 64, 32, 96, 16, 80, 48, 112,
  35. 8, 72, 40, 104, 24, 88, 56, 120,
  36. 4, 68, 36, 100, 20, 84, 52, 116,
  37. 12, 76, 44, 108, 28, 92, 60, 124,
  38. 2, 66, 34, 98, 18, 82, 50, 114,
  39. 10, 74, 42, 106, 26, 90, 58, 122,
  40. 6, 70, 38, 102, 22, 86, 54, 118,
  41. 14, 78, 46, 110, 30, 94, 62, 126,
  42. 1, 65, 33, 97, 17, 81, 49, 113,
  43. 9, 73, 41, 105, 25, 89, 57, 121,
  44. 5, 69, 37, 101, 21, 85, 53, 117,
  45. 13, 77, 45, 109, 29, 93, 61, 125,
  46. 3, 67, 35, 99, 19, 83, 51, 115,
  47. 11, 75, 43, 107, 27, 91, 59, 123,
  48. 7, 71, 39, 103, 23, 87, 55, 119,
  49. 15, 79, 47, 111, 31, 95, 63, 127
  50. };


  51. uchar COUNT=15,COUNT1=0,ADC_Count=0,LINE=15,G,T;
  52. uchar i,j,k,b,p;                 
  53. int Temp_Real,Temp_Imag,temp;                // 中間臨時(shí)變量  
  54. uint TEMP1;       
  55. int xdata Fft_Real[128];
  56. int xdata Fft_Image[128];               // fft的虛部
  57. uchar xdata LED_TAB2[16];                                //記錄 漂浮物 是否需要 停頓一下
  58. uchar xdata LED_TAB[16];                                //記錄紅色柱狀
  59. uchar xdata LED_TAB1[16];                                //記錄 漂浮點(diǎn)

  60. void FFT()
  61. {     //uchar x;              
  62.     for( i=1; i<=7; i++)                            /* for(1) */
  63.     {
  64.         b=1;
  65.         b <<=(i-1);                                       //碟式運(yùn)算,用于計(jì)算 隔多少行計(jì)算 例如 第一極 1和2行計(jì)算,,第二級(jí)
  66.         for( j=0; j<=b-1; j++)                              /* for (2) */
  67.         {
  68.             p=1;
  69.             p <<= (7-i);            
  70.             p = p*j;
  71.             for( k=j; k<128; k=k+2*b)                /* for (3) 基二fft */
  72.             {
  73.                 Temp_Real = Fft_Real[k]; Temp_Imag = Fft_Image[k]; temp = Fft_Real[k+b];
  74.                 Fft_Real[k] = Fft_Real[k] + ((Fft_Real[k+b]*COS_TAB[p])>>7) + ((Fft_Image[k+b]*SIN_TAB[p])>>7);
  75.                 Fft_Image[k] = Fft_Image[k] - ((Fft_Real[k+b]*SIN_TAB[p])>>7) + ((Fft_Image[k+b]*COS_TAB[p])>>7);
  76.                 Fft_Real[k+b] = Temp_Real - ((Fft_Real[k+b]*COS_TAB[p])>>7) - ((Fft_Image[k+b]*SIN_TAB[p])>>7);
  77.                 Fft_Image[k+b] = Temp_Imag + ((temp*SIN_TAB[p])>>7) - ((Fft_Image[k+b]*COS_TAB[p])>>7);     
  78.                 // 移位.防止溢出. 結(jié)果已經(jīng)是本值的 1/64               
  79.               Fft_Real[k] >>= 1;            
  80.                 Fft_Image[k] >>= 1;
  81.                Fft_Real[k+b]  >>= 1;                 
  82.                 Fft_Image[k+b]  >>= 1;
  83.                                                                               
  84.             }     
  85.         }
  86.     }
  87. //         Fft_Real[0]=Fft_Image[0]=0;                  //去掉直流分量
  88. //         Fft_Real[63]=Fft_Image[63]=0;
  89. //        x=((((Fft_Real[1]* Fft_Real[1]))+((Fft_Image[1]*Fft_Image[1])))>>5);
  90.         for(j=0;j<16;j++)                                                                                         
  91.         {                                                                                                                                                          
  92.                 TEMP1=((((Fft_Real[j+1]* Fft_Real[j+1]))+((Fft_Image[j+1]*Fft_Image[j+1])))>>1);//求功率
  93.                 if(TEMP1>1)TEMP1--;
  94.                 else TEMP1=0;
  95.                 if(TEMP1>31)TEMP1=31;
  96.                 if(TEMP1>(LED_TAB[j]))LED_TAB[j]=TEMP1;       
  97.                 if(TEMP1>(LED_TAB1[j]))
  98.                 {   LED_TAB1[j]=TEMP1;
  99.                         LED_TAB2[j]=14;                                                //提頓速度=12
  100.                 }
  101.         }      
  102. }

  103. void Init()
  104. {  
  105.        
  106. //-----------------------------------------------------------------------------------
  107.      P1ASF = 0x02;                 //0000,0010, 將 P1.1 置成模擬口
  108.          P1M0 = 0x01;                                                //0000,0001用于A/D轉(zhuǎn)換的P1.x口,先設(shè)為開(kāi)漏
  109.          P1M1 = 0x01;                                                //0000,0001 P1.0先設(shè)為開(kāi)漏。斷開(kāi)內(nèi)部上拉電阻
  110.    
  111.      AUXR1 &=0xFB;                 //1111,1011, 令 ADRJ=0
  112.          
  113.          EADC=1;                                           //AD中斷打開(kāi)
  114.          ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START | channel;
  115.                                    //1110 1001   1打開(kāi) A/D (ADC_POWER)轉(zhuǎn)換電源;11速度為70周期一次;
  116.                                //0中斷標(biāo)志清零;1啟動(dòng)adc(ADC_START);001AD通道打開(kāi)(這里為P1.1);
  117. //-----------------------------------------------------------------------------------
  118.          //P1M0=P1M1=1;
  119.          P2M0=1;
  120.      TMOD=0X12;                                          
  121.          TH0=0xb0;      //                                                             
  122.          TL0=0xb0;
  123.          TH1=0xEE;                                                                                                  
  124.          TL1=0XC0;
  125.          ET0=1;                                               //定時(shí)器0 打開(kāi)
  126.          TR0=0;                                                      //關(guān)閉定時(shí)器
  127.          ET1=1;
  128.          TR1=1;
  129.          PT1=0;
  130.          PT0=1;
  131.      IPH=PADCH;
  132.          IP=PADC;                                                  //中斷優(yōu)先級(jí)
  133.          EA=1;                                                        //總中斷打開(kāi)
  134. }


  135. void ADC_Finish() interrupt 5
  136. {           ADC_CONTR &= !ADC_FLAG;
  137.            Fft_Real[LIST_TAB[ADC_Count]]=(int)((ADC_RES)<<1)+(ADC_RESL>>1)*2;//-512; //按LIST_TAB表里的順序,進(jìn)行存儲(chǔ) 采樣值,,
  138.         //  ADC_CONTR = ADC_POWER | ADC_SPEEDHH| ADC_START | channel;        // 為了采集負(fù)電壓,采用 偏置采集。電壓提高到1/2 vcc,,所以要減去256
  139.           if(ADC_Count<=127)ADC_Count++;
  140.           else {EADC=0;TR0=0;}                                                                                                                   
  141. }

  142. void LED_Display() interrupt 3                                         //中斷一次 顯示一行。。。
  143. {                  
  144.         TH1=0xf2;                                                                                                 
  145.          TL1=0XAa;                                               
  146.                 for        (G=0;G<16;G++)                                                  //往點(diǎn)陣屏填充 一行的 數(shù)據(jù)
  147.                 {       
  148.                         if(LED_TAB[G]<=LINE+16)SDA_R_TOP=1;
  149.                         else SDA_R_TOP=0;
  150.                           if(LED_TAB[G]<=LINE)SDA_R=1;
  151.                         else SDA_R=0;

  152.                         if(LED_TAB1[G]==LINE){SDA_G_TOP=1;SDA_G=0;}
  153.                         else if(LED_TAB1[G]==(LINE+16)){SDA_G_TOP=0;SDA_G=1;}
  154.                         else SDA_G=SDA_G_TOP=1;
  155.                         SHCP=1;SHCP=0;
  156.                         SHCP=1;SHCP=0;
  157.                         SHCP=1;SHCP=0;
  158.                         SDA_G_TOP=1;SDA_G=1;SDA_R_TOP=1;SDA_R=1;
  159.                         SHCP=1;SHCP=0;
  160.                 }
  161.                 STCP=1;STCP=0;
  162.                 P2=15-LINE;                           //16掃描輸出
  163.                 if(LINE>0)LINE--;
  164.                 else LINE=15;
  165.   //////////////////////////
  166.        
  167.    if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--;                   //柱狀遞減,
  168.         if(COUNT>0)COUNT--;
  169.     else COUNT=15;
  170.    if(LED_TAB[COUNT]>0)LED_TAB[COUNT]--;
  171.     if(COUNT>0)COUNT--;
  172.     else COUNT=15;

  173.                                                                                                       //漂浮物遞減
  174. //  if(LED_TAB2[COUNT1]==0)                                        //判斷是否需要停頓          
  175. //  {
  176. //                   if(LED_TAB1[COUNT1]>LED_TAB[COUNT1])LED_TAB1[COUNT1]--;//大于柱狀則遞減(保持漂浮物在柱狀之上)
  177. //   }
  178. //  else LED_TAB2[COUNT1]--;
  179. //   COUNT1++;
  180. //   if(COUNT1>=16)COUNT1=0;
  181.    if(LED_TAB2[COUNT1]==0)
  182.    {
  183.                    if(LED_TAB1[COUNT1]>LED_TAB[COUNT1])LED_TAB1[COUNT1]--;
  184.    }
  185.    else LED_TAB2[COUNT1]--;
  186.    COUNT1++;
  187.    if(COUNT1>=16)COUNT1=0;
  188. }

  189. void Ad_Control() interrupt 1                                         //控制采樣率
  190. {
  191. ADC_CONTR = ADC_POWER | ADC_SPEEDHH| ADC_START | channel;         //開(kāi)始AD采集
  192. }
  193.   //==============================================================================================================
  194. //        *******************                                                           main()                                                        *********************************                                                                                  
  195. //===============================================================================================================

  196. void main()
  197. {
  198.     uchar i;
  199.         Init();
  200.         while(1)
  201.         {               
  202.                 ADC_Count=0;
  203.                 TR0=1;
  204.                 EADC=1;        //開(kāi)啟定時(shí)器中斷0,,開(kāi)啟ADC
  205.                 while(ADC_Count<128);
  206.         for(i=0;i<128;i++)
  207.         {
  208.          Fft_Image[i]=0;
  209.         }
  210.                 FFT();
  211.          //FFT運(yùn)算。并轉(zhuǎn)換為 功率值。。。                                                  
  212.                 //        TR1=1;                 
  213.         }
  214. }
復(fù)制代碼


音樂(lè)頻譜顯示3264雙色點(diǎn)陣.rar

53.55 KB, 下載次數(shù): 63, 下載積分: 黑幣 -5

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表