转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38023431

通过前面的介绍我们知道。声音信号要通过AD转换,变成我们可以处理的数字信号,然后再交给FFT进行处理。

一.ADC转换

1.设置引脚

void GPIO_Init()                       // GPIO口的初始化
{P1M1  = B(00000011);                //设置P1口模式P1M0  = B(00000000);                  //设置P1口模式 仅仅有1.0和1.1为开漏,用于ADP1    = B(00000011);P1ASF = B(00000011);               //将P10,P11的IO设置为模拟输入功能。
}

2.ADC初始化

void ADC_Init()                         // 集成ADC的初始化(官方函数)
{ADC_RES = 0;                          //Clear previous resultADC_CONTR = ADC_POWER | ADC_SPEEDLL;  //ADC_SPEEDLL,每次转换须要420个时钟周期。420*0.04=16.8usDelay(2);                            //ADC power-on and delay
}

3.ADC转换

uchar GetADCResult(uchar ch)         // 进行AD转换(官方函数)
{ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;_nop_();                        //Must wait before inquiry_nop_();_nop_();_nop_();while (!(ADC_CONTR & ADC_FLAG));//Wait complete flagADC_CONTR &= ~ADC_FLAG;         //Close ADCreturn ADC_RES;                 //Return ADC result
}

二.FFT

FFT(Fast Fourier Transformation),即为高速傅氏变换。是离散傅氏变换的高速算法,它是依据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。

1.实现的根本:时域到频域

从这张图我们清晰的看到,左面的就是我们输入的信号,右面就是输出到点阵上面的信号。中间的转换过程由FFT实现。

2.算法实现

float code iw[32]=
{1.000,0.000,  /* 0.9952,-0.0980,*/   0.9808,-0.1951,  /*0.9569,-0.2903,*/  0.9239,-0.3827,  /*0.8819,-0.4714,*/  0.8315,-0.5556,/*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, */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,     /*-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, */-0.9239,-0.3827, /*   -0.9569,-0.2903,*/ -0.9808,-0.1951,  /*-0.9952,-0.0980    */
};   //偶数cos值 奇数sin值。       复常数码表 。

历经几个小时最终尼玛明确了。。原因 就是计算器还要调弧度和角度模式。

好了这这就是将1的sin和cos值依照角度平均分然后得到的sin和cos值即为上表。

目的是为了节约计算量。

第二个cos(π/32)记住计算器弧度和角度的设置 void ee(struct compx b1,uchar b2) //复数乘法 { temp.real=b1.real*iw[2*b2]-b1.imag*iw[2*b2+1]; temp.imag=b1.real*iw[2*b2+1]+b1.imag*iw[2*b2]; } uint mypow(uchar nbottom,uchar ntop) //乘方函数 { uint result=1; uchar t; for(t=0;t<ntop;t++)result*=nbottom; return result; } void fft(struct compx *xin,uchar data N) //高速傅立叶变换 { uchar data fftnum,i,j,k,l,m,n,disbuff,dispos,dissec; data struct compx t; fftnum=N; //傅立叶变换点数 for(m=1;(fftnum=fftnum/2)!=1;m++);//求得M的值 N=64 所以M=6 也就是分解为6级 for(k=0;k<=N-1;k++) //码位倒置 { n=k; j=0; for(i=m;i>0;i--) //倒置 比如001变为100 { j=j+((n%2)<<(i-1)); //二进制除二取余的反过程。就得到了倒置十进制数 n=n/2; //倒置过程中处位和末位都不变即0和63都不变。此例中1相应32 } if(k<j){t=xin[1+j];xin[1+j]=xin[1+k];xin[1+k]=t;}//交换数据 , 由于从0開始。所以进行加1处理。比如xin[2]和xin[33]交换。即1与32交换 } //到此FFT码位倒置结束 for(l=1;l<=m;l++) //FFT运算 l为级数 { disbuff=mypow(2,l); //求得碟间距离 求得碟间距离 (乘方函数 pow(X,y)就是计算X的Y次方) dispos=disbuff/2; //求得碟形两点之间的距离 for(j=1;j<=dispos;j++) //每一个蝶形群运算的次数 当N等于64时每次进行蝶形运算次数l=1时为1*32 l=2时为 2* 16 总之每次进行蝶形运算数不变都为N/2 仅仅只是相乘的两个数的间隔每级都加大 for(i=j;i<N;i=i+disbuff) //遍历M级全部的碟形 { dissec=i+dispos; //求得第二点的位置 ee(xin[dissec],(uint)(j-1)*(uint)N/disbuff);//复数乘法 t=temp; xin[dissec].real=xin[i].real-t.real; xin[dissec].imag=xin[i].imag-t.imag; xin[i].real=xin[i].real+t.real; xin[i].imag=xin[i].imag+t.imag; } } }

