找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8956|回复: 18
收起左侧

16x16音乐频谱(源代码 原理图)

  [复制链接]
ID:104503 发表于 2016-1-26 22:34 | 显示全部楼层 |阅读模式
16x16音乐频谱(源代码 原理图)
1.png 0.png

部分源码预览:
  1. #include "STC12C5A.h"
  2. #include <intrins.h>      
  3. #include <math.h>
  4. #include "DS1302.h"
  5. #include "Led.h"
  6. #define uchar unsigned char
  7. #define uint unsigned int
  8. #define BinToHex(n) (((n>>21)&0x80)|((n>>18)&0x40)|((n>>15)&0x20)|((n>>12)&0x10)|((n>>9)& 0x08)|((n>>6)&0x04)|((n>>3)&0x02)|((n)&0x01))
  9. #define B(n) BinToHex(0x##n##l)                                // 8位2进制宏

  10. uchar code ColScan_2[16]   =  {0x17,0x13,0x15,0x11,0x16,0x12,0x14,0x10,
  11.                                      0x27,0x23,0x25,0x21,0x26,0x22,0x24,0x20};                                            // 74hc138 进行列扫描
  12. float code iw[64]=
  13. {
  14.         1.000,0,0.9952,-0.0980,0.9808,-0.1951,0.9569,-0.2903,0.9239,-0.3827,0.8819,-0.4714,0.8315,-0.5556,
  15.         0.7730,-0.6344,0.7071,-0.7071,0.6344,-0.7730,0.5556,-0.8315,0.4714,-0.8819,0.3827,-0.9239,0.2903,-0.9569,
  16.         0.1951,-0.9808,0.0980,-0.9952,0.0,-1.0000,-0.0980,-0.9952,-0.1951,-0.9808,-0.2903,0.9569,-0.3827,-0.9239,
  17.         -0.4714,-0.8819,-0.5556,-0.8315,-0.6344,-0.7730,-0.7071,-0.7071,-0.7730,-0.6344,-0.8315,-0.5556,-0.8819,-0.4714,
  18.         -0.9239,-0.3827,-0.9569,-0.2903,-0.9808,-0.1951,-0.9952,-0.0980
  19. };
  20. uint  data LEDBuf[16];
  21. uint idata refreshflag[16];
  22. uchar fft_sign = 0;                                // 进行fft变换标志位

  23. struct compx
  24. {
  25.         float real;
  26.         float imag;
  27. };
  28. struct compx dd[65];                         // FFT数据   
  29. data struct compx temp;

  30. void delay500ms(void)  
  31. {
  32.     unsigned char a,b,c,n;
  33.     for(c=218;c>0;c--)
  34.         for(b=79;b>0;b--)
  35.             for(a=238;a>0;a--);
  36.     for(n=4;n>0;n--);
  37. }

  38. void Delay(uint n)
  39. {
  40.     uint x;
  41.     while (n--)
  42.     {
  43.         x = 5000;
  44.         while (x--);
  45.     }
  46. }

  47. void GPIO_Init()                                                 // GPIO口的初始化
  48. {
  49.         P1M1  = B(00000011);
  50.         P1M0  = B(00000000);
  51.         P1    = B(00000011);
  52.         P1ASF = B(00000011);
  53. }

  54. void Interrupt_Init(void)                                // 单片机中断初始化
  55. {
  56.         TMOD = 0x01;                                                 // 高4位控制T/C1
  57.         EA = 1;                                                             // 开总中断
  58.         TH0 = 0x00;                                                  // 16位计数寄存器T1高8位
  59.         TL0 = 0x00;                                                  // 16位计数寄存器T1低8位
  60.         ET0 = 1;                                                     // T/C1中断开
  61.     TR0 = 1;                                                     // T/C1启动

  62. }

  63. void ADC_Init()                                                        // 集成ADC的初始化(官方函数)
  64. {
  65.     ADC_RES = 0;                                   //Clear previous result
  66.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
  67.     Delay(2);                                      //ADC power-on and delay
  68. }

  69. uchar GetADCResult(uchar ch)                           // 进行AD转换(官方函数)
  70. {
  71.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
  72.     _nop_();                        //Must wait before inquiry
  73.     _nop_();
  74.     _nop_();
  75.     _nop_();
  76.     while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
  77.     ADC_CONTR &= ~ADC_FLAG;         //Close ADC
  78.     return ADC_RES;                 //Return ADC result
  79. }

  80. void ee(struct compx b1,uchar b2)                         //复数乘法
  81. {
  82.         temp.real=b1.real*iw[2*b2]-b1.imag*iw[2*b2+1];
  83.         temp.imag=b1.real*iw[2*b2+1]+b1.imag*iw[2*b2];
  84. }

  85. uint mypow(uchar  nbottom,uchar  ntop)                 //乘方函数
  86. {
  87.     uint  result=1;
  88.     uchar t;   
  89.     for(t=0;t<ntop;t++)result*=nbottom;
  90.     return result;
  91. }
  92.   
  93. void fft(struct compx *xin,uchar data N)         //快速傅立叶变换
  94. {
  95.         uchar data  fftnum,i,j,k,l,m,n,disbuff,dispos,dissec;
  96.         data struct compx t;
  97.         fftnum=N;                         //傅立叶变换点数
  98.         for(m=1;(fftnum=fftnum/2)!=1;m++);//求得M的值
  99.         for(k=0;k<=N-1;k++)               //码位倒置
  100.         {
  101.                 n=k;
  102.                 j=0;
  103.                 for(i=m;i>0;i--)             //倒置
  104.                 {
  105.                         j=j+((n%2)<<(i-1));
  106.                         n=n/2;
  107.                 }
  108.                 if(k<j){t=xin[1+j];xin[1+j]=xin[1+k];xin[1+k]=t;}//交换数据
  109.         }  
  110.         for(l=1;l<=m;l++)                //FFT运算
  111.         {
  112.                 disbuff=mypow(2,l);          //求得碟间距离
  113.                 dispos=disbuff/2;            //求得碟形两点之间的距离
  114.                 for(j=1;j<=dispos;j++)
  115.                         for(i=j;i<N;i=i+disbuff) //遍历M级所有的碟形
  116.                         {
  117.                                 dissec=i+dispos;     //求得第二点的位置
  118.                                 ee(xin[dissec],(uint)(j-1)*(uint)N/disbuff);//复数乘法
  119.                                 t=temp;
  120.                                 xin[dissec].real=xin[i].real-t.real;
  121.                                 xin[dissec].imag=xin[i].imag-t.imag;
  122.                                 xin[i].real=xin[i].real+t.real;
  123.                                 xin[i].imag=xin[i].imag+t.imag;
  124.                         }
  125.         }
  126. }

  127. void processfft(uchar num)
  128. {
  129.     uchar  pt;
  130.         uint  tmp;
  131.     for(pt=1;pt<65;pt++)
  132.     {
  133.         dd[pt].imag=0;                //清零虚部
  134.     }
  135.     fft(dd,64);                       //对当前数据进行傅立叶变换                 
  136.     for(pt=1;pt<33;pt++)
  137.     {                                      
  138.         dd[pt].real=sqrt(dd[pt].real*dd[pt].real+dd[pt].imag*dd[pt].imag);//取均方根
  139.     }
  140.         switch(num)
  141.         {                                                                  // 选择显示模式
  142.                 case        1:        {       
  143.                                                 for(pt=0;pt<16;pt++)                                                    //         style 1
  144.                                             {      
  145.                                                         LEDBuf[pt]=0xffff;
  146.                                                         tmp = dd[(pt+1)*2].real;
  147.                                                         tmp = (tmp/16)+1;
  148.                                                         LEDBuf[pt]<<=tmp;       
  149.                                                         LEDBuf[pt]=~(LEDBuf[pt]);
  150.                                                 }
  151.                                                 break;
  152.                                         }
  153.                 case        2:        {
  154.                                                 for(pt=0;pt<16;pt++)                                                    //        style 2
  155.                                             {      
  156.                                                         if(refreshflag[pt]<(dd[pt].real/16)+1)                           
  157.                                                         {
  158.                                                                 LEDBuf[pt]=0xffff;
  159.                                                                 tmp = dd[(pt+1)*2].real;
  160.                                                                 tmp = (tmp/16)+1;
  161.                                                                 refreshflag[pt] = tmp;
  162.                                                                 LEDBuf[pt]<<=tmp;
  163.                                                         }
  164.                                                         else
  165.                                                         {
  166.                                                                  if(refreshflag[pt]>1)
  167.                                                                 {
  168.                                                                         refreshflag[pt]--;                        
  169.                                                                 }
  170.                                                                 LEDBuf[pt]=0xffff;
  171.                                                                 tmp = refreshflag[pt];
  172.                                                                 LEDBuf[pt]<<=tmp;
  173.                                                         }
  174.                                                         LEDBuf[pt]=~(LEDBuf[pt]);
  175.                                                 }
  176.                                                 break;
  177.                                         }
  178.                 case        3:        {                                                                                                                //        style 3
  179.                                                 for(pt=0;pt<16;pt++)         
  180.                                             {   
  181.                                                         LEDBuf[pt]=0xffff;
  182.                                                         tmp = dd[(pt+1)*2].real;
  183.                                                         tmp = (tmp/16)+1;
  184.                                                         if(refreshflag[pt]<tmp)                           
  185.                                                         {
  186.                                                                 refreshflag[pt] = tmp;                       
  187.                                                         }
  188.                                                         else
  189.                                                         {
  190.                                                                  if(refreshflag[pt]>1)
  191.                                                                 {
  192.                                                                         refreshflag[pt]--;                        
  193.                                                                 }
  194.                                                                 tmp = refreshflag[pt];                       
  195.                                                         }
  196.                                                         LEDBuf[pt]&=(0x0001<<(tmp-1));
  197.                                                 }
  198.                                                 break;
  199.                                         }

  200.                 case        4:        {                                                                                                           //                style        4
  201.                                                 for(pt=0;pt<16;pt++)         
  202.                                             {   
  203.                                                         LEDBuf[pt]=0xffff;
  204.                                                         tmp = dd[(pt+1)*2].real;
  205.                                                         tmp = (tmp/16)+1;
  206.                                                         LEDBuf[pt]<<=tmp;       
  207.                                                         LEDBuf[pt]=~(LEDBuf[pt]);
  208.                                                         if(refreshflag[pt]<tmp)                           
  209.                                                         {
  210.                                                                 refreshflag[pt] = tmp;                       
  211.                                                         }
  212.                                                         else
  213.                                                         {
  214.                                                                  if(refreshflag[pt]>1)
  215.                                                                 {
  216.                                                                         refreshflag[pt]--;                        
  217.                                                                 }
  218.                                                                 tmp = refreshflag[pt];                       
  219.                                                         }
  220.                                                         LEDBuf[pt]|=(0x0001<<(tmp-1));       
  221.                                                 }
  222.                                         }
  223.         }
  224. }

  225. void main()
  226. {
  227.         uchar i,num=1;
  228.         uint n;
  229.         GPIO_Init();                                // io口初始化
  230.         ADC_Init();                                        // 集成adc初始化
  231.         DS1302Init();                                // 初始化1302
  232.         MyLove();                                        // 开机动画
  233.         while(GetADCResult(0)+GetADCResult(1)==0)                // 没有插入耳机时
  234.         {
  235.                 DisplayTime();                        // 显示时间
  236.                 TimeSetting();                        // 时间设定
  237.         }
  238.         for(i=0;i<16;i++)                        // 清空数据缓存
  239.         {
  240.                 refreshflag[i] = 0x0000;       
  241.         }
  242.         Interrupt_Init();
  243.     while(1)
  244.     {       
  245.                 if(fft_sign == 1)                                                                                                // 读取频率为20Hz
  246.                 {
  247.                         fft_sign = 0;
  248.                         for(i=0;i<65;i++)
  249.                         {  
  250.                                 dd[i].real=(GetADCResult(0)+GetADCResult(1))<<2;                  // 读取ad结果并放大4倍;
  251.                         }
  252.                         processfft(num);                                                                                        // 傅立叶变化及处理
  253.                 }
  254.             for(i=0;i<16;i++)
  255.             {                                                                                                                                // 显示
  256.                 LineInput(0x0000);
  257.                 P2 = ColScan_2[i];
  258.                 LineInput(LEDBuf[i]);
  259.                         n = 512;
  260.                         while(n--);
  261.                         LineInput(0x0000);
  262.                 }
  263.                 if(ACT_Key == 0)                                                                                                // 动作检测,切换效果
  264.                 {
  265.                         num++;
  266.                         if(num>4)
  267.                         {
  268.                                 num = 1;
  269.                         }
  270.                         delay500ms();
  271.                 }                 
  272.         }

  273. }
  274. void Timer0() interrupt 1                        //20hz
  275. {
  276.     TL0 = 0x3c;      
  277.     TH0 = 0xb0;
  278.         fft_sign = 1;
  279. }



  280.        
