找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 26785|回复: 41
打印 上一主题 下一主题
收起左侧

音频频谱显示(原理图 源代码 开源 第一版)

  [复制链接]
跳转到指定楼层
楼主


很久没出新作品给大家了,其实不是不想出,而是开学这段时间太忙,从八月底到九月中旬,一直为新生忙碌着,自己的时间都很少。暑假闲在家里,也因为要体验“离开互联网的日子”而未曾碰触电脑(最近在整理假期离开网络生活的文字,希望大家可以了解另一个我)。所以也不曾出教学视频,觉得很对不住大家。

工作的时候,忙里偷闲,开通了新浪微博和新浪博客,感谢新浪推出的微号功能,让我的域名得以和QQ号码一样。以后工作室的动态会同步到新浪微博,作品和相关资料下载也会同步到新浪博客,希望大家多多关注!

频谱原理图:



新学期新气象,教学视频会保持更新,并加快进度,工作室也做好了新的工作计划,会有更优质的作品奉献给大家。
希望喜欢工作室作品的朋友将我们的作品和精神分享,我们坚持创新,坚持开源!
这次的小作品是频谱显示,8*16led显示点阵配合stc12系列单片机系统,就可以自己制作廉价的频谱显示了!
原理图请登录百度网盘下载。关于原理图我想说的是,这是原理图,不是封装图,所以大多数IC是看不到Vcc或者Gnd的,但不代表没有,希望初学者留意。
这次的程序不是本人编写,是我师弟的设计,程序是有缺陷的,比如音效的延时,显示的效果等,有耐心的朋友可以自己修改程序,这次的作品在于分享数模转换程序和FFT算法,我也希望网友可以将完善的程序分享到网上,大家共同进步!!!
实物照片:

下面是我的焊接工程,不熟悉电路布局的童鞋可以做为参考
点阵正面  

点阵背面  

系统板正面

系统板背面

成品   


在这里要说的是,焊接并不算复杂,无非就是点阵的焊接耗时耗力,要是有点焊接功夫,小半天也足够了,焊接的时候千万不要弄断管脚,弯折的管脚做跳线最好不过(图3)。系统板的布局我建议大家紧凑一些,我自己焊接的时候是考虑到这板子以后可能加个时间显示什么的,所以预留了一些空间,这样以后再做点阵显示的时候就方便多了


