音乐频谱分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
程序如下:
#include <iom16v.h>
#include <macros.h>
#include<math.h>
#define N 128
#define PI 3.141592653589
#define uchar unsigned char
#define uint unsigned int
typedef struct
{
int real;
int img;
}complex;
void initw(); //初始化旋转因子void bitReverse(); //比特反转void FFT();
complex x[N];
uchar vis[N];
void delayms(uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<3;j++);
}
}
void FFT()
{
int i,j,k,t,P,B,m;
complex up,down,product;
for (i=0;i<7;i++)
{
B=1<<i;
for (j=0;j<B;j++)
{
t=1<<(6-i);
P=t*j;
for (k=j;k<N;k=k+2*B)
{
complex product;
product.real=x[k+B].real*cos(2*PI*P/N)+x[k+B].img*sin(2*PI*P/N); product.img=x[k+B].real*(-1)* sin(2*PI*P/N)+x[k+B].img*cos(2*PI*P/N); x[k+B].real=x[k].real-product.real;
x[k+B].img=x[k].img-product.img;
x[k].real=x[k].real+product.real;
x[k].img=x[k].img+product.img;
}
}
}
}
void initw() //初始化旋转因子
{
int i;
for (i=0;i<N;i++)
vis[i]=0;
}
void bitReverse() //比特反转{
int i,j=0;
int k=0;
int q=0;
complex tmp3;
for (i=0;i<N;i++)
{
int tmp=i,tmp2=0,j;
for(j=0;j<7;j++)
tmp2+=((tmp>>j)&1)*(1<<(6-j)); if(vis[i]==0)
{
tmp3=x[i];
x[i]=x[tmp2];
x[tmp2]=tmp3;
vis[i]=1;
vis[tmp2]=1;
}
}
}
void main()
{
uchar ii,y;
float tmp;
for (ii=0;ii<20;ii++)
{
x[ii].real=3;
x[ii].img=0;
}
for (ii=20;ii<128;ii++) {
x[ii].real=0;
x[ii].img=0;
}
initw();
bitReverse();
FFT();
while(1);
}
/showpic.html -
blogid=61aa4e9d0100sjy6&url=/orignal/61aa4e9dxa99056ccb1e7
上图是8点FFT运算,按照上图的流程所示,FFT运算主要有两步,一步是比特反转,就是右边不是按照0、1、2、3……这样顺序进行计算的,而左边是的,两边的关系就是进行一个比特反转。可以看到右边0对应二进制为000,左边对应二进制为000,右边1二进制001,左边4对应二进制100,依次下去,可以清楚看到,对于8位FFT运算,对应二进制有三位,而左右两边的关系恰巧是按照中间位进行了个反转。
FFT运算第二步就是乘以旋转因子,注意的是这里是复数运算,虚部和实部都要加入运算。乘以旋转因子后对进行加减运算得到新的值,依次下去得到最终解。
由于单片机内存的限制,因而对于传统的FFT算法,我进行了些改进,原则就是尽量地少使用变量,一个变量可以重复的使用是最理想的了,大家可以在程序中看出。个人意见这是能节省变量最少的了,如果有好的方法,希望可以告诉我下,我的邮箱是albertvictordu@,谢谢!
下面是12864液晶驱动程序的写法:
LCD12864液晶,即像素为128*64的显示液晶。它的每一行横向一共有128个可显示点,每一列纵向有64个,这些“点”其实也都是一个个发光二极管。它可以在一个16*16的点阵区域上显示一个中文,也可以在一个8*16的点阵区域显示一个非中文字符,一般称为半宽字体。即一个中文字所占显示面积是一个非中文字符的两倍。
关于驱动函数的书写,是液晶显示的基础,整个液晶驱动主要有四个函数组成:
1、写命令函数;
2、写数据函数;
3、读状态函数;
4、读数据函数;