[应用相关] 折腾了一个月,终于搞成了音乐频谱,分别在OLED和LCD上显示

[复制链接]
1181|17
 楼主| conjunction 发表于 2020-3-21 17:31 | 显示全部楼层 |阅读模式
原贴链接:http://www.openedv.com/forum.php?mod=viewthread&tid=265897&extra=page%3D1%26filter%3Ddigest%26digest%3D1

折腾了一个月,终于搞成了音乐频谱,分别形成了在OLED和LCD彩屏上显示的两个版本。
STM32单片机从大半年前才开始自学的(前几年曾陆续自学了PIC和AVR.)。老朽已过古稀之年,自学中的酸甜苦辣只有自己知道。
现将这个音乐频谱的资料分享给大家,望提出宝贵的意见。
 楼主| conjunction 发表于 2020-3-21 17:31 | 显示全部楼层
      关于代码的几点说明:
      一、OLED屏是用的中景园的1.3寸屏和STM32F103C8T6的小系统板。LCD是用的是普中的屏和实验板(STM32F103ZET6),屏是ILI9341的3.2寸屏。各位移植时管脚连接可能不同,要注意修改相关的代码!
 楼主| conjunction 发表于 2020-3-21 17:32 | 显示全部楼层
      二、FFT转换使用的是ST提供的DSP_LIB的库函数。本例中采样频率为40KZ,采样点数是256点。但实际显示时,各柱条的频点的却是从256点中挑选出来的,因为音频的范围虽然是10Z-20KZ,但人声和乐器的频率主要集中在0-4KZ,4KZ-8KZ次之,而8KZ-20KZ段主要是高次谐波。
 楼主| conjunction 发表于 2020-3-21 18:20 | 显示全部楼层
     三、经FFT变换取模后,越是频率高的频点,其模值幅度越小,所以显示效果不好。且经FFT变换后,虽有256个频点,但后面的128个频点是和前面的128个频点成镜像的,所以只要从前面的128个频点里挑选就可以了。同时还要去掉第一个频点,因为第一个频点是直流分量,是不会跳动的,所以如果保留了第一个频点,那么在屏的最左边始终有一根不动的且满幅度的柱条,显得十分呆板,大煞风景。
 楼主| conjunction 发表于 2020-3-21 18:21 | 显示全部楼层
四、ADC采样软件触发方式,同时用TIM2定时器的溢出中断来设置一个标志位,当256点采集完成后,该标志位置位,再开始做FFT变换、计算幅值和显示。
 楼主| conjunction 发表于 2020-3-21 18:21 | 显示全部楼层
五、低频段的幅值一般较大,频率越高幅值越小,为了提高显示效果,使各柱条跳动的幅度较为均衡,我在程序里安排了用软件方式对增益做些适当的调整,即压缩较大的幅值,加大较小的幅值。
 楼主| conjunction 发表于 2020-3-21 18:22 | 显示全部楼层
六、如果实际使用在音响电路里,ADC的取样点可以是前级放大器,也可以取自功放。这时最好加上自动增益控制电路,以均衡采样的幅度;为了克服混叠效应和栅栏泄漏,最好要加上低通滤波电路(最好是2-4阶,以达到衰减较为陡峭的目的。);同时还要加上电平平移电路,因为单片机采样时是不接受负电压的。这些内容我之前曾发过一个帖子,有相关的电路图和PCB的图,各位如需要可移步查看。
 楼主| conjunction 发表于 2020-3-21 18:23 | 显示全部楼层
补遗:
上面的说明中提到FFT转换后的第一个频点是直流分量,有些不太准确。因为如果是采样的音频信号,且加了隔直流电容的话,第一个频点就不是直流分量,而是最低频率点。
对选取的频点又做了写调整,减少了几个点,大于12KZ的就没有选了,因为大于12KZ的柱条跳动的幅度太小,同时这样可以使显示的柱条稍宽些,看上去更舒服些。
 楼主| conjunction 发表于 2020-3-21 18:24 | 显示全部楼层
//从取模结果lBUFMAG中(前128个)挑选出25个值做显示。挑选的原则是:0-4K为主,4K-8K次之,8K-18K最少。将挑选出的32个值赋给COLUMN1

  1. void arctan(void)
  2. {   
  3.      u8 i,temp,a[16]={12,15,19,21,25,28,31,37,44,50,63,71,76,89}; //因为后14个无规律,所以将其位置号列出来
  4.     //u8 j=2;
  5.     for(i=0;i<11;i++)
  6.         { COLUMN1= lBUFMAG;}  //挑选前面11个。
  7.                                 
  8.     for(i=0;i<14;i++)  //后14个
  9.         {
  10.            temp=a;
  11.            COLUMN1[i+11]=lBUFMAG[temp];      
  12.         }        
  13.          
  14.     for(i=0;i<25;i++)  //增益调整
  15.        {   
  16.           COLUMN1=COLUMN1*10;
  17.           //COLUMN1=80*atan(COLUMN1); //用反正切函数来适当压缩较高的模的值,使柱条显示均衡
  18.           if(COLUMN1==0)
  19.                {COLUMN1=2;}
  20.           else if((COLUMN1<5)&&(COLUMN1>0))
  21.                {COLUMN1=COLUMN1+15;}
  22.           else if((COLUMN1>=5)&&(COLUMN1<10))
  23.                {COLUMN1=COLUMN1+12;}
  24.            else if((COLUMN1>=10)&&(COLUMN1<15))
  25.                {COLUMN1=COLUMN1+10;}
  26.            else if((COLUMN1>=15)&&(COLUMN1<20))
  27.                {COLUMN1=COLUMN1+7;}
  28.                
  29.            else if(COLUMN1>=240)
  30.                {COLUMN1=220;}                          
  31.           else if((COLUMN1>=225)&&(COLUMN1<=235))
  32.              {COLUMN1=COLUMN1-30;}
  33.                                          
  34.     }
  35. }
 楼主| conjunction 发表于 2020-3-21 18:24 | 显示全部楼层
相关的AGC和低通电路及PCB:

370605e75eb5b32777.png
958035e75eb65d5e6d.png
hanzhen654 发表于 2020-3-22 19:52 | 显示全部楼层
有效果图吗?看一下,
触觉的爱 发表于 2020-3-23 19:08 | 显示全部楼层
直接上效果图才亮眼
小明的同学 发表于 2020-3-23 21:20 | 显示全部楼层
没效果图?
keaibukelian 发表于 2020-4-7 13:26 | 显示全部楼层
非常感谢楼主分享
labasi 发表于 2020-4-7 13:27 | 显示全部楼层
非常感谢楼主分享
paotangsan 发表于 2020-4-7 13:27 | 显示全部楼层
非常感谢楼主分享
renzheshengui 发表于 2020-4-7 13:27 | 显示全部楼层
非常感谢楼主分享
wakayi 发表于 2020-4-7 13:27 | 显示全部楼层
非常感谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

196

帖子

0

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