日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]大家知道,如果采用DSP芯片效果那是相當(dāng)好的。但由于項(xiàng)目資金以及時(shí)間不夠等情況,我采用的是ATMEL公司的AVR單片機(jī),這款單片機(jī)的FLASH存儲(chǔ)和內(nèi)存比51單片機(jī)犀利得多。

本次創(chuàng)新基金我是要做一個(gè)簡(jiǎn)易的頻譜儀,核心就是要進(jìn)行一個(gè)FFT運(yùn)算。大家知道,如果采用DSP芯片效果那是相當(dāng)好的。但由于項(xiàng)目資金以及時(shí)間不夠等情況,我采用的是ATMEL公司的AVR單片機(jī),這款單片機(jī)的FLASH存儲(chǔ)和內(nèi)存比51單片機(jī)犀利得多。

由于采用的是12864液晶,也就是一個(gè)橫128點(diǎn)豎64點(diǎn)的一個(gè)點(diǎn)陣,因而采用128點(diǎn)FFT運(yùn)算已然夠了,因?yàn)榧词沟玫皆俣嗟臄?shù)據(jù)也無(wú)法在液晶上可視化顯示出來(lái)。本文是基于128點(diǎn)FFT運(yùn)算。

程序如下:

#include

#include

#include

#define N 128

#define PI 3.141592653589

#define uchar unsigned char

#define uint unsigned int

typedef struct

{

int real;

int img;

}complex;

void initw(); //初始化旋轉(zhuǎn)因子

void bitReverse(); //比特反轉(zhuǎn)

void FFT();

complex x[N];

uchar vis[N];

void delayms(uint ms)