源程序:
  1. #include<stc12c5a.h>
  2. #include<intrins.h>
  3. //#include"basic.h"
  4. typedef unsigned char uint8;
  5. typedef unsigned int uint16;
  6. #define ADC_FLAG    (1<<4)    /*ADC_中断标志*/
  7. /*放大128倍后的sin整数表(128)*/       
  8. 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,
  9.                         105,108,112,114,117,119,121,123,124,125,126,126,126,126,126,
  10.                                                 125,124,123,121,119,117,114,112,108,105,102,98,94,89,85,80,75,
  11.                                                 70,65,59,54,48,42,36,30,24,18,12,6,0,-6,-12,-18,-24,-30,-36,-42,
  12.                                                 -48,-54,-59,-65,-70,-75,-80,-85,-89,-94,-98,-102,-105,-108,-112,
  13.                                                 -114,-117,-119,-121,-123,-124,-125,-126,-126,-126,-126,-126,-125,
  14.                                                 -124,-123,-121,-119,-117,-114,-112,-108,-105,-102,-98,-94,-89,-85,
  15.                                                 -80,-75,-70,-65,-59,-54,-48,-42,-36,-30,-24,-18,-12,-6
  16.                                            };

  17. /*放大128倍后的cos整数表(128)*/
  18. code char COS_TAB[128]={127,126,126,125,124,123,121,119,117,114,112,108,105,102,98,94,
  19.                         89,85,80,75,70,65,59,54,48,42,36,30,24,18,12,6,0,-6,-12,-18,-24,
  20.                                                 -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,
  22.                                                 -126,-126,-125,-124,-123,-121,-119,-117,-114,-112,-108,-105,-102,
  23.                                                 -98,-94,-89,-85,-80,-75,-70,-65,-59,-54,-48,-42,-36,-30,-24,-18,
  24.                                                 -12,-6,0,6,12,18,24,30,36,42,48,54,59,65,70,75,80,85,89,94,98,102,
  25.                                                 105,108,112,114,117,119,121,123,124,125,126,126
  26.                                            };

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

  35. /*分级量化表*/
  36. uint8 QTY_TAB[] = {0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
  37. uint8 ADC_Count=0;
  38. uint8 i,j,k,b,p,anum;       
  39. uint16 xdata Fft_Real[128];
  40. uint16 xdata Fft_Image[128];               // fft的虚部
  41. uint8 xdata LED_TAB[16];                                //记录红色柱状

  42. /********************************************************************
  43. * 名称 : FFT
  44. * 功能 : 碟型运算转换
  45. * 输入 : 无
  46. * 输出 : 读出的值
  47. ***********************************************************************/
  48. void FFT()//基2fft
  49. {                 
  50.         uint16 Temp_Real,Temp_Imag,temp;                // 中间临时变量
  51.         uint16 TEMP1 = 0,max=0;
  52.         for( i=1; i<=7; i++)                            /* for(1) */
  53.         {
  54.                 b=1;
  55.                 b <<=(i-1);                                 //碟式运算,用于计算隔多少行计算例如 第一极 1和2行计算
  56.                 for( j=0; j<=b-1; j++)                      /* for (2) */
  57.                 {
  58.                         p=1;
  59.                         p <<= (7-i);            
  60.                         p = p*j;
  61.                         for( k=j; k<128; k=k+2*b)               /* for (3)  */
  62.                         {
  63.                                 Temp_Real=Fft_Real[k];
  64.                                 Temp_Imag=Fft_Image[k];
  65.                                 temp=Fft_Real[k+b];
  66.                                 Fft_Real[k]=Fft_Real[k]+((Fft_Real[k+b]*COS_TAB[p])>>7)+((Fft_Image[k+b]*SIN_TAB[p])>>7);
  67.                                 Fft_Image[k]=Fft_Image[k]-((Fft_Real[k+b]*SIN_TAB[p])>>7)+((Fft_Image[k+b]*COS_TAB[p])>>7);
  68.                                 Fft_Real[k+b]=Temp_Real-((Fft_Real[k+b]*COS_TAB[p])>>7)-((Fft_Image[k+b]*SIN_TAB[p])>>7);
  69.                                 Fft_Image[k+b]=Temp_Imag+((temp*SIN_TAB[p])>>7)-((Fft_Image[k+b]*COS_TAB[p])>>7);          // 移位.防止溢出. 结果已经是本值的 1/64               
  70.                                 Fft_Real[k] >>= 1;            
  71.                                 Fft_Image[k] >>= 1;
  72.                                 Fft_Real[k+b] >>= 1;                 
  73.                                 Fft_Image[k+b] >>= 1;                                                      
  74.                         }     
  75.                 }
  76.         }
  77.        
  78.         for(j=0;j<16;j++)//16分频                                                                                         
  79.         {                                                                                                                                                          
  80.                 TEMP1=((((Fft_Real[j+1]* Fft_Real[j+1]))+((Fft_Image[j+1]*Fft_Image[j+1])))>>1);//求各频段幅值
  81.                 if(TEMP1<1)TEMP1=0;
  82.                 LED_TAB[j]=TEMP1;       
  83.                 if(LED_TAB[j]>max)max=LED_TAB[j];
  84.         }
  85.         if(max > 16)//分级量化
  86.         {
  87.                 max/=16;
  88.                 for(j=0;j<16;j++)LED_TAB[j]/=max;
  89.         }      
  90. }

  91. /********************************************************************
  92. * 名称 : GPIO_init
  93. * 功能 : GPIO初始化
  94. * 输入 : 无
  95. * 输出 : 读出的值
  96. ***********************************************************************/
  97. void GPIO_init()
  98. {
  99.         P0M0 = 1; P0M1 = 0; P0 = 0XFF;    /*列*/
  100.         P2M0 = 1; P2M1 = 0; P2 = 0XFF;
  101.         P3M0 = 1; P3M1 = 0; P3 = 0XFF;          /*行*/
  102. }
  103. /********************************************************************
  104. * 名称 : timer_Init
  105. * 功能 : 内部寄存器初始化
  106. * 输入 : 无
  107. * 输出 : 无
  108. ***********************************************************************/
  109. void timer_Init()
  110. {
  111.         TMOD = 0X12;
  112.         TH0 = 0xb0;                                                                   
  113.         TL0 = 0xb0;
  114.         ET0 = 1;                                               //定时器0 打开
  115.         TR0 = 0;                                                      //关闭定时器
  116.         TH1 = 0xfd;                                                                                                 
  117.         TL1 = 0Xa8;
  118.         ET1  = 1;
  119.         TR1  = 1;       
  120.         EA   = 1;       
  121. }
  122. /********************************************************************
  123. * 名称 : adc_Init
  124. * 功能 : 内部寄存器初始化
  125. * 输入 : 无
  126. * 输出 : 无
  127. ***********************************************************************/
  128. void adc_Init()
  129. {         
  130.         ADC_CONTR = 0x80;             //ADC电源打开
  131.         _nop_();_nop_();_nop_();_nop_();
  132.         P1ASF = 0x01;                 //0000,0001, 将 P1.0 置成模拟口
  133.         AUXR1 &=0xFB;                 //1111,1011, 令 ADRJ=0
  134.         ADC_RES = 0x00;               //清零寄存器
  135.         ADC_RESL = 0x00;
  136.         EADC  = 1;                                          //AD中断打开
  137.         EA = 1;                                                  //总中断打开
  138. }

  139. /********************************************************************
  140. * 名称 : main
  141. * 功能 : 主程序
  142. * 输入 : 无
  143. * 输出 : 无
  144. ***********************************************************************/
  145. void main()
  146. {
  147.         uint8 i = 0;
  148.         GPIO_init();
  149.         timer_Init();
  150.         adc_Init();
  151.         while(1)
  152.         {
  153.                 ADC_Count = 0;
  154.                 EADC = 1;
  155.                 TR0  = 1;
  156.                 while(ADC_Count < 128);       //满足128点
  157.                 for(i=0; i<128; i++)                  //清除虚部
  158.                 {
  159.                         Fft_Image[i] = 0;
  160.                 }
  161.                 FFT();                        //FFT运算并转换为各频段幅值

  162.         }
  163. }
  164. /********************************************************************
  165. * 名称 : ADC_Finish
  166. * 功能 : ADC转换完成中断服务
  167. * 输入 : 无
  168. * 输出 : 无
  169. ***********************************************************************/
  170. void ADC_Finish() interrupt 5
  171. {
  172.         Fft_Real[LIST_TAB[ADC_Count]] = (int)(((ADC_RES)<<1)+(ADC_RESL>>1)*2)>>3;    /*按LIST_TAB表顺序,进行存储采样值*/
  173.         if(ADC_Count <= 127)
  174.         {
  175.                 ADC_Count++;           /*自动增量控制*/
  176.                 ADC_CONTR &= !ADC_FLAG;
  177.         }
  178.         else
  179.         {
  180.                 EADC = 0;
  181.                 TR0  = 0;       
  182.         }                       
  183. }
  184. /********************************************************************
  185. * 名称 : interrupt_timer1
  186. * 功能 : 显示屏幕刷新中断服务
  187. * 输入 : 无
  188. * 输出 : 无
  189. ***********************************************************************/
  190. void interrupt_timer1() interrupt 3
  191. {       
  192.         static uint8 rec = 0;
  193.         TH1 = 0xfd;                                                                                                 
  194.         TL1 = 0Xa8;

  195.         switch(rec)                                                                     //往点阵屏填充一列的数据
  196.         {
  197.                 case 0: P0 = QTY_TAB[LED_TAB[0]]; P2 = 0;break;
  198.                 case 1: P0 = QTY_TAB[LED_TAB[1]]; P2 = 1;break;                 
  199.                 case 2: P0 = QTY_TAB[LED_TAB[2]]; P2 = 2;break;       
  200.                 case 3: P0 = QTY_TAB[LED_TAB[3]]; P2 = 3;break;       
  201.                 case 4: P0 = QTY_TAB[LED_TAB[4]]; P2 = 4;break;       
  202.                 case 5: P0 = QTY_TAB[LED_TAB[5]]; P2 = 5;break;               
  203.                 case 6: P0 = QTY_TAB[LED_TAB[6]]; P2 = 6;break;       
  204.                 case 7: P0 = QTY_TAB[LED_TAB[7]]; P2 = 7;break;
  205.                 case 8: P0 = QTY_TAB[LED_TAB[8]]; P2 = 8;break;
  206.                 case 9: P0 = QTY_TAB[LED_TAB[9]]; P2 = 9;break;                 
  207.                 case 10: P0 = QTY_TAB[LED_TAB[10]]; P2 = 10;break;       
  208.                 case 11: P0 = QTY_TAB[LED_TAB[11]]; P2 = 11;break;       
  209.                 case 12: P0 = QTY_TAB[LED_TAB[12]]; P2 = 12;break;       
  210.                 case 13: P0 = QTY_TAB[LED_TAB[13]]; P2 = 13;break;               
  211.                 case 14: P0 = QTY_TAB[LED_TAB[14]]; P2 = 14;break;       
  212.                 case 15: P0 = QTY_TAB[LED_TAB[15]]; P2 = 15;break;               
  213.                 default:break;
  214.         }
  215.         rec++;
  216.         if(rec > 15)
  217.         {
  218.                 rec = 0;
  219.         }
  220. }
  221. /********************************************************************
  222. * 名称 : Ad_Control
  223. * 功能 : 控制采样率
  224. * 输入 : 无
  225. * 输出 : 无
  226. ***********************************************************************/
  227. void Ad_Control() interrupt 1
  228. {
  229.         ADC_CONTR = 0xe8;                     //开始AD采集
  230.         _nop_();_nop_();_nop_();_nop_();         
  231. }

复制代码





音频显示(STC12系列老版).zip

733.11 KB, 下载次数: 265, 下载积分: 黑币 -5

LED频谱开源版资料(STC15系列新版).zip

143.45 KB, 下载次数: 335, 下载积分: 黑币 -5

评分

参与人数 2黑币 +38 收起 理由
angmall + 35 共享资料的黑币奖励!
qjzyx + 3 赞一个!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏34 分享淘帖 顶4 踩
回复

使用道具 举报

沙发
ID:94392 发表于 2015-11-2 20:25 来自手机 | 只看该作者
楼主,谢谢你的制作,我也正再做,希望可以请教你,可以加我QQ  1336294189谢谢
回复

使用道具 举报

板凳
ID:134722 发表于 2016-7-29 17:21 | 只看该作者
这个好!MCU的处理量比较大喔
回复

使用道具 举报

地板
ID:112693 发表于 2016-8-8 00:04 | 只看该作者
这个有意思,回头DIY一个
回复

使用道具 举报

5#
ID:17396 发表于 2016-8-23 10:01 | 只看该作者
有意思,希望能够学习到并做到
回复

使用道具 举报

6#
ID:137539 发表于 2016-8-25 16:31 | 只看该作者
不错,学习学习,谢谢分享,回头做一做
回复

使用道具 举报

7#
ID:141649 发表于 2016-10-8 11:41 来自手机 | 只看该作者
一直在找频谱的资料,通俗易懂
回复

使用道具 举报

8#
ID:141143 发表于 2016-10-14 22:48 | 只看该作者
谢谢分享.........
回复

使用道具 举报

9#
ID:186696 发表于 2017-4-6 15:08 | 只看该作者
学习了,感谢楼主分享资源
回复

使用道具 举报

10#
ID:221681 发表于 2017-7-22 23:12 | 只看该作者
好东西,收藏了
回复

使用道具 举报

11#
ID:221117 发表于 2017-7-23 09:47 | 只看该作者
收藏,尽快做一个出来
回复

使用道具 举报

12#
ID:48413 发表于 2017-8-7 19:32 | 只看该作者
谢谢,学习一下
回复

使用道具 举报

13#
ID:68429 发表于 2017-9-25 21:53 来自手机 | 只看该作者
楼主强
回复

使用道具 举报

14#
ID:241982 发表于 2017-10-27 01:42 | 只看该作者
正在制作一个功放缺一个音频显示,正好。。。。。谢谢楼主
回复

使用道具 举报

15#
ID:241982 发表于 2017-10-27 01:49 | 只看该作者
有效果图吗!
回复

使用道具 举报

16#
ID:241982 发表于 2017-10-27 01:49 | 只看该作者
楼主什么时候更新第二版呢!期待
回复

使用道具 举报

17#
ID:98767 发表于 2017-11-12 15:13 | 只看该作者
谢谢楼主分享,下个研究下,自己也DIY一个,好像视频看不了
回复

使用道具 举报

18#
ID:254064 发表于 2017-11-27 10:48 | 只看该作者
非常感谢楼主的分享,我在protues中按照您的方法接好运行了,但是不知道如何输入音频信号,请问这个可以说一下吗,谢谢!
回复

使用道具 举报

19#
ID:282866 发表于 2018-2-7 16:28 | 只看该作者
非常感谢!!!!!!
回复

使用道具 举报

20#
ID:282726 发表于 2018-2-7 19:10 | 只看该作者
视频怎么看不了
另外,两个点阵的接法,怎么不一样呢
回复

使用道具 举报

21#
ID:266116 发表于 2018-2-7 22:44 | 只看该作者
做的很好看!
回复

使用道具 举报

22#
ID:282866 发表于 2018-3-6 11:32 | 只看该作者
很感谢!非常的需要
回复

使用道具 举报

23#
ID:282866 发表于 2018-3-6 11:32 | 只看该作者
我正好也在做,不知道怎么下手
回复

使用道具 举报

24#
ID:338306 发表于 2018-5-25 20:41 | 只看该作者
楼主焊功牛逼啊~
回复

使用道具 举报

25#
ID:431129 发表于 2018-11-22 13:25 | 只看该作者
楼主雪里送炭,我正非常需要这个资料。谢谢!
回复

使用道具 举报

26#
ID:425041 发表于 2018-11-22 16:31 | 只看该作者
我是能做出来就是不会写程序
回复

使用道具 举报

27#
ID:399179 发表于 2018-11-23 21:12 来自手机 | 只看该作者
感谢分享!
回复

使用道具 举报

28#
ID:490130 发表于 2019-3-13 18:16 | 只看该作者
感谢分享!
回复

使用道具 举报

29#
ID:490130 发表于 2019-3-13 18:17 | 只看该作者
感谢分享!
回复

使用道具 举报

30#
ID:503342 发表于 2019-4-2 16:21 | 只看该作者
感激不尽
回复

使用道具 举报

31#
ID:399179 发表于 2019-4-2 20:02 来自手机 | 只看该作者
谢谢楼主分享!
回复

使用道具 举报

32#
ID:27919 发表于 2019-8-9 15:14 | 只看该作者
谢谢!正需要,太高兴了。
回复

使用道具 举报

33#
ID:13396 发表于 2019-9-17 22:31 | 只看该作者
学习了,感谢楼主分享资源.
回复

使用道具 举报

34#
ID:517951 发表于 2019-12-12 17:48 | 只看该作者
楼主,好文章,学习啦
回复

使用道具 举报

35#
ID:681106 发表于 2020-1-4 16:39 | 只看该作者
最近在做,但好多都不懂,谢谢博主的分享
回复

使用道具 举报

36#
ID:681106 发表于 2020-1-4 16:41 | 只看该作者
谢谢,最近在做,希望能后期再出点更详细的教程,谢谢
回复

使用道具 举报

37#
ID:595367 发表于 2020-2-25 15:55 | 只看该作者
很好,值得参考
回复

使用道具 举报

38#
ID:373976 发表于 2020-3-26 15:59 | 只看该作者
感谢楼主的分享
回复

使用道具 举报

39#
ID:97023 发表于 2020-3-26 22:07 | 只看该作者
51黑电子名字 发表于 2017-11-27 10:48
非常感谢楼主的分享,我在protues中按照您的方法接好运行了,但是不知道如何输入音频信号,请问这个可以说 ...

不知道是否对你有帮助:


回复

使用道具 举报

40#
ID:895005 发表于 2021-6-7 17:36 | 只看该作者
你好 请问一下 信号输入 是要接音频座吗    那么接到哪个口上呢?希望回复一下    谢谢了!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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