复制代码


16x16音乐频谱(源代码 原理图).zip

196.15 KB, 下载次数: 195, 下载积分: 黑币 -5

16x16音乐频谱(源代码 原理图)

回复

使用道具 举报

ID:155591 发表于 2016-12-18 15:35 | 显示全部楼层
能发一下实物图,或效果展示视频吗
回复

使用道具 举报

ID:150587 发表于 2016-12-18 18:14 | 显示全部楼层
这音乐的代码可以修改吗
回复

使用道具 举报

ID:155775 发表于 2016-12-18 23:47 | 显示全部楼层
有没有效果图呀呀
回复

使用道具 举报

ID:90996 发表于 2017-6-26 20:11 | 显示全部楼层
想下载没有金币,看看吧
回复

使用道具 举报

ID:169527 发表于 2017-10-17 18:39 来自手机 | 显示全部楼层
这能用吗?那个压缩文件里面的程序和原理图对应?
回复

使用道具 举报

ID:105064 发表于 2017-10-19 18:18 | 显示全部楼层
分享快乐
回复

使用道具 举报

ID:240944 发表于 2017-10-19 23:18 来自手机 | 显示全部楼层
哎,没有金币。。。
回复

使用道具 举报

ID:241152 发表于 2017-10-20 08:48 | 显示全部楼层
非常好,谢谢分享
回复