尽管凝视的比較完好,但我还须要进行几点说明:

a.FFT的产生

我们想通过单片机处理信号,信号必须是离散的和有限长度的数据才干被处理。所以我们仅仅能用DFT(离散傅里叶变换),DFT尽管可以处理信号,可是运算比較复杂,所以依据它的一些性质提出了FFT。

b.蝶形算法

在这里希望读者感兴趣的话找一本信号分析与处理的数来对比着分析,我写的凝视比較完好,相信你可以理解,当中的凝视部分。是我在用64点採样的时候做的,32点的原理是一样的。我在这里简单说下思路。

1.码位倒置

2.基32的FFT蝶形算法

c.採样点数的选取

这里网上大家通常看到的用单片机一般都採用64个点的。高级一点的STM32的程序用128个点的,而我选择了32个点。

这里事实上并没有明白要求大家採样用多少个点。

可是通常都是2的N次方,因为计算会方便。再来说说我做的,因为因为FFT结果的对称性,通常仅仅使用前N/2个採样点的结果。

所以我用32个点採样,刚刚好能满足。

採样频率我选择的是1KHZ,因为我一共同拥有16列所以,每一个列的频率事实上已经固定了。所以加大採样的点数仅仅是添加了计算而已。还有就是添加了我这16个点的选择机会。

我測试过採用64个点,发现会有闪屏的现象,就是偶尔你会发现点阵上没有灯亮和刚开机的时候一样,后来分析原因就是运算的时间过长。使得画面无法连续显示。

d.FFT的採样时间

理论的情况:依据香农採样定力我们知道:为了不失真地恢复模拟信号,採样频率应该不小于模拟信号频谱中最高频率的2倍。人耳理论能听到声音范围20HZ---20kHZ,我选择了500us定时,也就是2kHZ的採样频率。可是非常遗憾结果是失真的,可是失真的结果是能够接受的。

真实的情况:我曾最后拿着音频频谱和分析音频的软件相对照,发现你採样时2KHZ还是4KHZ结果差点儿是几乎相同的。我试着再次减小频率,发现还是几乎相同。

最后分析整个程序我才发现当中的问题。那就是因为单片机性能还是有限处理这样的FFT计算还是有些费力。所以造成的运算的时间比較长。这就使得不管你如何调节定时器。仅仅要超过了某个值。其结果都是一样的,这也是这个设计的一个缺陷之处。

void Timer0() interrupt 1            //我用的24M晶振,ADC採样频率即为採样周期  2KH     因为运行语句过长所以即使频率加大也没有仍会失真
{   TH0 = 0xd1;TL0 = 0x20;      fft_sign = 1;}   

e.显示的BUG

显示的时候小伙伴可能会看到第一列的灯始终是亮着的,由于这个是结果产生的直流分量,当时调程序的时候。由于C语言能力有限,没可以弄掉,有点遗憾。

转载于:https://www.cnblogs.com/llguanli/p/6723203.html

