12864液晶驅動的頻譜顯示
電路原理圖如下:
51hei.png (33.54 KB, 下載次數: 42)
下載附件
2022-5-2 17:20 上傳
單片機源程序如下:
- #include<math.h>
- #include"stc12c5a60s2.h"
- #include"LCD12864.h"
- #define uint unsigned int
- #define uchar unsigned char
- struct compx //定義復數結構體
- {
- float real;
- float imag;
- };
- xdata struct compx s[ 64 ]; //FFT數據緩存放在XDATA空間
- struct compx EE(struct compx,struct compx); //復數乘法函數的聲明
- void FFT(struct compx xin[],int N); //FFT函數的聲明
- struct compx EE(struct compx a1,struct compx b2) //復數乘法
- {
- 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函數*/
- 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為倒序中相應位置的權值
- 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); //旋轉因子
- w.imag=-sin(pi/lei);
-
- for(j=1;j<=lei;j++) //控制蝶形運算的級數
- {
- for(i=j-1;i<N;i=i+le) //控制每級蝶形運算的次數
- {
- 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 showbar()
- {
- xdata unsigned char dis_data[31][16]; //用于顯示的數據
- unsigned char i,j,high;
- unsigned char dis_rdata[16];
- for(i=0;i<16;i++) //讀取FFT轉換數據
- {
- 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;
- }
- /**************************************************************/
- /*****************寫入下屏,i:0~16,表示16列**************/
- /***************************high:表示列的高度*********/
- for (i=0;i<=32;i++) //在顯示下屏顯存必須清0,后面有操作是或運算
- {
- for (j=0;j<16;j++)
- {
- dis_data[i][j]=0;
- }
- }
- for(i=0;i<16;i++)
- {
- high=dis_rdata[i];
- if(high>62)high=62; //12864的高度只有64,判斷高于64時,為62***/
- if(high>31) //下屏和下屏的高度各處為32,大于32時,多于的在上屏顯示
- {
- for(j=0;j<31;j++)//高度大于32時,下屏柱體全充滿,多于的在上屏顯示
- {
- dis_data[j][i]|=0xfe; // 或的方法是數據結合12864的顯示特性進行的算法
- } //0xfe使每條柱體之間有一條線的間隔
- }
- else //下屏和下屏的高度各處為32,小于32個,在下屏顯示
- {
- for(j=31-high;j<31;j++)
- {
- dis_data[j][i]|=0xfe; // 或的方法是數據結合12864的顯示特性進行的算法
- }
- }
- }
- for(i=0;i<=31;i++)//寫入下屏圖形數據時采用逐行掃描的方式
- {
- write_com(0x80|i); //寫入x和y的地址
- write_com(0x88|0);
- for(j=0;j<16;j++)write_data(dis_data[i][j]); //寫入數據
- }
- /**************************************************************/
- /*****************寫入上屏,i:0~16,表示16列**************/
- /***************************high:表示列的高度*********/
- for (i=0;i<=32;i++) //后面在上屏顯示,顯存必須清0,后面有操作或運算
- {
- for (j=0;j<16;j++)
- {
- dis_data[i][j]=0;
- }
- }
- for(i=0;i<16;i++)
- {
- high=dis_rdata[i];
- if(high>62)high=62;
- if(high>31)
- {
- for(j=64-high;j<=31;j++)
- {
- dis_data[j][i]|=0xfe; // 或的方法是數據結合12864的顯示特性進行的算法
- }
- }
- else
- {
- for(j=64-high;j<=31;j++)
- {
- dis_data[j][i]|=0x00; // 或的方法是數據結合12864的顯示特性進行的算法
- }
- }
- }
- for(i=0;i<=31;i++)//寫入圖形數據時采用逐行掃描的方式
- {
- write_com(0x80|i);
- write_com(0x90|0);
- for(j=0;j<16;j++)write_data(dis_data[i][j]);
- }
-
- }
- /*主函數*/
- void main()
- {
- int N=64,i; //變量初始化,64點FFT運算
- float offset;
- lcd_init(); //12864
- P1ASF=0x01; //P10口做AD 使用
- P1M0 = 0x01; //0000,0001用于A/D轉換的P1.x口,先設為開漏
- P1M1 = 0x01; //0000,0001 P1.0先設為開漏。斷開內部上拉電阻
- ADC_CONTR=0xC8; //40.96K采樣率
- while(!(ADC_CONTR&0x10));
- offset=((float)ADC_RES*4+(float)(ADC_RESL%0x04)); //AD結果高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)/4;//((((int)ADC_DATA-128)/2))*4;
- s[i].imag=0;
- }
- FFT(s,N); //調用FFT函數進行變換
- showbar(); //顯示頻譜
- }
- }
復制代碼
51hei.png (6.49 KB, 下載次數: 41)
下載附件
2022-5-2 17:20 上傳
Keil5程序51hei下載:
12864.rar
(168.18 KB, 下載次數: 140)
2019-5-10 14:00 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|