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

當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]基于MCS51設(shè)計的概念版的信號發(fā)生器

系統(tǒng)簡介:這款信號發(fā)生器的原理是利用單片機(jī)控制DAC0832數(shù)模轉(zhuǎn)化芯片,使其輸出-5~+5的模擬量信號,由于單片機(jī)的指令執(zhí)行周期很短,其中Atmel89s52最大可支持24M的晶振,可以用數(shù)字信號產(chǎn)生很好的“模擬”信號。

這款系統(tǒng)只是概念上的,因為受到數(shù)模芯片轉(zhuǎn)化時間和單片機(jī)程序控制時間的限制,只能在很小的頻率范圍內(nèi)出比較好的波形,這款系統(tǒng)主要還是其程序的控制,其中控制程序占有整個程序的90%左右。

一塊4×4的矩陣鍵盤向單片機(jī)提供輸入,使LCD1602液晶顯示出頻率和幅值,通過抄作鍵盤可以改變相應(yīng)的頻率、幅值以及輸出波形。

系統(tǒng)構(gòu)成部件:

單片機(jī)Atmel89s52、數(shù)模轉(zhuǎn)換芯片DAC0832、4×4鍵盤、LCD1602液晶顯示

模塊介紹:

4×4的矩陣鍵盤

 

單片機(jī)系統(tǒng):24M晶振,30pf的電容,P0口:液晶的數(shù)據(jù)口,P2口:DAC0832的數(shù)據(jù)口,P1口:接4×4的矩陣鍵盤,P3.7:DAC0832片選信號

 

數(shù)模轉(zhuǎn)換:DAC0832,基本接法

 

顯示:LCD1602

 

波形輸出:DAC0832的雙極型輸出

 

仿真波形:

 

LCD顯示:

 

程序設(shè)計:

#include //包含單片機(jī)寄存器的頭文件

#include //包含_nop_()函數(shù)定義的頭文件

#define uchar unsigned char

#define uint unsigned int

sbit RS=P3^0; //寄存器選擇位,將RS位定義為P2.0引腳

sbit RW=P3^1; //讀寫選擇位,將RW位定義為P2.1引腳

sbit E=P3^2; //使能信號位,將E位定義為P2.2引腳

sbit BF=P0^7; //忙碌標(biāo)志位,,將BF位定義為P0.7引腳

sbit CS=P3^7; //DA0832片選信號

bit F_Flag=0;

bit SET_Flag=0;

bit Wave_Flag=1;

unsigned char Flag=0;

unsigned char j=0;

unsigned char a=0;

unsigned int F_Val=100;

unsigned int A_Val=5000;

unsigned int u1,u2;

unsigned char code digit[ ]={"0123456789"}; //定義字符數(shù)組顯示數(shù)字

unsigned char code string[ ]= {" F: 100HZ "};

unsigned char code string1[ ]={" A:5000mV "};

unsigned char code string2[ ]={"SIN"};

unsigned char code string3[ ]={"TRA"};

unsigned char code string4[ ]={"REC"};

unsigned char code key_code[]={

0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,

0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77 };

uchar code tosin[256]={

0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,

0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5,

0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,

0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5,

0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,

0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,

0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,

0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,

0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,

0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99,

0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0x76,

0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,

0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,

0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16,

0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,

0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x05,

0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15,

0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,

0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e,

0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x72,

0x76,0x79,0x7c,0x80};//正弦波碼

/*****************************************************

函數(shù)功能:延時1ms

***************************************************/

void delay1ms()

{

unsigned char i,j;

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

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

;

}

/*****************************************************

函數(shù)功能:延時若干毫秒

入口參數(shù):n

***************************************************/

void delay(unsigned int n)