{

uint i,j;

for(i=0;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<

for (j=0;j

{

t=1<<(6-i);

P=t*j;

for (k=j;k

{

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() //初始化旋轉(zhuǎn)因子

{

int i;

for (i=0;i

vis[i]=0;

}

void bitReverse() //比特反轉(zhuǎn)

{

int i,j=0;

int k=0;

int q=0;

complex tmp3;

for (i=0;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);

}

上圖是8點(diǎn)FFT運(yùn)算,按照上圖的流程所示,F(xiàn)FT運(yùn)算主要有兩步,一步是比特反轉(zhuǎn),就是右邊不是按照0、1、2、3……這樣順序進(jìn)行計(jì)算的,而左邊是的,兩邊的關(guān)系就是進(jìn)行一個(gè)比特反轉(zhuǎn)。可以看到右邊0對(duì)應(yīng)二進(jìn)制為000,左邊對(duì)應(yīng)二進(jìn)制為000,右邊1二進(jìn)制001,左邊4對(duì)應(yīng)二進(jìn)制100,依次下去,可以清楚看到,對(duì)于8位FFT運(yùn)算,對(duì)應(yīng)二進(jìn)制有三位,而左右兩邊的關(guān)系恰巧是按照中間位進(jìn)行了個(gè)反轉(zhuǎn)。

FFT運(yùn)算第二步就是乘以旋轉(zhuǎn)因子,注意的是這里是復(fù)數(shù)運(yùn)算,虛部和實(shí)部都要加入運(yùn)算。乘以旋轉(zhuǎn)因子后對(duì)進(jìn)行加減運(yùn)算得到新的值,依次下去得到最終解。

由于單片機(jī)內(nèi)存的限制,因而對(duì)于傳統(tǒng)的FFT算法,我進(jìn)行了些改進(jìn),原則就是盡量地少使用變量,一個(gè)變量可以重復(fù)的使用是最理想的了,大家可以在程序中看出。個(gè)人意見(jiàn)這是能節(jié)省變量最少的了,如果有好的方法,希望可以告訴我下,我的郵箱是albertvictordu@139.com,謝謝!

下面是12864液晶驅(qū)動(dòng)程序的寫(xiě)法:

LCD12864液晶,即像素為128*64的顯示液晶。它的每一行橫向一共有128個(gè)可顯示點(diǎn),每一列縱向有64個(gè),這些“點(diǎn)”其實(shí)也都是一個(gè)個(gè)發(fā)光二極管。它可以在一個(gè)16*16的點(diǎn)陣區(qū)域上顯示一個(gè)中文,也可以在一個(gè)8*16的點(diǎn)陣區(qū)域顯示一個(gè)非中文字符,一般稱為半寬字體。即一個(gè)中文字所占顯示面積是一個(gè)非中文字符的兩倍。

關(guān)于驅(qū)動(dòng)函數(shù)的書(shū)寫(xiě),是液晶顯示的基礎(chǔ),整個(gè)液晶驅(qū)動(dòng)主要有四個(gè)函數(shù)組成:

1、寫(xiě)命令函數(shù);

2、寫(xiě)數(shù)據(jù)函數(shù);

3、讀狀態(tài)函數(shù);

4、讀數(shù)據(jù)函數(shù);

這四個(gè)函數(shù)并不是必須全部寫(xiě)的,具體要看你實(shí)現(xiàn)的功能,如果只是單純的顯示漢字和字符,寫(xiě)命令、寫(xiě)數(shù)據(jù)、讀狀態(tài)這三個(gè)函數(shù)就夠了,如過(guò)你還需要進(jìn)行一些繪圖的操作,那讀數(shù)據(jù)函數(shù)也必須書(shū)寫(xiě)。

另外關(guān)于讀狀態(tài)函數(shù),其實(shí)也就是用于判忙操作,原則上每次對(duì)控制器進(jìn)行讀寫(xiě)操作之前,都必須進(jìn)行讀寫(xiě)檢測(cè),由于單片機(jī)的操作速度慢于液晶控制器的反應(yīng)速度,因此可不進(jìn)行讀寫(xiě)檢測(cè),或者只進(jìn)行簡(jiǎn)短的延時(shí)即可。因此,讀狀態(tài)函數(shù)也可以不寫(xiě),只用簡(jiǎn)短的延時(shí)函數(shù)替換即可。

單片機(jī)用于控制LCD的管腳主要為RS、RW和E管腳,分別的功能是RS為0時(shí),對(duì)應(yīng)單片機(jī)訪問(wèn)的是命令寄存器,為1時(shí)對(duì)應(yīng)數(shù)據(jù)寄存器;RW為1時(shí),對(duì)應(yīng)單片機(jī)操作為讀操作,為0時(shí)對(duì)應(yīng)單片機(jī)為寫(xiě)操作;E是使能信號(hào)。

讀操作如下圖所示

寫(xiě)操作如下圖所示

在12864液晶中,開(kāi)發(fā)商將一些基本指令已經(jīng)寫(xiě)入到命令寄存器中,我們調(diào)用該指令就可以完成相應(yīng)的功能。

LCD初始化

初始化操作如下:

1. 芯片上電;

2. 延時(shí)40ms以上;

3. 復(fù)位操作:RST出現(xiàn)一個(gè)上升沿(RST=1;RST=0;RST=1;);

4. 功能設(shè)定;

5. 延時(shí)100us以上;

6. 再次進(jìn)行功能設(shè)定;

7. 延時(shí)37us;

8. 顯示開(kāi)關(guān)控制;

9. 延時(shí)100us以上;

10. 清除顯示;

11. 延時(shí)10ms以上;

12. 進(jìn)入點(diǎn)設(shè)置;

13. 初始化結(jié)束;

LCD液晶屏初始化過(guò)程如圖所示為:

打點(diǎn)函數(shù)

打點(diǎn)函數(shù)是創(chuàng)建GUI的基礎(chǔ),打點(diǎn)函數(shù)的書(shū)寫(xiě)分為以下幾個(gè)步驟:

1. 進(jìn)入擴(kuò)展模式

2. 寫(xiě)入打點(diǎn)地址

3. 讀取該地址的數(shù)據(jù)

4. 修改該地址的數(shù)據(jù)

5. 將修改后的數(shù)據(jù)輸入LCD中

6. 進(jìn)入普通模式

GDRAM地址分布情況,需要注意的是橫縱坐標(biāo)的起始地址都是0x80,還有上下半屏的橫坐標(biāo)是不一樣的,下半屏的橫坐標(biāo)要加上0x08,而縱坐標(biāo)跟對(duì)應(yīng)的上半屏的縱坐標(biāo)是一樣的。GDRAM地址分布圖,如圖所示。

下面的函數(shù)是12864與FFT算法的一個(gè)結(jié)合,里面設(shè)置了一個(gè)門函數(shù),12864上顯示的結(jié)果則是一個(gè)sinc函數(shù),證明結(jié)果是正確的。

#include

#include

#include

#define N 128

#define PI 3.141592653589

#define uchar unsigned char

#define uint unsigned int

#define RS (1<<4)

#define RW (1<<5)

#define EN (1<<6)

//

typedef struct

{

int real;

int img;

}complex;

void initw(); //初始化旋轉(zhuǎn)因子

void bitReverse(); //比特反轉(zhuǎn)

void FFT();

complex x[N];

uchar vis[N];

void delayms(uint ms)

{

uint i,j;

for(i=0;i

{

for(j=0;j<3;j++);

}

}

//此處定義字符串

//寫(xiě)數(shù)據(jù)

void WriteDataLCM(unsigned char WDLCM) //寫(xiě)數(shù)據(jù)函數(shù)

{

// ReadStatusLCM(); //檢測(cè)忙

delayms(1);

PORTA|=RS; //RS=1

delayms(1);

PORTA&=~RW; //RW=0

delayms(1);

PORTA|=EN; //EN=1

delayms(1);

PORTB=WDLCM; //輸出數(shù)據(jù)

delayms(1);

PORTA&=~EN; //EN=0

delayms(1);

}

//寫(xiě)指令

void WriteCommandLCM(unsigned char WCLCM) //寫(xiě)命令函數(shù)

{

// ReadStatusLCM(); //根據(jù)需要檢測(cè)忙

delayms(1);

PORTA&=~RS; //RS=0

delayms(1);

PORTA&=~RW; //RW=0

delayms(1);

PORTA|=EN; //EN=1

delayms(1);

PORTB=WCLCM; //輸出指令

delayms(1);

PORTA&=~EN; //EN=0

delayms(1);

}

//讀狀態(tài):檢測(cè)忙

void ReadStatusLCM() //讀狀態(tài)函數(shù)

{

uchar temp;

uchar flag = 1;

while(flag==1)

{

PORTB=0xff;

delayms(1);

DDRB=0x00; //端口B改為輸入

delayms(1);

PORTA&=~RS; //RS=0

delayms(1);

PORTA|=RW; //RW=1

delayms(1);

PORTA|=EN; //EN=1

delayms(10);

temp = PINB; //讀端口B

delayms(10);

DDRB=0xff; //端口B改為

delayms(10);

PORTA&=~EN; //EN=0

delayms(1);

if(temp>>7==0)

flag = 0;

}

}

uchar read_data() //讀數(shù)據(jù)函數(shù)

{

uchar lcd_data;

PORTB=0xff;

DDRB=0x00;

PORTA|=RW;

PORTA|=RS;

delayms(10);

PORTA|=EN;

delayms(10);

lcd_data=PINB;

delayms(10);

PORTA&=~EN;

DDRB=0xff;

return(lcd_data) ;

}

void point(uchar x,uchar y) //打點(diǎn)函數(shù),最重要的函數(shù),GUI的基礎(chǔ)

{

uchar x_Dyte,x_byte;

uchar y_Dyte,y_byte;

uchar GDRAM_hbit,GDRAM_lbit;

WriteCommandLCM(0x36);

x_Dyte=x/16;

x_byte=x&0x0f;

y_Dyte=y/32;

y_byte=y&0x1f;

WriteCommandLCM(0x80+y_byte);

WriteCommandLCM(0x80+x_Dyte+8*y_Dyte);

read_data();

GDRAM_hbit=read_data();

GDRAM_lbit=read_data();

delayms(10);

WriteCommandLCM(0x80+y_byte);

WriteCommandLCM(0x80+x_Dyte+8*y_Dyte);

delayms(10);

if(x_byte<8)

{

WriteDataLCM(GDRAM_hbit|(0x01<<(7-x_byte)));

WriteDataLCM(GDRAM_lbit);

}

else

{

WriteDataLCM(GDRAM_hbit);

WriteDataLCM(GDRAM_lbit|(0x01<<(15-x_byte)));

}

WriteCommandLCM(0x30);

}

//LCM初始化

void LCMInit(void)

{

WriteCommandLCM(0x30); //三次顯示模式設(shè)置,不檢測(cè)忙信號(hào)

delayms(10);

WriteCommandLCM(0x30);

delayms(10);

WriteCommandLCM(0x30);

delayms(10);

WriteCommandLCM(0x30); //顯示模式設(shè)置,開(kāi)始要求每次檢測(cè)忙信號(hào)

WriteCommandLCM(0x08); //關(guān)閉顯示

WriteCommandLCM(0x01); //顯示清屏

WriteCommandLCM(0x06); //顯示光標(biāo)移動(dòng)設(shè)置

WriteCommandLCM(0x0C); //顯示開(kāi)及光標(biāo)設(shè)置

}

void clear(uchar dat) //清屏函數(shù)

{

uchar i,j,k;

uchar addr=0x80;

for(i=0;i<2;i++)

{

for(j=0;j<32;j++)

{

for(k=0;k<8;k++)

{

WriteCommandLCM(0x36);

WriteCommandLCM(0x80+j);

WriteCommandLCM(addr+k);

WriteDataLCM(dat);

WriteDataLCM(dat);

}

}

addr=0x88;

}

WriteCommandLCM(0x36);

WriteCommandLCM(0x30);

}

void heng(uchar a)

{

uchar i;

for(i=0;i<127;i++)

point(i,a);

}

void su(uchar a)

{

uchar i;

for(i=0;i<63;i++)

point(a,i);

}

void FFT()

{

int i,j,k,t,P,B,m;

complex up,down,product;

for (i=0;i<7;i++)

{

B=1<

for (j=0;j

{

t=1<<(6-i);

P=t*j;

for (k=j;k

{

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() //初始化旋轉(zhuǎn)因子

{

int i;

for (i=0;i

vis[i]=0;

}

void bitReverse() //比特反轉(zhuǎn)

{

int i,j=0;

int k=0;

int q=0;

complex tmp3;

for (i=0;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 xian(uchar x,uchar y)

{

uchar i;

for(i=63;i>=y;i--)

point(x,i);

}

//主函數(shù)

void main(void)

{

uchar ii,y;

float tmp;

//端口初始化

DDRA=0xff;

PORTA=0xff;

DDRB=0xff;

PORTB=0xff;

DDRD=0xff;

PORTD=0x00;

delayms(20);

delayms(20);

LCMInit(); //LCM初始化 //液晶初始化

delayms(100);

clear(0x00);

heng(0);

heng(63);

su(0);

su(127);

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();

for(ii=64;ii<128;ii++)

{

tmp=sqrt((x[ii].real*x[ii].real)+(x[ii].img*x[ii].img));

y= 63-(int)tmp;

point(ii-64,y);

xian(ii-64,y);

}

for(ii=0;ii<64;ii++)

{

tmp=sqrt((x[ii].real*x[ii].real)+(x[ii].img*x[ii].img));

y= 63-(int)tmp;

point(ii+64,y);

xian(ii+64,y);

}

while(1);

}

得到的圖片:

MATLAB仿真圖形:

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