亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
使用0.96OLED與STC單片機的音樂頻譜程序
[打印本頁]
作者:
紅石渣工作室
時間:
2019-6-23 13:42
標題:
使用0.96OLED與STC單片機的音樂頻譜程序
自己寫的一個項目,基于FFT算法實現(xiàn)的音樂頻譜,利用OLED實現(xiàn)顯示,需要在32M晶振運行
單片機源程序如下:
#include"OLED.H"
sbit sb0=P3^6;//定義按鈕位置
sbit sb1=P3^5;
idata uchar fft_shuzu[2][32];
uint s_time;
struct compx //定義復(fù)數(shù)結(jié)構(gòu)體
{
float real;
float imag;
};
xdata struct compx s[ 64 ]; //FFT數(shù)據(jù)緩存放在XDATA空間
struct compx EE(struct compx,struct compx); //復(fù)數(shù)乘法函數(shù)的聲明
void FFT(struct compx xin[],int N); //FFT函數(shù)的聲明
struct compx EE(struct compx a1,struct compx b2) //復(fù)數(shù)乘法
{
struct compx b3;
b3.real=a1.real*b2.real-a1.imag*b2.imag;
b3.imag=a1.real*b2.imag+a1.imag*b2.real;
return(b3);
}
/*FFT函數(shù)*/
void FFT(struct compx xin[],int N)
{
int f,m,nv2,nm1,i,k,j=1,l;
struct compx v,w,t;
nv2=N/2;
f=N;
for(m=1;(f=f/2)!=1;m++){;}
nm1=N-1;
for(i=0;i<nm1;i++) //倒序操作
{
if(i<j)
{
t=xin[j];
xin[j]=xin[i];
xin[i]=t;
}
k=nv2; //k為倒序中相應(yīng)位置的權(quán)值
while(k<j)
{
j=j-k;
k=k/2;
}
j=j+k;
}
{
int le,lei,ip;
float pi;
for(l=1;l<=m;l++)
{
le=pow(2,l); //乘方
lei=le/2;
pi=3.14159265;
v.real=1.0;
v.imag=0.0;
w.real=cos(pi/lei); //旋轉(zhuǎn)因子
w.imag=-sin(pi/lei);
for(j=1;j<=lei;j++) //控制蝶形運算的級數(shù)
{
for(i=j-1;i<N;i=i+le) //控制每級蝶形運算的次數(shù)
{
ip=i+lei;
t=EE(xin[ ip ],v);
xin[ ip ].real=xin[ i ].real-t.real; //蝶形計算
xin[ ip ].imag=xin[ i ].imag-t.imag;
xin[ i ].real=xin[ i ].real+t.real;
xin[ i ].imag=xin[ i ].imag+t.imag;
}
v=EE(v,w);
}
}
}
}
void showbar0()//延時跳帽函數(shù)
{
unsigned char i,j,x,p,high,tigh,temp,itemp;
xdata unsigned char dis_rdata[16];
for(i=0;i<16;i++) //讀取FFT轉(zhuǎn)換數(shù)據(jù)
{
float t0=0;
t0=sqrt(pow((s[i ].real+s[i+1].real),2)+pow((s[i ].imag+s[i+1].imag),2))/2;
dis_rdata[i]=(unsigned char)t0;
}
// OLED_Display_On();
for(i=0;i<16;i++)//16個條形柱控制
{
itemp=high=0;
itemp=high=dis_rdata[i];//對處理變量賦值
// high=high/1;
for(x=0;x<8;x++)//清空當前條形柱空間
{
OLED_Set_Pos(i*8,7-x);
temp=0x00;
for(j=0;j<8;j++)
{
OLED_WR_Byte(temp,1);
}
}
if(high>64)high=64;//溢出值限制
if(fft_shuzu[0][i]<=high)//檢測當前大小
{
fft_shuzu[0][i]=high;//大于賦值當前頻譜帽為此值
fft_shuzu[1][i]=10;//重新設(shè)置當前延時
}
fft_shuzu[1][i]--;//當前延時自減
if(fft_shuzu[1][i]==0)//如果當前延時為0
{
fft_shuzu[0][i]=high;//強度等于當前大小
}
p=high/8; //掃描圖形生成
tigh=high%8;
for(x=0;x<p;x++)//填滿單元區(qū)域
{
OLED_Set_Pos(i*8,7-x);
temp=0xff;
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
p=fft_shuzu[0][i]/8;//生成延時帽所在位置函數(shù)
tigh=fft_shuzu[0][i]%8;
if((itemp/8)==p)//如果與所在位置重合
{
OLED_Set_Pos(i*8,7-p);//到達所在位置
temp=0x80>>tigh;//生成延時帽
temp=temp|~0xff>>(high%8);//合并當前位置
for(j=0;j<7;j++)//發(fā)送屏幕
{
OLED_WR_Byte(temp,1);
}
}
else//如果不重合
{
OLED_Set_Pos(i*8,7-p);//到達生成位置
temp=0x80>>tigh;//生成延時帽
for(j=0;j<7;j++)//發(fā)送屏幕
{
OLED_WR_Byte(temp,1);
}
OLED_Set_Pos(i*8,7-(high/8));//到達非滿數(shù)單元
temp=~0xff>>(itemp%8);//生成條形柱
for(j=0;j<7;j++)//發(fā)送
{
OLED_WR_Byte(temp,1);
}
}
}
}
/*----以下生成函數(shù)原理差不多----*/
void showbar1()//條形柱函數(shù)
{
unsigned char i,j,x,p,high,tigh,temp;
xdata unsigned char dis_rdata[16];
for(i=0;i<16;i++) //讀取FFT轉(zhuǎn)換數(shù)據(jù)
{
float t0=0;
t0=sqrt(pow((s[i ].real+s[i+1].real),2)+pow((s[i ].imag+s[i+1].imag),2))/2;
dis_rdata[i]=(unsigned char)t0;
}
// OLED_Display_On();
for(i=0;i<16;i++)
{
high=0;
high=dis_rdata[i];
// high=high/1;
for(x=0;x<8;x++)
{
OLED_Set_Pos(i*8,7-x);
temp=0x00;
for(j=0;j<8;j++)
{
OLED_WR_Byte(temp,1);
}
}
if(high>64)high=64;
if(high==0)high=1;
p=high/8;
tigh=high%8;
for(x=0;x<p;x++)
{
OLED_Set_Pos(i*8,7-x);
temp=0xff;
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
OLED_Set_Pos(i*8,7-(high/8));
temp=~0xff>>(high%8);
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
}
void showbar2()//等號指示函數(shù)
{
unsigned char i,j,x,p,high,tigh,temp,itemp;
xdata unsigned char dis_rdata[16];
for(i=0;i<16;i++) //讀取FFT轉(zhuǎn)換數(shù)據(jù)
{
float t0=0;
t0=sqrt(pow((s[i ].real+s[i+1].real),2)+pow((s[i ].imag+s[i+1].imag),2))/2;
dis_rdata[i]=(unsigned char)t0;
}
// OLED_Display_On();
for(i=0;i<16;i++)
{
itemp=high=0;
itemp=high=dis_rdata[i];
// high=high/1;
for(x=0;x<8;x++)
{
OLED_Set_Pos(i*8,7-x);
temp=0x00;
for(j=0;j<8;j++)
{
OLED_WR_Byte(temp,1);
}
}
if(high>64)high=64;
p=high/8;
tigh=high%8;
if(p==0)
{
p=1;
temp=0x80;
}
else temp=0x88;
for(x=0;x<p;x++)
{
OLED_Set_Pos(i*8,7-x);
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
}
}
void showbar3()//延時跳帽函數(shù)取反
{
unsigned char i,j,x,p,high,tigh,temp,itemp;
xdata unsigned char dis_rdata[16];
for(i=0;i<16;i++) //讀取FFT轉(zhuǎn)換數(shù)據(jù)
{
float t0=0;
t0=sqrt(pow((s[i ].real+s[i+1].real),2)+pow((s[i ].imag+s[i+1].imag),2))/2;
dis_rdata[i]=(unsigned char)t0;
}
// OLED_Display_On();
for(i=0;i<16;i++)
{
itemp=high=0;
itemp=high=dis_rdata[i];
// high=high/1;
for(x=0;x<8;x++)
{
OLED_Set_Pos(i*8,7-x);
temp=0xFF;
for(j=0;j<8;j++)
{
OLED_WR_Byte(temp,1);
}
}
if(high>64)high=64;
if(fft_shuzu[0][i]<=high)
{
fft_shuzu[0][i]=high;
fft_shuzu[1][i]=10;
}
fft_shuzu[1][i]--;
if(fft_shuzu[1][i]==0)
{
fft_shuzu[0][i]=high;
}
p=high/8;
tigh=high%8;
for(x=0;x<p;x++)
{
OLED_Set_Pos(i*8,7-x);
temp=0x00;
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
p=fft_shuzu[0][i]/8;
tigh=fft_shuzu[0][i]%8;
if((itemp/8)==p)
{
OLED_Set_Pos(i*8,7-p);
temp=~0x80>>tigh;
temp=temp|0xff>>(high%8);
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
else
{
OLED_Set_Pos(i*8,7-p);
temp=~0x80>>tigh;
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
OLED_Set_Pos(i*8,7-(high/8));
temp=0xff>>(itemp%8);
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
}
}
void showbar4()//條形柱取反函數(shù)
{
unsigned char i,j,x,p,high,tigh,temp;
xdata unsigned char dis_rdata[16];
for(i=0;i<16;i++) //讀取FFT轉(zhuǎn)換數(shù)據(jù)
{
float t0=0;
t0=sqrt(pow((s[i ].real+s[i+1].real),2)+pow((s[i ].imag+s[i+1].imag),2))/2;
dis_rdata[i]=(unsigned char)t0;
}
// OLED_Display_On();
for(i=0;i<16;i++)
{
high=0;
high=dis_rdata[i];
// high=high/1;
for(x=0;x<8;x++)
{
OLED_Set_Pos(i*8,7-x);
temp=0xff;
for(j=0;j<8;j++)
{
OLED_WR_Byte(temp,1);
}
}
if(high>64)high=64;
if(high==0)high=1;
p=high/8;
tigh=high%8;
for(x=0;x<p;x++)
{
OLED_Set_Pos(i*8,7-x);
temp=0x00;
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
OLED_Set_Pos(i*8,7-(high/8));
temp=0xff>>(high%8);
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
}
void showbar5()//等號指示函數(shù)
{
unsigned char i,j,x,p,high,tigh,temp,itemp;
xdata unsigned char dis_rdata[16];
for(i=0;i<16;i++) //讀取FFT轉(zhuǎn)換數(shù)據(jù)
{
float t0=0;
t0=sqrt(pow((s[i ].real+s[i+1].real),2)+pow((s[i ].imag+s[i+1].imag),2))/2;
dis_rdata[i]=(unsigned char)t0;
}
// OLED_Display_On();
for(i=0;i<16;i++)
{
itemp=high=0;
itemp=high=dis_rdata[i];
// high=high/1;
for(x=0;x<8;x++)
{
OLED_Set_Pos(i*8,7-x);
temp=0xff;
for(j=0;j<8;j++)
{
OLED_WR_Byte(temp,1);
}
}
if(high>64)high=64;
p=high/8;
tigh=high%8;
if(p==0)
{
p=1;
temp=~0x80;
}
else temp=~0x88;
for(x=0;x<p;x++)
{
OLED_Set_Pos(i*8,7-x);
for(j=0;j<7;j++)
{
OLED_WR_Byte(temp,1);
}
}
}
}
/*主函數(shù)*/
void main()
{
int N=64,i,k; //變量初始化,64點FFT運算
float offset;
s_time=0;
TMOD=0X01; //定時器開到模式1
TH0=(65535-10000)/256; //設(shè)置延時時間
TL0=(65535-10000)%256;
TR0=1; //啟動定時器0
ET0=1; //開啟定時器0中斷
EA=1; //開啟中斷
oled_init(); //OLED
OLED_Clear();
P1ASF=0x01; //P10口做AD 使用
P1M0 = 0x01; //0000,0001用于A/D轉(zhuǎn)換的P1.x口,先設(shè)為開漏
P1M1 = 0x01; //0000,0001 P1.0先設(shè)為開漏。斷開內(nèi)部上拉電阻
ADC_CONTR=0xC8; //40.96K采樣率
while(!(ADC_CONTR&0x10));
offset=((float)ADC_RES*4+(float)(ADC_RESL%0x04)); //AD結(jié)果高8位左移2位,低2位不變,然后相加
while(1)
{ if(P3==(P3&0xFE))IAP_CONTR=0x60;
for(i=0;i<N;i++) //采集音頻信號
{
ADC_CONTR=0xC8; //40.96K采樣率
while(!(ADC_CONTR&0x10));
s[i].real=((float)ADC_RES*4+(float)(ADC_RESL%0x04)-offset);//((((int)ADC_DATA-128)/2))*4;
s[i].imag=0;
}
FFT(s,N); //調(diào)用FFT函數(shù)進行變換
EA=0;
if(sb0==0) //模式調(diào)節(jié)按鈕控制
{
delay(100);
if(sb0==0)
{
while(!sb0);
delay(100);
k+=1;
if(k==6)k=0;
}
}
if(sb1==0) //延時調(diào)節(jié)按鈕控制
{
delay(100);
if(sb1==0)
{
while(!sb1);
delay(100);
s_time+=100;
if(s_time==1100)s_time=0;
}
}
switch(k) //顯示頻譜
{
case 0:showbar0();break; //延時跳帽函數(shù)
case 1:showbar1();break; //條形柱函數(shù)
case 2:showbar2();break; //等號條函數(shù)
case 3:showbar3();break; //延時跳帽函數(shù)取反
case 4:showbar4();break; //條形柱函數(shù)取反
case 5:showbar5();break; //等號條函數(shù)取反
}
EA=1;
delay(s_time);//顯示延時函數(shù)
}
}
void yp_l()interrupt 1
{
TH0=(65535-10000)/256; //設(shè)置延時時間
TL0=(65535-10000)%256;
}
復(fù)制代碼
所有程序51hei提供下載:
OLED FFT.rar
(72.2 KB, 下載次數(shù): 152)
2019-6-23 13:41 上傳
點擊文件名下載附件
源碼
下載積分: 黑幣 -5
作者:
TOMMY_liu
時間:
2019-10-30 22:14
有原理圖嗎
作者:
qjy822
時間:
2021-9-20 14:31
感謝分享,正在學(xué)習(xí)這方面的知識!
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1