{

unsigned int i;

for(i=0;i

delay1ms();

}

/*****************************************************

函數(shù)功能:判斷液晶模塊的忙碌狀態(tài)

返回值:result。result=1,忙碌;result=0,不忙

***************************************************/

unsigned char BusyTest(void)

{

bit result;

RS=0; //根據(jù)規(guī)定,RS為低電平,RW為高電平時,可以讀狀態(tài)

RW=1;

E=1; //E=1,才允許讀寫

_nop_(); //空操作

_nop_();

_nop_();

_nop_(); //空操作四個機(jī)器周期,給硬件反應(yīng)時間

result=BF; //將忙碌標(biāo)志電平賦給result

E=0;

return result;

}

/*****************************************************

函數(shù)功能:將模式設(shè)置指令或顯示地址寫入液晶模塊

入口參數(shù):dictate

***************************************************/

void WriteInstruction (unsigned char dictate)

{

while(BusyTest()==1); //如果忙就等待

RS=0; //根據(jù)規(guī)定,RS和R/W同時為低電平時,可以寫入指令

RW=0;

E=0; //E置低電平(根據(jù)表8-6,寫指令時,E為高脈沖,

// 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"

_nop_();

_nop_(); //空操作兩個機(jī)器周期,給硬件反應(yīng)時間

P0=dictate; //將數(shù)據(jù)送入P0口,即寫入指令或地址

_nop_();

_nop_();

_nop_();

_nop_(); //空操作四個機(jī)器周期,給硬件反應(yīng)時間

E=1; //E置高電平

_nop_();

_nop_();

_nop_();

_nop_(); //空操作四個機(jī)器周期,給硬件反應(yīng)時間

E=0; //當(dāng)E由高電平跳變成低電平時,液晶模塊開始執(zhí)行命令

}

/*****************************************************

函數(shù)功能:指定字符顯示的實際地址

入口參數(shù):x

***************************************************/

void WriteAddress(unsigned char x)

{

WriteInstruction(x|0x80); //顯示位置的確定方法規(guī)定為"80H+地址碼x"

}

/*****************************************************

函數(shù)功能:將數(shù)據(jù)(字符的標(biāo)準(zhǔn)ASCII碼)寫入液晶模塊

入口參數(shù):y(為字符常量)

***************************************************/

void WriteData(unsigned char y)

{

while(BusyTest()==1);

RS=1; //RS為高電平,RW為低電平時,可以寫入數(shù)據(jù)

RW=0;

E=0; //E置低電平(根據(jù)表8-6,寫指令時,E為高脈沖,

// 就是讓E從0到1發(fā)生正跳變,所以應(yīng)先置"0"

P0=y; //將數(shù)據(jù)送入P0口,即將數(shù)據(jù)寫入液晶模塊

_nop_();

_nop_();

_nop_();

_nop_(); //空操作四個機(jī)器周期,給硬件反應(yīng)時間

E=1; //E置高電平

_nop_();

_nop_();

_nop_();

_nop_(); //空操作四個機(jī)器周期,給硬件反應(yīng)時間

E=0; //當(dāng)E由高電平跳變成低電平時,液晶模塊開始執(zhí)行命令

}

/*****************************************************

函數(shù)功能:對LCD的顯示模式進(jìn)行初始化設(shè)置

***************************************************/

void LcdInitiate(void)

{

delay(15); //延時15ms,首次寫指令時應(yīng)給LCD一段較長的反應(yīng)時間

WriteInstruction(0x38); //顯示模式設(shè)置:16×2顯示,5×7點陣,8位數(shù)據(jù)接口

delay(5); //延時5ms

WriteInstruction(0x38);

delay(5);

WriteInstruction(0x38);

delay(5);

WriteInstruction(0x0F); //顯示模式設(shè)置:顯示開,有光標(biāo),光標(biāo)閃爍

delay(5);

WriteInstruction(0x06); //顯示模式設(shè)置:光標(biāo)右移,字符不移

delay(5);

WriteInstruction(0x01); //清屏幕指令,將以前的顯示內(nèi)容清除

delay(5);

}

/**********************************************************

鍵盤掃描子函數(shù)

************************************************************/

uchar keyscan()

{

uchar scan1,scan2,keycode,j,key;

P2=0xf0;

scan1=P2;

if((scan1&0xf0)!=0xf0) //判鍵是否按下

{

delay(10); //延時10ms

scan1=P2;

if((scan1&0xf0)!=0xf0) //二次判鍵是否按下

{

P2=0x0f;

scan2=P2;

keycode=scan1|scan2; //組合成鍵編碼

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

{

if(keycode== key_code[j]) //查表得鍵值

{

key=j;

return(key);

}

}

}

}

else P1=0xff;

return (16);

}

/****************延時中斷子程序1*****************/

void timer0() interrupt 1

{

if(Flag==0) //正弦波

P1=tosin[j];

if(Flag==1)//三角波

if(j<128)

P1=A_Val*j/5000;

else

P1=A_Val*(255-j)/5000;

if(Flag==2) //方波

{if(j<128)

P1=A_Val/20;

else P1=255-A_Val/20;

a=0;}

j++;

}

void main(void) //主函數(shù)

{

unsigned char i;

LcdInitiate(); //調(diào)用LCD初始化函數(shù)

delay(10);

WriteInstruction(0x01);//清顯示:清屏幕指令

WriteAddress(0x00); // 設(shè)置顯示位置為第一行的第1個字

i = 0;

while(string[i] != '\0') //'\0'是數(shù)組結(jié)束標(biāo)志

{ // 顯示字符

WriteData(string[i]);

i++;

delay(40);

}

WriteAddress(0x40); // 設(shè)置顯示位置為第二行的第1個字

i = 0;

while(string[i] != '\0') //'\0'是數(shù)組結(jié)束標(biāo)志

{ // 顯示字符

WriteData(string1[i]);

i++;

delay(40);

}

WriteAddress(0x67);

while(1)

{

if(keyscan()==10&&SET_Flag==0)

{ delay(20);

if(keyscan()==10&&SET_Flag==0)

{ Flag++;

if(Flag==3)

Flag=0;

WriteAddress(0x01);

_nop_();

_nop_();

_nop_();

_nop_();

if(Flag==0)

{ i = 0;

while(string2[i] != '\0') //'\0'是數(shù)組結(jié)束標(biāo)志

{ // 顯示字符 SIN

WriteData(string2[i]);

i++;

delay(40);

}

}

if(Flag==1)

{ i = 0;

while(string3[i] != '\0') //'\0'是數(shù)組結(jié)束標(biāo)志

{ // 顯示字符 TRA

WriteData(string3[i]);

i++;

delay(40);

}

}

if(Flag==2)

{ i = 0;

while(string4[i] != '\0') //'\0'是數(shù)組結(jié)束標(biāo)志

{ // 顯示字符 REC

WriteData(string4[i]);

i++;

delay(40);

}

}

delay(400);

}

WriteAddress(0x67);

}

if(keyscan()==11)

{ delay(20);

if(keyscan()==11)

{ if(F_Flag==0)

WriteAddress(0x46);

else

WriteAddress(0x06);

delay(500) ;

F_Flag=!F_Flag;

SET_Flag=1;

Wave_Flag=1;

}

}

if(keyscan()==12&&SET_Flag==1)

{ delay(20);

if(keyscan()==12&&SET_Flag==1)

{unsigned char D1,D2,D3,D4;

unsigned int Val;

if(F_Flag==0)

{Val=F_Val;

WriteAddress(0x08);}

else {Val=A_Val;

WriteAddress(0x48);}

Val=Val+10;

D1=Val%10; //計算個位數(shù)字

D2=(Val%100)/10; //計算十位數(shù)字

D3=(Val%1000)/100; //計算百位數(shù)字

D4=Val/1000; //計算千位數(shù)字

WriteData(digit[D4]); //將千位數(shù)字的字符常量寫入LCD

WriteData(digit[D3]); //將百位數(shù)字的字符常量寫入LCD

WriteData(digit[D2]); //將十位數(shù)字的字符常量寫入LCD

WriteData(digit[D1]); //將個位數(shù)字的字符常量寫入LCD

if(F_Flag==0)

F_Val=Val;

else A_Val=Val;

}

if(F_Flag==0)

WriteAddress(0x06);

else WriteAddress(0x46);

delay(400);

}

if(keyscan()==13&&SET_Flag==1)

{ delay(20);

if(keyscan()==13&&SET_Flag==1)

{unsigned char D1,D2,D3,D4;

unsigned int Val;

if(F_Flag==0)

{Val=F_Val;

WriteAddress(0x08); }

else {Val=A_Val;

WriteAddress(0x48);}

Val=Val-10;

D1=Val%10; //計算個位數(shù)字

D2=(Val%100)/10; //計算十位數(shù)字

D3=(Val%1000)/100; //計算百位數(shù)字

D4=Val/1000; //計算千位數(shù)字

WriteData(digit[D4]); //將千位數(shù)字的字符常量寫入LCD

WriteData(digit[D3]); //將百位數(shù)字的字符常量寫入LCD

WriteData(digit[D2]); //將十位數(shù)字的字符常量寫入LCD

WriteData(digit[D1]); //將個位數(shù)字的字符常量寫入LCD

if(F_Flag==0)

F_Val=Val;

else A_Val=Val;

}

if(F_Flag==0)

WriteAddress(0x06);

else WriteAddress(0x46);

delay(400);

}

if(keyscan()==14)

{delay(20);

if(keyscan()==14)

{SET_Flag=0;

Wave_Flag=1;

WriteAddress(0x76);

}

}

if(Wave_Flag==1)

{ CS=0;

u1=3906/F_Val;

u2=3906%F_Val;

if(u2>F_Val/2)

u1++;

TMOD=0x02;

TH0=TL0=255-u1;

EA=1;

ET0=1;

TR0=1;

}

if(keyscan()!=16)

TR0=TR1=0;

}

}

總結(jié):優(yōu)秀的程序設(shè)計源自于優(yōu)秀的硬件系統(tǒng),好的硬件電路可以大大提高開發(fā)效率,單片機(jī)開發(fā)應(yīng)該走接口的模塊話和標(biāo)準(zhǔn)化,這樣可以大大減少開發(fā)人員的工作量,單片機(jī)接口模塊的開發(fā)也較具有市場前景!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

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

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