LED音乐频谱之输入数据处理相关推荐

  1. LED音乐频谱之输出数据处理

    转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38023539 一.PWM调节 1.初始化 void DACInit() {CC ...

  2. LED音乐频谱之概述

    点击打开链接       转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/37929733 这个LED音乐频谱是我在学51单片机的 ...

  3. LED音乐频谱之点阵

    转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/37967455 一.硬件 这里的LED选择直插的雾面LED,亮度可以还不失美观. ...

  4. 毕业设计| STM32F103全彩FFT音乐频谱+LED年历闹钟显示

    大家好,我是写代码的篮球球痴,今天在后台看到有人想找毕业设计的点子. 然后我今天刚好看到一个不错的点子,给大家分享 看今天分享的毕设是来自点-凡自制的FTF音乐频谱制作,先来看展示效果: --视频出处 ...

  5. 51DIY音乐频谱显示

    以前,每当看到家里的音箱功放上的几排小灯,随着播放的音乐如波浪般跳跃,或者在电脑上打开千千静听这个音乐播放软件时,看到那动感的频谱跟随音乐节奏优美的舞动着时,不禁思绪万千,要是自己某天能亲手用普通的单 ...

  6. Python 提取音乐频谱并可视化

    你有没有经常好奇一些音乐软件的频谱特效是怎么做的,为什么做的这么好看?有没有想试试自己提取音乐频谱并可视化展现出来?今天,咱就结合上次的音乐剪辑操作: Python 剪辑音乐就是这么简单 来可视化下面 ...

  7. 音乐频谱显示小玩具——FFT在STM32中的实现与应用

    0.前言 音乐频谱显示说白了就是"儿童版"频谱仪.笔者平时比较喜欢听音乐,闲暇之余听音乐的时候如果有个频谱显示的小玩具在旁边跳来跳去的也挺有意思的,所以笔者去万能的某宝上搜索了一下 ...

  8. python音频频谱_Python 提取音乐频谱并可视化

    你有没有经常好奇一些音乐软件的频谱特效是怎么做的,为什么做的这么好看?有没有想试试自己提取音乐频谱并可视化展现出来?今天,咱就结合上次的音乐剪辑操作: 来可视化下面这首歌曲的频谱: 1.准备工作 开始 ...

  9. html音乐跳动的线,利用CSS3制作跳动音乐频谱跳动效果

    [摘要] CSS3新增很多实用的属性,特别是可以实现动画效果的animation属性,本文通过使用CSS3来实现一个类似于音乐频谱跳动效果. 在一个网站上看到"直播中"的提示标题, ...

最新文章

  1. MySQL参数优化辅助工具_mysqltuner.pl
  2. ElasticSearch聚合分析API——非常详细,如果要全面了解的话,最好看这个
  3. ubuntu创建文件夹快捷方式命令
  4. linux snap安装redis-desktop-manager
  5. leetcode 561. 数组拆分 I(Java版)
  6. Nexys4 DDR + OV7670 摄像头实时监控系统
  7. 将jOOQ与Spring结合使用:配置
  8. python输入日期时间转换格式_python如何格式化日期?
  9. onvif 客户端发现
  10. 杨辉三角(完整代码)
  11. 用PostgreSQL运行文件中的SQL程序
  12. 检测c/c++中内存泄露
  13. 关于linux安装openoffice无法启动
  14. docker swarm集群
  15. 标准差 php,标准偏差怎么计算
  16. 如何升级maven版本
  17. 一键制作三维真实地形DEM
  18. 嵌入式linux开发04-roottfs移植
  19. 传奇3服务器配置文件,服务器技术交流_GowLom2战神引擎GameServer配置文件说明_-921根据地_只做有质量的游戏 - Powered by Discuz!...
  20. java流程图中平行四边形代表什么,一文搞懂

热门文章

  1. Android手机修改hosts文件
  2. JDK环境变量配置-win10
  3. 由 serverAdd.sin_addr.s_addr 引发的思考
  4. JSOUP爬取4K高清壁纸
  5. JS修改this指向:call、apply和bind函数
  6. 就业难,如何“解救”2022年的应届毕业生......
  7. 跨考西电计算机科学与技术研究生经验贴,西安交通大学912计算机133分经验分享...
  8. 妥妥的去面试之Android基础(五)
  9. html课堂笔记2.24
  10. BP神经网络隐藏层单元数的选择--(1)