找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6790|回复: 4
收起左侧

五色LED音乐频谱源程序和原理图 原件清单

[复制链接]
ID:169388 发表于 2017-3-9 14:45 | 显示全部楼层 |阅读模式
12单片机频闪,五色LED音乐频谱源程序代码

原理图如下:
0.png
元件清单:
0.png
五色LED音乐频谱源程序:
  1. #include <stc12c5a60s2.h>
  2. #include<intrins.h>
  3. #define BIN(n) LongToBin(0x##n##)
  4. #define uchar  unsigned char
  5. #define uint  unsigned int
  6. #define SAMPLE_NUM 64
  7. #define NUM_2_LOG 6
  8. #define FFT_OUT_MIN 3
  9. #define LongToBin(n) (((n>>21)&0x80)|((n>>18)&0x40)|((n>>15)&0x20)|((n>>12)&0x10)|((n>>9)&0x08)|((n>>6)&0x04)|((n>>3)&0x02)|((n)&0x01))

  10. uchar code BRTable[SAMPLE_NUM] ={ 0, 32, 16, 48, 8, 40, 24, 56,4, 36, 20, 52, 12, 44, 28, 60, 2, 34, 18, 50, 10, 42, 26, 58, 6, 38, 22, 54, 14, 46, 30, 62, 1, 33, 17, 49, 9, 41, 25, 57,5, 37, 21, 53, 13, 45, 29, 61,3, 35, 19, 51, 11, 43, 27, 59,7, 39, 23, 55, 15, 47, 31, 63};
  11. char code sin_tabb[SAMPLE_NUM] = { 0 ,12 ,25 ,37 ,49 ,60 ,71 ,81 ,90 ,98 ,106 ,112 ,117 ,122 ,125 ,126 ,127 ,126 ,125 ,122 ,117 ,112 ,106 ,98 ,90 ,81 ,71 ,60 ,49 ,37 ,25 ,12 ,0 ,-12 ,-25 ,-37 ,-49 ,-60 ,-71 ,-81 ,-90 ,-98 ,-106 ,-112 ,-117 ,-122 ,-125 ,-126 ,-127 ,-126 ,-125 ,-122 ,-117 ,-112 ,-106 ,-98 ,-90 ,-81 ,-71 ,-60 ,-49 ,-37 ,-25 ,-12  };
  12.                                  
  13. char code cos_tabb[SAMPLE_NUM] = {127 ,126 ,125 ,122 ,117 ,112 ,106 ,98 ,90 ,81 ,71 ,60 ,49 ,37 ,25 ,12 ,0 ,-12 ,-25 ,-37 ,-49 ,-60 ,-71 ,-81 ,-90 ,-98 ,-106 ,-112 ,-117 ,-122 ,-125 ,-126 ,-127 ,-126 ,-125 ,-122 ,-117 ,-112 ,-106 ,-98 ,-90 ,-81 ,-71 ,-60 ,-49 ,-37 ,-25 ,-12 ,0 ,12 ,25 ,37 ,49 ,60 ,71 ,81 ,90 ,98 ,106 ,112 ,117 ,122 ,125 ,126 };
  14. uchar a[21];
  15. uchar keep,keepnum,anum,timernum,timernum2,lednum3,Ltime;//用于分离

  16. /*加入数组用于显示相应led灯数目*/
  17. uchar lednum[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};//0-7的显示数组  P2组控制
  18. int xdata FftReal[SAMPLE_NUM];
  19. int xdata FftImage[SAMPLE_NUM];
  20. sbit p30=P3^0;
  21. sbit p31=P3^1;
  22. sbit p32=P3^2;
  23. sbit p33=P3^3;
  24. sbit p34=P3^4;
  25. sbit p35=P3^5;//9-11的led控制
  26. sbit p36=P3^6;
  27. sbit p37=P3^7;

  28. void timerinit()//定时器 初始化函数
  29. {
  30.          TMOD=0x01;
  31.          TH0=(65536-6000)/256;
  32.          TL0=(65536-6000)%256;
  33.          EA=1;
  34.          ET0=1;
  35.          TR0=1;
  36. }
  37. void disp()
  38. {
  39.         timernum++;
  40.         if(timernum==6) timernum=1;
  41.         P2=0;//显示前先关闭
  42.         P3=P3&0x1f;
  43.         switch(timernum)
  44.         {
  45.                 case 1:anum=a[0];p34=0;p33=1;p32=1;p31=1;p30=1;break;
  46.                 case 2:anum=a[1];p34=1;p33=0;p32=1;p31=1;p30=1;break;
  47.                 case 3:anum=a[2];p34=1;p33=1;p32=0;p31=1;p30=1;break;
  48.                 case 4:anum=a[3];p34=1;p33=1;p32=1;p31=0;p30=1;break;
  49.                 case 5:anum=a[4];p34=1;p33=1;p32=1;p31=1;p30=0;break;
  50.         }
  51.         //anum=a[10];/*修改可以改变光柱高度 (anum值分开几个部分用定时器区分显示)(a[]内逐加) */
  52.         if(anum<=8){P2=lednum[anum];P3=P3&0x1f;}//屏蔽高三位
  53.         //else {P2=0xff;P3=lednum2[anum-9];}
  54.         if(anum==9){P2=0xff;p35=1;p36=0;p37=0;}
  55.         if(anum==10){P2=0xff;p35=1;p36=1;p37=0;}
  56.         if(anum==11){P2=0xff;p35=1;p36=1;p37=1;}

  57. }

  58. uchar STC_ADC()                   //!!根据数据手册写一个ad读取函数
  59.   {
  60.      uchar i;
  61.         ADC_RES   = 0;
  62.         ADC_RESL  = 0;
  63.   ADC_CONTR = BIN(10001000);
  64.   i=3;
  65.         while(i--);
  66.         while (1)                     
  67.      {
  68.          if (ADC_CONTR & BIN(10000))      
  69.          {
  70.             break;
  71.            }
  72.      }
  73.      ADC_CONTR = BIN(10000000);
  74.   return( ADC_RESL<<2) ;
  75. }
  76. short sqrt_16( unsigned long M)   
  77. {
  78.     unsigned int N, i;
  79.     unsigned long tmp, ttp;
  80.     if( M == 0 )            
  81.         return 0;
  82.    
  83.     N = 0;
  84.    
  85.     tmp = ( M >> 30 );        
  86.     M <<= 2;
  87.     if( tmp > 1 )            
  88.     {
  89.         N ++;               
  90.         tmp -= N;
  91.     }
  92.    
  93.     for( i=15; i>0; i-- )   
  94.     {
  95.         N <<= 1;           
  96.         
  97.         tmp <<= 2;
  98.         tmp += (M >> 30);  
  99.         
  100.         ttp = N;
  101.         ttp = (ttp<<1)+1;
  102.         
  103.         M <<= 2;
  104.         if( tmp >= ttp )   
  105.         {
  106.             tmp -= ttp;
  107.             N ++;
  108.         }      
  109.     }
  110.    
  111.     return N;
  112. }
  113. void FFT()
  114. {
  115. register    uchar i,bb,j,k,p,max;
  116. register short TR,TI,temp;
  117.     unsigned long ulReal;                             
  118.     unsigned long ulImage;
  119.    
  120.    
  121.                                                                  
  122. for(i=0; i<SAMPLE_NUM;i++)          //此处可以加入自动增益
  123. {
  124.                 FftReal[BRTable[i]] = STC_ADC()<<keep;//使显示保持在一定范围内
  125.         FftImage[i] = 0;
  126. }

  127.          keepnum=FftReal[2]/32;//提取等级数
  128.                    if((7<keepnum)&&(keepnum<=8)) {keep=1;}
  129.          else if((4<keepnum)&&(keepnum<=6)) {keep=2;}
  130.          else if((2<keepnum)&&(keepnum<=4)) {keep=3;}
  131.          else {keep=5;}       
  132.    
  133.     for( i=1; i<=NUM_2_LOG; i++)                          
  134.     {
  135.         bb=1;
  136.         bb <<= (i-1);                                      
  137.         for( j=0; j<=bb-1; j++)                           
  138.         {
  139.             p=1;
  140.             p <<= (NUM_2_LOG-i);            
  141.             p = p*j;
  142.             for( k=j; k<SAMPLE_NUM; k=k+2*bb)               
  143.             {
  144.                 TR = FftReal[k]; TI = FftImage[k]; temp = FftReal[k+bb];
  145.                 FftReal[k] = FftReal[k] + ((FftReal[k+bb]*cos_tabb[p])>>7) + ((FftImage[k+bb]*sin_tabb[p])>>7);
  146.                 FftImage[k] = FftImage[k] - ((FftReal[k+bb]*sin_tabb[p])>>7) + ((FftImage[k+bb]*cos_tabb[p])>>7);
  147.                 FftReal[k+bb] = TR - ((FftReal[k+bb]*cos_tabb[p])>>7) - ((FftImage[k+bb]*sin_tabb[p])>>7);
  148.                 FftImage[k+bb] = TI + ((temp*sin_tabb[p])>>7) - ((FftImage[k+bb]*cos_tabb[p])>>7);
  149.                
  150.                 FftReal[k]  >>= 1;            
  151.                 FftImage[k]  >>= 1;
  152.                 FftReal[k+bb]  >>= 1;                 
  153.                 FftImage[k+bb]  >>= 1;
  154.                                                                               
  155.             }  
  156.         }
  157.     }
  158.     max=0;
  159.     for( i=0; i<5; i++)//5
  160.     {  
  161.         ulReal = FftReal[i+1];
  162.         ulReal *= ulReal;
  163.         ulImage = FftImage[i+1];
  164.         ulImage *= ulImage;
  165.         
  166.         a[i] = sqrt_16( ulReal + ulImage );   //修改
  167.                         
  168.         if( a[i] < FFT_OUT_MIN )     
  169.             a[i] = 0;//修改
  170.         else
  171.           a[i] = a[i]-FFT_OUT_MIN;
  172.         if( a[i] >max)
  173.              max =a[i];
  174.                          //disp();                     
  175.     }
  176.     if(max>11) //11
  177.     {
  178.        max/=11;       
  179.         for( i=0; i<5; i++) //输出a的5个分离数值
  180.         {      
  181.              a[i]/=max;
  182.             
  183.         }  
  184.     }
  185. }            


  186. void main()
  187. {
  188.         P2M0=0xff;//  (11111111);//P2组设置为推挽输出
  189.         P2M1=0;

  190.         …………余下代码请下载附件…………
复制代码


0.png
可看得出用的是stc单片机
下载:
频谱.rar (181.27 KB, 下载次数: 122)
回复

使用道具 举报

ID:228186 发表于 2017-12-19 18:17 | 显示全部楼层
谢谢,学习了。
回复

使用道具 举报

ID:160713 发表于 2019-4-2 20:33 | 显示全部楼层
这个程序能用吗?
回复

使用道具 举报

ID:524014 发表于 2019-5-2 09:50 来自手机 | 显示全部楼层
学习学习
回复

使用道具 举报

ID:710246 发表于 2020-5-16 17:16 来自手机 | 显示全部楼层
这个原理图是用什么软件画的
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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