使用道具 举报

ID:241159 发表于 2017-10-20 09:33 | 显示全部楼层
楼主,是用七彩灯吗?
回复

使用道具 举报

ID:201871 发表于 2017-10-21 13:44 | 显示全部楼层
想看下效果图
回复

使用道具 举报

ID:124995 发表于 2018-2-28 17:39 | 显示全部楼层
很好很不错
回复

使用道具 举报

ID:299231 发表于 2018-4-9 22:15 | 显示全部楼层
效果啥样儿的,还在挣币中。。。
回复

使用道具 举报

ID:314717 发表于 2018-4-24 09:11 来自手机 | 显示全部楼层
wwtor 发表于 2018-4-9 22:15
效果啥样儿的,还在挣币中。。。

怎么挣币啊?貌似评论都要审核
回复

使用道具 举报

ID:128101 发表于 2018-8-1 21:03 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:214103 发表于 2020-1-22 17:22 来自手机 | 显示全部楼层
压缩包里的原理图怎么打不开啊,
回复

使用道具 举报

ID:694488 发表于 2020-3-1 23:02 | 显示全部楼层
33/5000  无法打开文件“ src stc12c5a.h”
回复

使用道具 举报

ID:694488 发表于 2020-3-1 23:02 | 显示全部楼层
  无法打开文件“ src stc12c5a.h”   怎么解决
回复

使用道具 举报

ID:214103 发表于 2020-3-14 05:16 | 显示全部楼层
请问我在keil3中编译的时候出现 :16X16音乐频谱(源代码+原理图)\PROJECT\MAIN.C(298): 错误 C249: 'DATA': SEGMENT TOO LARGE      这个怎么解决啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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