找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4340|回复: 2
收起左侧

stc12c5a60s2单片机音乐频谱程序

  [复制链接]
ID:622100 发表于 2020-5-6 11:33 | 显示全部楼层 |阅读模式
stc12c5a60s2单片机的IO口自带AD转换接口,而stc89c51需要使用AD转换模块,程序太长,懒得复制,都在压缩包里面。注意水银开关的接法,如果不需要第二种功能的可以指教短接。新手上路,请大家指教!!!
1588819857.jpg

单片机源程序如下:
  1. #include <stc12c5a60s2.h>//"stc12c5620ad.h"
  2. #include <intrins.h>
  3. #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))
  4. #define BIN(n) LongToBin(0x##n##)
  5. #define uchar  unsigned char
  6. #define uint  unsigned int
  7. #define SAMPLE_NUM 64
  8. #define NUM_2_LOG 6
  9. #define FFT_OUT_MIN 1
  10. #define FFT_OUT_MAX        11
  11. uchar code BRTable[SAMPLE_NUM] ={
  12. 0, 32, 16, 48, 8, 40, 24, 56,4, 36, 20, 52, 12, 44, 28, 60, 2, 34, 18, 50, 10, 42, 26,
  13. 58, 6, 38, 22, 54, 14, 46, 30, 62, 1, 33, 17, 49, 9, 41, 25, 57,5, 37, 21, 53, 13, 45,
  14. 29, 61,3, 35, 19, 51, 11, 43, 27, 59,7, 39, 23, 55, 15, 47, 31, 63};
  15. char code sin_tabb[SAMPLE_NUM] = {
  16. 0 ,12 ,25 ,37 ,49 ,60 ,71 ,81 ,90 ,98 ,106 ,112 ,117 ,122 ,125 ,126 ,127 ,126 ,125 ,
  17. 122 ,117 ,112 ,106 ,98 ,90 ,81 ,71 ,60 ,49 ,37 ,25 ,12 ,0 ,-12 ,-25 ,-37 ,-49 ,-60 ,
  18. -71 ,-81 ,-90 ,-98 ,-106 ,-112 ,-117 ,-122 ,-125 ,-126 ,-127 ,-126 ,-125 ,-122 ,-117
  19. ,-112 ,-106 ,-98 ,-90 ,-81 ,-71 ,-60 ,-49 ,-37 ,-25 ,-12  };
  20.                                  
  21. char code cos_tabb[SAMPLE_NUM] = {
  22. 127 ,126 ,125 ,122 ,117 ,112 ,106 ,98 ,90 ,81 ,71 ,60 ,49 ,37 ,25 ,12 ,0 ,-12 ,-25 ,
  23. -37 ,-49 ,-60 ,-71 ,-81 ,-90 ,-98 ,-106 ,-112 ,-117 ,-122 ,-125 ,-126 ,-127 ,-126 ,-125 ,
  24. -122 ,-117 ,-112 ,-106 ,-98 ,-90 ,-81 ,-71 ,-60 ,-49 ,-37 ,-25 ,-12 ,0 ,12 ,25 ,37 ,49
  25. ,60 ,71 ,81 ,90 ,98 ,106 ,112 ,117 ,122 ,125 ,126 };
  26. uchar a[64];
  27. uchar keep,keepnum,anum,timernum,timernum2,lednum3,Ltime;//用于分离

  28. /*加入数组用于显示相应led灯数目*/
  29. uchar lednum[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};//0-7的显示数组  P2组控制

  30. int xdata FftReal[SAMPLE_NUM];
  31. int xdata FftImage[SAMPLE_NUM];

  32. xdata unsigned char num[128];
  33. xdata unsigned char temp[128];

  34. sbit p37=P3^7;
  35. sbit p36=P3^6;
  36. sbit p35=P3^5;
  37. sbit p34=P3^4;

  38. sbit p07=P0^7;
  39. sbit p06=P0^6;
  40. sbit p05=P0^5;
  41. sbit p04=P0^4;
  42. sbit p03=P0^3;
  43. sbit p02=P0^2;
  44. sbit p01=P0^1;
  45. sbit p00=P0^0;

  46. sbit p27=P2^7;
  47. sbit p26=P2^6;
  48. sbit p25=P2^5;
  49. sbit p24=P2^4;
  50. sbit p23=P2^3;
  51. sbit p22=P2^2;
  52. sbit p21=P2^1;
  53. sbit p20=P2^0;

  54. sbit key=P3^3;
  55. sbit zh=P3^0;

  56. void delay(unsigned char a)
  57. {
  58.         unsigned int i;
  59.         while(--a)
  60.                 for(i=0;i<50;i++);                                    
  61. }
  62. void timerinit()//定时器 初始化函数
  63. {
  64.          TMOD=0x11;
  65.          TH0=(65536-2048)/256;
  66.          TL0=(65536-2048)%256;

  67.          TH1=(65536-50000)/256;
  68.          TL1=(65536-50000)%256;

  69.          EA=1;
  70.          ET0=1;
  71.          TR0=1;

  72.          ET1=0;
  73.          TR1=0;
  74. }

  75. void FFT_process()                          //下落迟滞
  76. {
  77.         unsigned char i;
  78.         for(i=0;i<14;i++)
  79.         {        
  80.                 if(a[i] < temp[i])
  81.                 {
  82.                         num[i]++;
  83.                         if(num[i] == 1)
  84.                         {
  85.                                 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);
  86.                                 else
  87.                                 {
  88.                                         a[i] = --temp[i];
  89.                                         num[i] = 0;
  90.                                 }
  91.                         }
  92.                 }
  93.                 else num[i] = 0;               
  94.         }
  95. }

  96. void disp()
  97. {
  98.         timernum++;
  99.         if(timernum==15) timernum=1;
  100.         P2=0x00;//显示前先关闭

  101.         p37=1;
  102.         p36=1;
  103.         p35=1;
  104.         p34=1;

  105.         P0=0Xff;
  106.         FFT_process();
  107.         switch(timernum)
  108.         {
  109.                 case 1:anum=a[0];break;//
  110.                 case 2:anum=a[1];break;//
  111.                 case 3:anum=a[2];p37=0;break;
  112.                 case 4:anum=a[3];p36=0;break;
  113.                 case 5:anum=a[4];p35=0;break;
  114.                 case 6:anum=a[5];p34=0;break;
  115.                 case 7:anum=a[6];p07=0;break;
  116.                 case 8:anum=a[7];p06=0;break;
  117.                 case 9:anum=a[8];p05=0;break;
  118.                 case 10:anum=a[9];p04=0;break;
  119.                 case 11:anum=a[10];p03=0;break;
  120.                 case 12:anum=a[11];p02=0;break;//
  121.                 case 13:anum=a[12];p01=0;break;//
  122.                 case 14:anum=a[13];p00=0;break;//
  123.         }
  124.         P2=lednum[anum];
  125.         delay(2);
  126. }

  127. uchar STC_ADC()                   //!!根据数据手册写一个ad读取函数  buyonggai
  128. {                                                                                                
  129.      uchar i;
  130.      ADC_RES   = 0;
  131.      ADC_RESL  = 0;
  132.          ADC_CONTR = BIN(10001000);
  133.          i=3;
  134.      while(i--);
  135.      while (1)                     
  136.      {
  137.          if (ADC_CONTR & BIN(10000))      
  138.               {
  139.                              break;
  140.                     }
  141.      }
  142.      ADC_CONTR = BIN(10000000);
  143.            return( ADC_RESL<<2) ;
  144. }
  145. short sqrt_16( unsigned long M)   
  146. {
  147.     unsigned int N, i;
  148.     unsigned long tmp, ttp;
  149.     if( M == 0 )            
  150.         return 0;
  151.    
  152.     N = 0;
  153.    
  154.     tmp = ( M >> 30 );        
  155.     M <<= 2;
  156.     if( tmp > 1 )            
  157.     {
  158.         N ++;               
  159.         tmp -= N;
  160.     }
  161.    
  162.     for( i=15; i>0; i-- )   
  163.     {
  164.         N <<= 1;           
  165.         
  166.         tmp <<= 2;
  167.         tmp += (M >> 30);  
  168.         
  169.         ttp = N;
  170.         ttp = (ttp<<1)+1;
  171.         
  172.         M <<= 2;
  173.         if( tmp >= ttp )   
  174.         {
  175.             tmp -= ttp;
  176.             N ++;
  177.         }      
  178.     }
  179.    
  180.     return N;
  181. }
  182. void FFT()
  183. {
  184.         register    uchar i,bb,j,k,p,max;
  185.         register short TR,TI,temp;
  186.     unsigned long ulReal;                             
  187.     unsigned long ulImage;   
  188.                                                                  
  189.         for(i=0; i<SAMPLE_NUM;i++)          //此处可以加入自动增益
  190.         {
  191.                 FftReal[BRTable[i]] = STC_ADC();//使显示保持在一定范围内
  192.         FftImage[i] = 0;               
  193.         }
  194.    
  195.     for( i=1; i<=NUM_2_LOG; i++)                          
  196.     {
  197.         bb=1;
  198.         bb <<= (i-1);                                      
  199.         for( j=0; j<=bb-1; j++)                           
  200.         {
  201.             p=1;
  202.             p <<= (NUM_2_LOG-i);            
  203.             p = p*j;
  204.             for( k=j; k<SAMPLE_NUM; k=k+2*bb)               
  205.             {
  206.                 TR = FftReal[k]; TI = FftImage[k]; temp = FftReal[k+bb];
  207.                 FftReal[k] = FftReal[k] + ((FftReal[k+bb]*cos_tabb[p])>>7) + ((FftImage[k+bb]*sin_tabb[p])>>7);
  208.                 FftImage[k] = FftImage[k] - ((FftReal[k+bb]*sin_tabb[p])>>7) + ((FftImage[k+bb]*cos_tabb[p])>>7);
  209.                 FftReal[k+bb] = TR - ((FftReal[k+bb]*cos_tabb[p])>>7) - ((FftImage[k+bb]*sin_tabb[p])>>7);
  210.                 FftImage[k+bb] = TI + ((temp*sin_tabb[p])>>7) - ((FftImage[k+bb]*cos_tabb[p])>>7);
  211.                
  212.                 FftReal[k]  >>= 1;            
  213.                 FftImage[k]  >>= 1;
  214.                 FftReal[k+bb]  >>= 1;                 
  215.                 FftImage[k+bb]  >>= 1;                                                                 
  216.             }  
  217.         }
  218.     }
  219.         max=0;
  220.     for( i=0; i<14; i++)
  221.     {  
  222.         ulReal = FftReal[i+1];
  223.         ulReal *= ulReal;
  224.         ulImage = FftImage[i+1];
  225.         ulImage *= ulImage;
  226.         
  227.         a[i] = sqrt_16( ulReal + ulImage );   //修改
  228.                         
  229.         if( a[i] < FFT_OUT_MIN ) //   
  230.             a[i] = 0;//修改
  231.         else
  232.           a[i] = a[i]-FFT_OUT_MIN;   
  233.                   
  234.         if( a[i] >max)
  235.              max =a[i];                                 
  236.     }

  237.     if(max>8) //11
  238.     {
  239.        max/=8;        
  240.         for( i=0; i<14; i++) //输出a的5个分离数值
  241.         {      
  242.              a[i]/=max;
  243.         }  
  244.     }
  245. }            
复制代码
/////--------------------------------剩余代码在压缩包内--------------------------------------------------
全部代码51hei下载地址:
音乐频谱.rar (50.64 KB, 下载次数: 111)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1 发表于 2020-5-6 22:46 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

ID:836579 发表于 2022-5-20 17:23 | 显示全部楼层
求原理图
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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