6x16音乐频谱(源代码 原理图)
#include "STC12C5A.h"
#include
#include
#include "DS1302.h"
#include "Led.h"
#define uchar unsigned char
#define uint unsigned int
#define BinToHex(n) (((n>>21)&0x80)|((n>>18)&0x40)|((n>>15)&0x20)|((n>>12)&0x10)|((n>>9)& 0x08)|((n>>6)&0x04)|((n>>3)&0x02)|((n)&0x01))
#define B(n) BinToHex(0x##n##l) // 8位2进制宏
uchar code ColScan_2[16] = {0x17,0x13,0x15,0x11,0x16,0x12,0x14,0x10,
0x27,0x23,0x25,0x21,0x26,0x22,0x24,0x20}; // 74hc138 进行列扫描
float code iw[64]=
{
1.000,0,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
};
uint data LEDBuf[16];
uint idata refreshflag[16];
uchar fft_sign = 0; // 进行fft变换标志位
struct compx
{
float real;
float imag;
};
struct compx dd[65]; // FFT数据
data struct compx temp;
void delay500ms(void)
{
unsigned char a,b,c,n;
for(c=218;c>0;c--)
for(b=79;b>0;b--)
for(a=238;a>0;a--);
for(n=4;n>0;n--);
}
void Delay(uint n)
{
uint x;
while (n--)
{
x = 5000;
while (x--);
}
}
void GPIO_Init() // GPIO口的初始化
{
P1M1 = B(00000011);
P1M0 = B(00000000);
P1 = B(00000011);
P1ASF = B(00000011);
}
void Interrupt_Init(void) // 单片机中断初始化
{
TMOD = 0x01; // 高4位控制T/C1
EA = 1; // 开总中断
TH0 = 0x00; // 16位计数寄存器T1高8位
TL0 = 0x00; // 16位计数寄存器T1低8位
ET0 = 1; // T/C1中断开
TR0 = 1; // T/C1启动
}
void ADC_Init() // 集成ADC的初始化(官方函数)
{
ADC_RES = 0; //Clear previous result
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
Delay(2); //ADC power-on and delay
}
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 flag
ADC_CONTR &= ~ADC_FLAG; //Close ADC
return ADC_RES; //Return ADC result
}
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
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的值
for(k=0;k<=N-1;k++) //码位倒置
{
n=k;
j=0;
for(i=m;i>0;i--) //倒置
{
j=j+((n%2)<
n=n/2;
}
if(k
}
for(l=1;l<=m;l++) //FFT运算
{
disbuff=mypow(2,l); //求得碟间距离
dispos=disbuff/2; //求得碟形两点之间的距离
for(j=1;j<=dispos;j++)
for(i=j;i
{
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;
}
}
}
void processfft(uchar num)
{
uchar pt;
uint tmp;
for(pt=1;pt<65;pt++)
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』