[资料下载] FFT-LED算法led频谱显示

[复制链接]
 楼主| abotomson 发表于 2023-5-30 10:00 | 显示全部楼层 |阅读模式


  1. #include<intrins.h>

  2. /********************************************************************/
  3. #define SAMPLE_NUM 128
  4. #define LOG 6
  5. #define TIME 2048           //中断
  6. #define FFT_OUT_MIN 0
  7. #define FFT_OUT_MAX        7      
  8. #define OFF L1=L2=L3=L4=L5=L6=L7=L8=L9=L10=L11=L12=L13=L14=L15=L16=L17=L18=L19=L20=L21=L22=L23=L24=1;
  9. #define ADC_POWER   0x80            //ADC power control bit
  10. #define ADC_FLAG    0x10            //ADC complete flag
  11. #define ADC_START   0x08            //ADC start control bit
  12. //#define ADC_SPEEDLL 0x00            //420 clocks
  13. //#define ADC_SPEEDL  0x20            //280 clocks
  14. #define ADC_SPEEDH  0x40            //140 clocks
  15. //#define ADC_SPEEDHH 0x60            //70 clocks

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

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

  36. 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,

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

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

  39. -98, -94, -89, -85, -80, -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6};                        
  40. char code cos_tabb[SAMPLE_NUM] = {127, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112, 108, 105, 102, 98, 94,

  41. 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,

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

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

  44. -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,

  45. 75, 80, 85, 89, 94, 98, 102, 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126};
  46. xdata unsigned char result[128];
  47. xdata unsigned char temp[128];
  48. xdata unsigned char num[128];
  49. unsigned char anum,timernum,timernum2,lednum3,Ltime,t;//用于分离
  50. unsigned char lednum[]={0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};//0-7的显示数组  P2组控制
  51. int xdata FftReal[SAMPLE_NUM];
  52. int xdata FftImage[SAMPLE_NUM];

  53. unsigned char code musicdisplay[]={
  54.         0x00,0x00,
  55.         0xFE,0x40,0x30,0x40,0xFE,0x00, // -M-
  56.         0xFC,0x02,0x02,0x02,0xFC,0x00, // -U-
  57.         0x64,0x92,0x92,0x92,0x4C,0x00, // -S-
  58.         0x00,0x82,0xFE,0x82,0x00,0x00, // -I-
  59.         0x7C,0x82,0x82,0x82,0x44,0x00, // -C-
  60.         0x00,0x00,0x00,
  61.         0xFE,0x82,0x82,0x82,0x7C,0x00, // -D-
  62.         0x00,0x82,0xFE,0x82,0x00,0x00, // -I-
  63.         0x64,0x92,0x92,0x92,0x4C,0x00, // -S-
  64.         0xFE,0x90,0x90,0x90,0x60,0x00, // -P-
  65.         0xFE,0x02,0x02,0x02,0x02,0x00, // -L-
  66.         0x3E,0x48,0x88,0x48,0x3E,0x00, // -A-
  67.         0xC0,0x20,0x1E,0x20,0xC0,0x00, // -Y-
  68.         0x00,0x00,0x00,0x00,0x00,0x00,
  69.         0x00,0x00,0x00,0x00,0x00,0x00,
  70.         0x00,0x00,0x00,0x00,0x00,0x00,
  71.         0x00,0x00,0x00,0x00,0x00,0x00,
  72.         0x00,0x00,0x00,0x00,0x00,0x00};
  73. /********************************************************************/
  74. #define LED P2
  75. #define pwm 9

  76. sbit L24=P3^2;
  77. sbit L23=P3^1;
  78. sbit L22=P3^0;
  79. sbit L21=P4^7;
  80. sbit L20=P1^7;
  81. sbit L19=P1^6;
  82. sbit L18=P1^5;
  83. sbit L17=P1^4;
  84. sbit L16=P3^3;
  85. sbit L15=P3^4;
  86. sbit L14=P3^5;
  87. sbit L13=P3^6;
  88. sbit L12=P3^7;
  89. sbit L11=P0^2;
  90. sbit L10=P0^1;
  91. sbit L9=P0^0;
  92. sbit L8=P0^3;
  93. sbit L7=P0^4;
  94. sbit L6=P0^5;
  95. sbit L5=P0^6;
  96. sbit L4=P0^7;
  97. sbit L3=P4^6;
  98. sbit L2=P4^5;
  99. sbit L1=P4^4;
  100. /********************************************************************/
  101. void delay(unsigned char a)
  102. {
  103.         unsigned int i;
  104.         while(--a)
  105.                 for(i=0;i<50;i++);                                    
  106. }
  107. /********************************************************************/
  108. void off()
  109. {
  110.         LED = 0x00;
  111.         OFF
  112. //        delay(10-pwm);
  113. }
  114. /********************************************************************/
  115. void display(unsigned char i,unsigned char dat)
  116. {
  117.         P2=dat;
  118.         switch(i)
  119.         {
  120.                 case 1:L1=0;break;
  121.                 case 2:L2=0;break;
  122.                 case 3:L3=0;break;
  123.                 case 4:L4=0;break;
  124.                 case 5:L5=0;break;
  125.                 case 6:L6=0;break;
  126.                 case 7:L7=0;break;
  127.                 case 8:L8=0;break;
  128.                 case 9:L9=0;break;
  129.                 case 10:L10=0;break;
  130.                 case 11:L11=0;break;
  131.                 case 12:L12=0;break;
  132.                 case 13:L13=0;break;
  133.                 case 14:L14=0;break;
  134.                 case 15:L15=0;break;
  135.                 case 16:L16=0;break;
  136.                 case 17:L17=0;break;
  137.                 case 18:L18=0;break;
  138.                 case 19:L19=0;break;
  139.                 case 20:L20=0;break;
  140.                 case 21:L21=0;break;
  141.                 case 22:L22=0;break;
  142.                 case 23:L23=0;break;
  143.                 case 24:L24=0;break;
  144.         }
  145.         delay(pwm);
  146.         off();
  147. }
  148. /********************************************************************/
  149. void show_musicdisplay()
  150. {
  151.         unsigned char a,b,c;
  152.         for(c=0;c<80;c++)
  153.                 for(b=12;b>0;b--)
  154.                            for(a=1;a<25;a++)
  155.                                 display(a,musicdisplay[a-1+c]);
  156. }
  157. /********************************************************************/            
  158. void FFT_process()                          //下落迟滞
  159. {
  160.         unsigned char i;
  161.         for(i=0;i<24;i++)
  162.         {      
  163.                 if(result[i] < temp[i])
  164.                 {
  165.                         num[i]++;
  166.                         if(num[i] == 1)
  167.                         {
  168.                                 if(temp[0]==0&&temp[1]==0&&temp[2]==0&&temp[3]==0&&temp[4]==0&&temp[5]==0&&temp[6]==0&&temp[7]==0&&temp[8]==0&&temp[9]==0&&temp[10]==0&&temp[11]==0&&temp[12]==0&&temp[13]==0&&temp[14]==0&&temp[15]==0&&temp[16]==0&&temp[17]==0&&temp[18]==0&&temp[19]==0&&temp[20]==0&&temp[21]==0&&temp[22]==0&&temp[23]==0&&temp[24]==0);
  169.                                 else
  170.                                 {
  171.                                         result[i] = --temp[i];
  172.                                         num[i] = 0;
  173.                                 }
  174.                         }
  175.                 }
  176.                 else
  177.                         num[i] = 0;               
  178.         }
  179. }
  180. /********************************************************************/
  181. void disp()
  182. {
  183. //        unsigned char i,j,buff;
  184.         timernum++;
  185.         if(timernum == 25)
  186.                 timernum = 1;
  187.            OFF
  188.         FFT_process();
  189.         /*for(i=0;i<16;i++)
  190.                 for(j=i+1;j<16;j++)
  191.                         if(result[j] > result[i])
  192.                         {
  193.                                 buff = result[i];
  194.                                 result[i] = result[j];
  195.                                 result[j] = buff;
  196.                         }*/                                          
  197.         switch(timernum)
  198.         {
  199.                 case 1:anum = result[0];L1=0;break;
  200.                 case 2:anum = result[1];L2=0;break;
  201.                 case 3:anum = result[2];L3=0;break;
  202.                 case 4:anum = result[3];L4=0;break;
  203.                 case 5:anum = result[4];L5=0;break;
  204.                 case 6:anum = result[5];L6=0;break;
  205.                 case 7:anum = result[6];L7=0;break;
  206.                 case 8:anum = result[7];L8=0;break;
  207.                 case 9:anum = result[8];L9=0;break;
  208.                 case 10:anum = result[9];L10=0;break;
  209.                 case 11:anum = result[10];L11=0;break;
  210.                 case 12:anum = result[11];L12=0;break;
  211.                 case 13:anum = result[12];L13=0;break;
  212.                 case 14:anum = result[13];L14=0;break;
  213.                 case 15:anum = result[14];L15=0;break;
  214.                 case 16:anum = result[15];L16=0;break;
  215.                 case 17:anum = result[16];L17=0;break;
  216.                 case 18:anum = result[17];L18=0;break;
  217.                 case 19:anum = result[18];L19=0;break;
  218.                 case 20:anum = result[19];L20=0;break;
  219.                 case 21:anum = result[20];L21=0;break;
  220.                 case 22:anum = result[21];L22=0;break;
  221.                 case 23:anum = result[22];L23=0;break;
  222.                 case 24:anum = result[23];L24=0;break;
  223.         }
  224.         if(anum >= 8)
  225.                 anum = FFT_OUT_MAX;
  226.         LED = lednum[anum];
  227. }
  228. /********************************************************************/
  229. void ADC_init()
  230. {
  231.         P1ASF = 0x01;                   //Open 8 channels ADC function
  232.     ADC_RES = 0;                    //Clear previous result
  233.         ADC_RESL= 0;
  234.     ADC_CONTR = ADC_POWER | ADC_SPEEDH;
  235.     delay(5);                       //ADC power-on and delay      
  236. }
  237. /********************************************************************/
  238. float ADC_read()
  239. {
  240. //delay(10);      
  241.     ADC_CONTR = ADC_POWER | ADC_SPEEDH  | ADC_START;
  242.     _nop_();                        //至少要延时4个时钟周期
  243.     _nop_();
  244.     _nop_();
  245.     _nop_();
  246.         _nop_();
  247.     while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
  248.     ADC_CONTR &= ~ADC_FLAG;         //关闭ADC
  249.     return (ADC_RES*4+ADC_RESL);                 //Return ADC result
  250. }
  251. /********************************************************************/
  252. short sqrt_16(unsigned long M)   
  253. {
  254.     unsigned int N,i;
  255.     unsigned long tmp,ttp;
  256.     if( M == 0 )            
  257.         return 0;   
  258.     N = 0;  
  259.     tmp = (M >> 30);        
  260.     M <<= 2;
  261.     if( tmp > 1 )            
  262.     {
  263.         N++;               
  264.         tmp -= N;
  265.     }   
  266.     for( i=15; i>0; i-- )   
  267.     {
  268.         N <<= 1;                  
  269.         tmp <<= 2;
  270.         tmp += (M >> 30);         
  271.         ttp = N;
  272.         ttp = (ttp<<1)+1;        
  273.         M <<= 2;
  274.         if( tmp >= ttp )   
  275.         {
  276.             tmp -= ttp;
  277.             N ++;
  278.         }      
  279.     }   
  280.     return N;
  281. }
  282. /********************************************************************/
  283. void FFT()
  284. {
  285.     register unsigned char i,bb,j,k,p;
  286.     register short TR,TI,temp;
  287.     unsigned long ulReal,ulImage;                             
  288.         unsigned char max;
  289.                                                                   
  290.     for(i=0;i<SAMPLE_NUM;i++)         
  291.     {
  292.                 FftReal[BRTable[i]] = ADC_read();
  293.         FftImage[i] = 0;
  294.     }        

  295.     for(i=1;i<=LOG;i++)                        
  296.     {
  297.         bb=1;
  298.         bb <<= (i-1);                                      
  299.         for(j=0;j<=bb-1;j++)                           
  300.         {
  301.             p=1;
  302.             p <<= (LOG-i);           
  303.             p = p*j;
  304.             for(k=j;k<SAMPLE_NUM;k=k+2*bb)               
  305.             {
  306.                 TR=FftReal[k];TI=FftImage[k];temp=FftReal[k+bb];
  307.                 FftReal[k]=FftReal[k]+((FftReal[k+bb]*cos_tabb[p])>>7)+((FftImage[k+bb]*sin_tabb[p])>>7);
  308.                 FftImage[k]=FftImage[k] - ((FftReal[k+bb]*sin_tabb[p])>>7)+((FftImage[k+bb]*cos_tabb[p])>>7);
  309.                 FftReal[k+bb]=TR-((FftReal[k+bb]*cos_tabb[p])>>7)-((FftImage[k+bb]*sin_tabb[p])>>7);
  310.                 FftImage[k+bb]=TI+((temp*sin_tabb[p])>>7)-((FftImage[k+bb]*cos_tabb[p])>>7);
  311.                
  312.                 FftReal[k] >>= 1;            
  313.                 FftImage[k] >>= 1;
  314.                 FftReal[k+bb] >>= 1;                 
  315.                 FftImage[k+bb] >>= 1;                                                                              
  316.             }  
  317.         }
  318.     }

  319.    for(i=0;i<24;i++)
  320.     {  
  321.         ulReal = FftReal[i+1];
  322.         ulReal *= ulReal;
  323.         ulImage = FftImage[i+1];
  324.         ulImage *= ulImage;      
  325.         result[i] = sqrt_16(ulReal+ulImage);                                                                 
  326.                     
  327.     }
  328. /*        for(i=0;i<17;i++)
  329.     {
  330.                 while(result[i] > FFT_OUT_MAX)
  331.                 {
  332.                 for(i=0;i<17;i++)
  333.              {                        
  334.                         result[i] =result[i] -1;      
  335.                   }
  336.             }
  337.         }         */
  338.         while(result[i] == FFT_OUT_MIN)
  339.                 {
  340.                 for(i=0;i<24;i++)
  341.              {                        
  342.                         result[i] =result[i] +1;      
  343.                   }
  344.             }
  345.         for(i=0;i<24;i++)
  346.         {
  347.                 if(result[i] > FFT_OUT_MAX)
  348.                 {
  349.                         result[i] = FFT_OUT_MAX;      
  350.                         if(result[i] > max)
  351.                 max = result[i];
  352.                 }
  353.         }
  354.         //局部增益        */        /*                       
  355.                 /*if(max >= 4)               
  356.                 for(i=1;i<24;i++)
  357.                         if(result[i] >= 2)
  358.                                 result[i]+=1;          */
  359.                                                                  
  360. }
  361. /********************************************************************/            
  362. void init()
  363. {
  364.         P2M0=0XFF;
  365.         P2M1=0X00;
  366.         P3M0=0XFF;
  367.         P3M1=0X00;
  368.         P1M0=0XFE;
  369.         P1M1=0X01;
  370.         P4SW=0x70;

  371.         ADC_init();
  372.         //AUXR |= 0x80;                //定时器时钟1T模式
  373.         TMOD=0x01;
  374.         TH0=(65535-TIME)/256;
  375.         TL0=(65535-TIME)%256;
  376.     EA=1;
  377.         ET0=1;               
  378.         show_musicdisplay();  
  379.         TR0=1;
  380. }
  381. /********************************************************************/
  382. void main()
  383. {
  384.         init();
  385.     while(1)         
  386.         FFT();
  387. }
  388. /********************************************************************/
  389. void timer0() interrupt 1
  390. {
  391.         unsigned char i;
  392.         t++;
  393.         if(t == 24)
  394.         {
  395.                 for(i=0;i<24;i++)
  396.                         temp[i] = result[i];
  397.                 t = 0;
  398.         }                                 
  399.         disp();
  400.         TH0=(65535-TIME)/256;      
  401.         TL0=(65535-TIME)%256;
  402. }


您需要登录后才可以回帖 登录 | 注册

本版积分规则

55

主题

1904

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

55

主题

1904

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部