版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第十章單片機(jī)典型模塊應(yīng)用1、任務(wù):點亮LED燈在Keil軟件編輯窗口輸入以下程序:#include<AT89x51.H>sbitP3_0=P3^0;voidmain(void){while(1){P3_0=0;}}2、AT89S51單片機(jī)最小系統(tǒng)介紹單片機(jī)要工作必須具備以下條件:(1)+5V電源;(2)起振電路;(3)復(fù)位電路;(4)一塊正常的單片機(jī)。注意:另外P0口要加上拉電阻,才有足夠的驅(qū)動能力驅(qū)動外圍器件工作;EA接高電平,表示單片機(jī)使用的是片內(nèi)FLASHROM。3、任務(wù):閃爍燈#include<AT89X51.H>voiddelay02s(void){unsignedchari,j,k;for(i=20;i>0;i--)for(j=20;j>0;j--)for(k=248;k>0;k--);}voidmain(void){while(1){P3_0=0;delay02s();P3_0=1;delay02s();}}要求:前面例子是讓LED燈亮,現(xiàn)在實現(xiàn)LED燈的閃爍。4、任務(wù):流水燈要求:做廣告燈的左移右移,八個發(fā)光二極管分別接在單片機(jī)的P3.0-P3.7接口上,輸出“0”時,發(fā)光二極管亮,左移右移按D1→D2→D3→D4→┅→D8→D7→D6→┅→D1亮,重復(fù)循環(huán)。4、任務(wù):流水燈程序:#include<AT89X52.H>unsignedchari;unsignedchartemp;voiddelay(void)//延時子程序{ unsignedcharm,n,s; for(m=20;m>0;m--) for(n=20;n>0;n--) for(s=248;s>0;s--);}voidmain(void)//主程序{ while(1)//循環(huán)條件永遠(yuǎn)為真,以下程序一直執(zhí)行下去。 {
續(xù)前頁:temp=0x7f; P3=temp;//直接對I/O口P3賦值,使P3.7輸出低點平。 delay();//延時 for(i=1;i<8;i++)//實現(xiàn)廣告燈的從D1到D7移動 { temp=(temp>>1)|0x80; P3=temp; delay(); } temp=0xfe; P3=temp; delay(); for(i=1;i<8;i++)//實現(xiàn)廣告燈的從D7到D1移動 { temp=(temp<<1)|0x01; P3=temp; delay(); } }}
思考:如何實現(xiàn)更為復(fù)雜的花樣燈?參考程序:#include"reg51.h"#defineucharunsignedcharconstuchartab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,//下移0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,//上移 0xef,0xbd,0xdb,0xfe,//兩邊向中間移 0xdb,0xbd,0xef,//中間向兩邊移 0xaa,0x55,0xaa,0x55,0xaa,0x55,//1357,2468交替3次 0xf0,0x0f,0xf0,0x0f,//1234,5678交替2次 0x33,0xcc,0x33,0xcc,0x33,0xcc,//1256,3478交替3次 0x00};//結(jié)束碼
uchart=0;////以下初始化子函數(shù)////voidsys_init(void){TMOD=0x01;TH0=0xd8;續(xù)前頁:TL0=0xef;ET0=1;EA=1;TR0=1;}////以下主函數(shù)////voidmain(void){uchari=0;P3=tab[i];i++;sys_init();while(1){while(t<100);t=0;if(tab[i]==0x00){i=0;}P3=tab[i];i++;}}續(xù)左頁:////以下定時器0中斷函數(shù)////voidtimer0(void)interrupt1{TR0=0;TH0=0xd8;TL0=0xef;t++;TR0=1;}5、任務(wù):按鍵識別要求:通過按下一次按鍵INT0,使小燈D1亮滅交替變換。實驗原理:只要判斷P3.2的電平就可以知道按鍵是否被按下;而在按鍵按下的過程中,由于機(jī)械抖動,將產(chǎn)生干擾,電平高低變化。可以采用軟件濾波的方法去除這些干擾信號,在程序設(shè)計時,一旦發(fā)現(xiàn)P3.2為低電平,進(jìn)入按鍵判斷狀態(tài),軟件延時10-20ms,從而避開了干擾信號區(qū)域,再重新檢測P3.2狀態(tài),看按鍵是否真的已經(jīng)按下。參考程序:include<AT89X52.H>sbitINT_0=P3^2;//定義按鍵的輸入端sbitD1=P3^0;
//D1小燈定義voiddelay10ms(void)//延時程序{
unsignedchari,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);}key(
)
//按鍵判斷程序{ if(INT_0==0)//判斷是否按下鍵盤 { delay10ms(
);//延時,軟件去干擾 if(INT_0==0)//確認(rèn)按鍵按下 {
D1=!D1;//D1亮滅交替變化 }
while(INT_0==0);//按鍵鎖定,每按一次D1只變化一次 }續(xù)前頁:}main(){while(1)
//永遠(yuǎn)循環(huán),掃描判斷按鍵是否按下 { key();
//對于此處CPU只按鍵判斷一直掃描; }}
課后請實踐:1.用兩個按鍵來控制D1的亮滅;2.使用一個按鍵,控制小燈亮的順序D1→D2→D3→D4→┅→D8→D7→→┅D0亮重復(fù)循環(huán);6、任務(wù):數(shù)碼管靜態(tài)顯示要求:用數(shù)碼管LED的個位,靜態(tài)顯示數(shù)字“4”字樣;注意:因采用共陰數(shù)碼顯示管,故此圖P0口還應(yīng)接1K或10K的排阻作為上拉電阻。參考程序:#include<AT89X52.H>sbitGE=P1^3;codeunsignedcharseg7code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//顯示段碼main(){ unsignedchardisplay_date=4;//定義并賦值要顯示的數(shù)據(jù) while(1) { P0=seg7code[display_date];
//查表,輸出 GE=0;//P1^3為低電平,相當(dāng)于把數(shù)碼管的4H端接地 }}課后請實踐:1.讓顯示的數(shù)據(jù)動起來,比如做一個0到9的秒表(用軟件延時);2.和按鍵判斷程序結(jié)合,用按鍵控制數(shù)字變化;7、任務(wù):數(shù)碼管動態(tài)顯示要求:用數(shù)碼管LED的顯示四位數(shù)據(jù),比如顯示數(shù)字“1234”;參考程序:#include<AT89X52.H>sbitqian=P1^0;sbitbai=P1^1;sbitshi=P1^2;sbitge=P1^3;codeunsignedcharseg7code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//顯示段碼voidDelay(unsignedinttc)//延時程序{ while(tc!=0) //如果tc為0則終止延時 { unsignedinti; //局部正整數(shù)變量i for(i=0;i<100;i++); //執(zhí)行400次將耗時1毫秒 tc--; //tc計數(shù)減一 }}續(xù)前頁:voidLed(intdate)//顯示函數(shù){ qian=0;//P1.0輸出低電平,選通千位數(shù) P0=seg7code[date/1000];//取出千位數(shù),查表,輸出。 Delay(10);//延時 qian=1;//銷隱 bai=0;//P1.1輸出低電平,選通百位數(shù) P0=seg7code[date%1000/100];//取出百位數(shù),查表,輸出。 Delay(10);//延時 bai=1;//銷隱 shi=0;//P1.2輸出低電平,選通十位數(shù) P0=seg7code[date%100/10];//取出十位數(shù),查表,輸出。 Delay(10);//延時 shi=1;//銷隱 ge=0; //P1.3輸出低電平,選通十位數(shù) P0=seg7code[date%10];//取出個位數(shù),查表,輸出。 Delay(10); ge=1;}
續(xù)前頁:main(){intdisplay_date=1234;//定義并賦值要顯示的數(shù)據(jù)while(1){Led(display_date);//調(diào)用顯示函數(shù)顯示數(shù)據(jù)display_date}}
上述數(shù)碼管動態(tài)顯示程序的另一種寫法參考程序:#include<AT89X51.H>unsignedchardatebit[]={0xfe,0xfd,0xfb,0xf7};//存儲數(shù)碼管的位選值unsignedchartvdate[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f,};unsignedintdisdata;//定義要顯示的數(shù)據(jù)unsignedchardisdat[4];//存儲要顯示的四位數(shù)據(jù)voiddelay(time){unsignedchari,j;for(j=0;j<time;j++)for(i=0;i<250;i++);}display(void){ unsignedchark; disdata=1234;//顯示1234
續(xù)前頁:
disdat[0]=disdat/1000; //取出千位 disdat[1]=disdat%1000/100;
//取出百位 disdat[2]=disdat%100/10; //取出十位 disdat[3]=disdat%10; //取出個位 for(k=0;k<4;k++)
//顯示四位數(shù)據(jù) { P0=tvdate[disdat[k]];
//送出要顯示數(shù)據(jù)的段碼 P1=datebit[k]; //P2位選 delay(10); //延時 }}main(){while(1){display();}}
這種寫法比上一種復(fù)雜,占用空間要多一些.但是使用方便,可以在此基礎(chǔ)上方便的加上比如顯示小數(shù)點,指定某位數(shù)碼管閃爍等。課后思考:如何用軟件延時來做一個0到60秒的計數(shù)器嗎?8、任務(wù):4X4矩陣鍵盤識別要求:用AT89S51的并行口P2接4×4矩陣鍵盤,以P3.0-P3.3作輸入線,以P3.4-P3.7作輸出線;在每一個數(shù)碼管上顯示每個按鍵的“0-F”序號。[實驗原理]每個按鍵有它的行值和列值,行值和列值的組合就是識別這個按鍵的編碼。矩陣的行線和列線分別通過兩并行接口和CPU通信。鍵盤處理程序的任務(wù)是:確定有無鍵按下,判斷哪一個鍵按下,鍵的功能是什么;還要消除按鍵在閉合或斷開時的抖動。兩個并行口中,一個輸出掃描碼,使按鍵逐行動態(tài)接地,另一個并行口輸入按鍵狀態(tài),由行掃描值和回饋信號共同形成鍵編碼而識別按鍵,通過軟件查表,查出該鍵的功能。鍵盤識別的兩種方法逐行掃描法:(1)首先判斷有無鍵按下:令矩陣行線輸出全0信號,檢測列線狀態(tài),若有一列電平為低,則有鍵按下。(2)確定閉合鍵位置:依次將各行線置為低電平,逐行檢測各列線的電平狀態(tài),若某列為低,則該行線和列線交叉處按鍵就是閉合鍵。線反轉(zhuǎn)法:(1)令矩陣鍵盤列線輸出全0信號,行線作為輸入接口接收信號,可判斷按鍵處于哪一行。(2)令矩陣鍵盤行線輸出全0信號,列線作為輸入接口接收信號,可判斷按鍵處于哪一列。(3)將輸入信號相或后形成鍵盤的唯一鍵碼。程序:(線反轉(zhuǎn)法)#include<reg52.h>unsignedcharcodeseg7code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};unsignedchark;voiddelay10ms(void)//延時程序{ unsignedchari,j; for(i=20;i>0;i--) for(j=248;j>0;j--);}voidGetch(){ unsignedcharX,Y,Z;
P2=0xff;
P2=0x0f;
//先對P2置數(shù)行掃描 if(P2!=0x0f)//判斷是否有鍵按下 {
delay10ms();//延時,軟件去干擾
if(P2!=0x0f)
//確認(rèn)按鍵按下X=P2;
{
續(xù)前頁:
X=P2;//保存行掃描時有鍵按下時狀態(tài) P2=0xf0;//列掃描 Y=P2;//保存列掃描時有鍵按下時狀態(tài) Z=X|Y;//取出鍵值 switch(Z)//判斷鍵值(那一個鍵按下) { case0x77:k=0;break;//對鍵值賦值 case0x7b:k=1;break; case0x7d:k=2;break; case0x7e:k=3;break; case0xb7:k=4;break; case0xbb:k=5;break; case0xbd:k=6;break; case0xbe:k=7;break; case0xd7:k=8;break; case0xdb:k=9;break; case0xdd:k=10;break; case0xde:k=11;break; case0xe7:k=12;break; case0xeb:k=13;break; 續(xù)前頁:
case0xed:k=14;break;
case0xee:k=15;break; } } }}voidmain(void){while(1){P2=0xff;Getch(
);P0=seg7code[k];//查表LED輸出P1=0xf0;//輸出相同的四位數(shù)據(jù)。}}
9、任務(wù):按鍵中斷識別要求:采用中斷技術(shù),每按一下按鍵,計數(shù)器加1,并用LED顯示出來,注意只顯示2位十進(jìn)制數(shù)。原理:以上的兩個關(guān)于按鍵識別的實驗的程序都是采用掃描的方式來實現(xiàn)的,CPU的利用率比較低;按鍵判斷還可以用中斷方式來判斷。中斷方式可以滿足快速響應(yīng)的要求。程序:#include<AT89X51.H>unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unsignedchardispcount=0;//計數(shù)sbitgewei=P1^3;//個位選通定義sbitshiwei=P1^2;//十位選通定義voidDelay(unsignedinttc)//延時程序{while(tc!=0){unsignedinti;for(i=0;i<100;i++);tc--;}}voidExtInt0()interrupt0//中斷服務(wù)程序{續(xù)前頁:dispcount++;//每按一次中斷按鍵,計數(shù)加一if(dispcount==100)//計數(shù)范圍0-99{dispcount=0;}}voidLED()//LED顯示函數(shù){if(dispcount>=10)//顯示兩位數(shù){shiwei=0;P0=table[dispcount/10];Delay(8);shiwei=1;gewei=0;P0=table[dispcount%10];Delay(5);gewei=1;}else//顯示一位數(shù){
續(xù)前頁:shiwei=1;gewei=0;P0=table[dispcount];Delay(8);}}
voidmain(){TCON=0x01;
//下降沿觸發(fā)
IE=0x81;
//開總中斷和允許外部中斷
while(1)
//循環(huán)執(zhí)行{LED(
);}
//調(diào)用顯示函數(shù)}/*******************************************************************課后思考:在程序在硬件運(yùn)行過程中,有時候按一下鍵會加幾個數(shù),是因為沒有去除按鍵干擾請您想一想怎么消除抖動./***************************************************************************************/
10、任務(wù):定時器T0的應(yīng)用——9.9秒計時設(shè)計要求:開始時,顯示“00”,第1次按下INT0后就開始計時。第2次按INT0后,計時停止。第3次按INT0后,計時歸零。程序:#include<AT89X51.H>unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,};unsignedcharsec;//定義計數(shù)值,每過1/10秒,sec加一unsignedcharkeycnt=1;//鍵值判斷unsignedinttcnt;//中斷次數(shù)計數(shù)器
sbitgewei=P1^3;//個位選通定義sbitshiwei=P1^2;//十位選通定義sbitINT_0=P3^2;//按鍵定義位voidDelay(unsignedinttc)//延時程序{while(tc!=0){unsignedinti;for(i=0;i<100;i++);tc--;}}續(xù)前頁:voidLED(
)//LED顯示函數(shù){shiwei=0;P0=table[sec/10]|0x80;//十位加上小數(shù)點Delay(5);shiwei=1;gewei=0;P0=table[sec%10];Delay(5);gewei=1;}voidKEY()//按鍵掃描程序{unsignedchari,j;if(INT_0==0){for(i=20;i>0;i--)//延時去干擾for(j=248;j>0;j--);續(xù)前頁:if(INT_0==0){switch(keycnt)
//按下次數(shù)判斷{case1:
//第一次按下TH0=0x06;
//對TH0TL0賦值TL0=0x06;TR0=1;
//開始定時keycnt=2;
//為第二次做準(zhǔn)備break;case2:
//第二次按下TR0=0;
//定時結(jié)束keycnt=3;
//為第三次按下做準(zhǔn)備break;case3:
//第三次按下keycnt=1;
//重新開始判斷鍵值sec=0;
//計數(shù)重新從零開始break;}
續(xù)前頁:while(INT_0==0);}}}voidt0(void)interrupt1using0//定時中斷服務(wù)函數(shù){tcnt++;//每過250us,tcnt加一if(tcnt==400)//計滿400次(0.1秒)時{tcnt=0;//重新再計sec++;if(sec==100)//定時10秒,在從零開始計時{sec=0;}}}續(xù)前頁:voidmain(void){TMOD=0x02;//定時器工作在方式2自動重裝方式ET0=1;//允許T0產(chǎn)生中斷EA=1;//開總中斷sec=0;while(1){KEY();LED();}}11、任務(wù):PC機(jī)與單片機(jī)通信要求:單片機(jī)串口通信的應(yīng)用,通過串口,電腦和單片機(jī)系統(tǒng)進(jìn)行通信。電腦作為上位機(jī),向下位機(jī)單片機(jī)系統(tǒng)發(fā)送十六進(jìn)制或者ASCLL碼,單片機(jī)系統(tǒng)接收后,用LED顯示接收到的數(shù)據(jù)和向上位機(jī)發(fā)回原樣數(shù)據(jù)。單片機(jī)串口相關(guān)知識回顧(1)MCS-51串行口的原理結(jié)構(gòu)圖
單片機(jī)串口相關(guān)知識回顧(2)串行口控制寄存器SCON
SM0SM1SM2RENTB8RB8TIRID7D6D5D4D3D2D1D0
SMODGF1GF0PDIDLD7D6D5D4D3D2D1D0
(3)特殊功能寄存器PCON
單片機(jī)串口相關(guān)知識回顧(4)串口通信的波特率
對于方式0,波特率是固定的,為單片機(jī)時鐘的1/12,即fosc/12。對于方式2,波特率有兩種可供選擇,即fosc/32和fosc/64。對應(yīng)于以下公式:
波特率=fosc×(2^SMOD)/64對于方式1和方式3,波特率都由定時器T1的溢出率來決定,對應(yīng)于以下公式:
波特率=(2^SMOD/32)×(定時器T1的溢出率)
而定時器T1的溢出率則和所采用的定時器工作方式有關(guān),并可用以下公式表示:
定時器T1的溢出率=fosc/12×(2^n-X)程序:#include<AT89X51.H>unsignedchardat;//用于存儲單片機(jī)接收發(fā)送緩沖寄存器SBUF里面的內(nèi)容sbitgewei=P1^3;//個位選通定義sbitshiwei=P1^2;//十位選通定義unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};voidDelay(unsignedinttc)//延時程序{while(tc!=0){unsignedinti;for(i=0;i<100;i++);tc--;}}voidLED()//LED顯示接收到的數(shù)據(jù)(十進(jìn)制){shiwei=0;P0=table[dat/10];Delay(5);續(xù)前頁:shiwei=1;gewei=0;P0=table[dat%10];Delay(5);gewei=1;}voidInit_Com(void)//功能:串口初始化,波特率9600,方式1{TMOD=0x20;PCON=0x00;SCON=0x50;TH1=0xFd;TL1=0xFd;TR1=1;}續(xù)前頁:voidmain()//實現(xiàn)接收數(shù)據(jù)并把接收到的數(shù)據(jù)原樣發(fā)送回去///////{Init_Com();//串口初始化while(1){if(RI)//掃描判斷是否接收到數(shù)據(jù),{dat=SBUF;//接收數(shù)據(jù)SBUF賦與datRI=0;//RI清零(必須用軟件清零)SBUF=dat;//再原樣把數(shù)據(jù)發(fā)送回去}LED();//顯示接收到的數(shù)據(jù)}}12、任務(wù):數(shù)模轉(zhuǎn)換器ADC0804的應(yīng)用(擴(kuò)展)要求:從ADC0804的通道IN+輸入0-5V之間的模擬量,通過ADC0804轉(zhuǎn)換成數(shù)字量在數(shù)碼管上以十進(jìn)制形成顯示出來。程序:#include<reg52.h>codeunsignedcharseg7code[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//顯示段碼sbitint1=P3^3;//定義管腳功能sbitcs=P3^2;sbitwr=P3^6;sbitrd=P3^7;voidDelay(unsignedinttc)//顯示延時程序{while(tc!=0){unsignedinti;for(i=0;i<100;i++);tc--;}}unsignedcharadc0804(void)//讀AD0804子程序{unsignedcharaddata,i;rd=1;wr=1;int1=1;//讀ADC0804前準(zhǔn)備P1=0xff;//P1全部置一準(zhǔn)備cs=0;wr=0;wr=1;//啟動ADC0804開始測電壓while(int1==1);//查詢等待A/D轉(zhuǎn)換完畢產(chǎn)生的INT(低電平有效)信號rd=0;//開始讀轉(zhuǎn)換后數(shù)據(jù)續(xù)前頁:i=i;i=i;//無意義語句,用于延時等待ADC0804讀數(shù)完畢addata=P1;//讀出的數(shù)據(jù)賦與addatard=1;cs=1;//讀數(shù)完畢return(addata);//返回最后讀出的數(shù)據(jù)}unsignedintdatpro(void)
//ADC0804讀出的數(shù)據(jù)處理{unsignedcharx;unsignedintdianyah,dianyal;
//用于存儲讀出數(shù)據(jù)的高字節(jié)和低字節(jié)unsignedintdianya=0;
//存儲最后處理完的結(jié)果注意數(shù)據(jù)類型for(x=0;x<10;x++)
//將10次測得的結(jié)果存儲在dianya中{dianya=adc0804()+dianya;}dianya=dianya/10;
//求平均值dianyah=dianya&0xf0;
//屏蔽低四位dianyah=dianyah>>4;
//右移四位取出高四位dianyal=dianya&0x0f;
//屏蔽高四位取出低四位dianya=dianyal*20+dianyah*320;
//最后的結(jié)果是一個四位數(shù),便于顯示return(dianya);//返回最后處理結(jié)果}續(xù)前頁:voidLed(){unsignedintdate;date=datpro();//調(diào)用數(shù)據(jù)處理最后結(jié)果P2=P2&0xef;P0=seg7code[date/1000]|0x80;//輸出個位數(shù)和小數(shù)點Delay(8);P2=P2|0xf0;P2=P2&0xdf;P0=seg7code[date%1000/100];//輸出小數(shù)點后第一位Delay(8);P2=P2|0xf0;P2=P2&0xbf;P0=seg7code[date%100/10];//輸出小數(shù)點后第二位Delay(8);P2=P2|0xf0;P2=P2&0x7f;P0=seg7code[date%10];//輸出小數(shù)點后第三位Delay(8);P2=P2|0xf0;}main(){while(1){Led();//只需調(diào)用顯示函數(shù)}}13、任務(wù):模數(shù)轉(zhuǎn)換器DAC0832的應(yīng)用要求:用兩個按鍵通過單片機(jī)控制DAC0832的輸出,使OUT端可以輸出0—5V的幅值,頻率為1KHZ的鋸齒波和三角波兩種波形。通上電源后;按下INT1則輸出三角波,再按下INT0輸出鋸齒波。[實驗原理]DAC0832是8位全MOS中速D/A轉(zhuǎn)換器,采用R—2RT形電阻解碼網(wǎng)絡(luò),轉(zhuǎn)換結(jié)果為一對差動電流輸出,轉(zhuǎn)換時間大約為1us。使用單電源+5V―+15V供電。參考電壓為-10V-+10V。在此我們直接選擇+5V作為參考電壓。DAC0832有三種工作方式:直通方式,單緩沖方式,雙緩沖方式;在此我們選擇直通的工作方式,將XFER、WR1、WR2和CS管腳全部接數(shù)字地。管腳8接參考電壓,在此我們接的參考電壓是+5V。那么經(jīng)過第一級運(yùn)放后,輸出電壓將是-5V-0V,在經(jīng)過第二級運(yùn)放反相放大1倍以后將可以輸出0V—5V了。再控制P1口輸出數(shù)據(jù)有規(guī)律的變化將可以產(chǎn)生三角波,鋸齒波,梯型波等波形了。程序:#include<AT89X51.H>unsignedcharkeycnt=0;//波形標(biāo)志unsignedchartcnt=0;//鍵值判斷bitsjz=0;//產(chǎn)生三角波時上升、下降用到的標(biāo)志voiddelayl()
//延時子程序{unsignedchari,j;for(i=20;i>0;i--)for(j=248;j>0;j--);}voidKEY()
//按鍵掃描程序{if(P3_2==0){delayl();//延時跳過按下時的抖動if(P3_2==0){keycnt=0;
//定時器產(chǎn)生鋸齒波標(biāo)志TR0=0;
//暫時停止波形輸出TH0=0x256-40;
//對TH0TL0賦值TL0=0x256-40;TR0=1;
//開始定時,產(chǎn)生鋸齒波續(xù)前頁:while(P3_2==0);//如果一直按著鍵,則等待鍵松開delayl();//延時跳過松開后的抖動}}if(P3_3==0){delayl();//延時跳過按下時的抖動if(P3_3==0){keycnt=1;//定時器產(chǎn)生三角波標(biāo)志TR0=0;//暫時停止波形輸出TH0=0x256-40;//對TH0、TL0賦值TL0=0x256-40;TR0=1;//開始定時產(chǎn)生三角波}while(P3_2==0);//如果一直按著鍵,則等待松鍵開delayl();//延時跳過松開后的抖動}}續(xù)前頁:voidt0(void)interrupt1using0//定時中斷服務(wù)函數(shù){if(keycnt==0)//產(chǎn)生鋸齒波{P0=tcnt;tcnt=+0x0a;//步進(jìn)0.2V/一次中斷if(tcnt==0xfb){tcnt=0;}}if(keycnt==1)//產(chǎn)生三角波{if(sjz==0){P0=tcnt;tcnt=+0x0a;//步進(jìn)0.2V/一次中斷if(tcnt==0xfa){sjz=1;}}if(sjz==1)續(xù)前頁:{P0=tcnt;Tcnt-=0x0a;if(tcnt==0){sjz=0;}}}}voidmain(void){TMOD=0x02;//定時器工作在方式2ET0=1;EA=1;while(1){KEY();}}14、任務(wù):24C08的讀寫操作要求:利用24C08斷電以后存儲的數(shù)據(jù)不消失的特點,可以做一個斷電保護(hù)裝置。首先利用單片機(jī)做一個0—99秒的自動計時器。然后隨機(jī)關(guān)斷電源,在通電以后計時器接著斷電前的狀態(tài)繼續(xù)計時。[實驗原理——引腳圖][實驗原理——總線協(xié)議][實驗原理——寫周期時序和起始、停止時序][實驗原理——器件尋址][實驗原理——器件尋址][實驗原理——寫操作]注意:I2C總線數(shù)據(jù)都是高位在前,低位在后?。。蹖嶒炘怼獙懖僮鳎荩蹖嶒炘怼x操作][實驗原理——讀操作][實驗原理——讀操作]程序:#include<AT89X52.H>#include<stdio.h>#include<absacc.h>unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unsignedcharsec;//定義計數(shù)值,每過1秒,sec加1unsignedinttcnt;//定時中斷次數(shù)bitwrite=0;//寫24C08的標(biāo)志;sbitgewei=P1^3;//個位選通定義sbitshiwei=P1^2;//十位選通定義/////////24C08讀寫驅(qū)動程序開始////////////////////sbitscl=P3^6;//24c08SCLsbitsda=P3^7;//24c08SDAvoiddelay1(unsignedcharx){unsignedinti;for(i=0;i<x;i++);;}voidflash()
//延時2us{;;}voidx24c08_init()//24c08初始化子程序{scl=1;flash();sda=1;flash();}voidstart()//啟動I2C總線{sda=1;flash();scl=1;flash();sda=0;flash();scl=0;flash();}voidstop()//停止I2C總線{sda=0;flash();scl=1;flash();sda=1;flash();}voidwritex(unsignedcharj)//寫一個字節(jié){unsignedchari,temp;temp=j;for(i=0;i<8;i++){temp=temp<<1;scl=0;flash();sda=CY;flash();scl=1;flash();}scl=0;flash();sda=1;flash();}unsignedcharreadx()//讀一個字節(jié){unsignedchari,j,k=0;scl=0;flash();sda=1;for(i=0;i<8;i++){flash();scl=1;flash();if(sda==1)j=1;elsej=0;k=(k<<1)|j;scl=0;}flash();return(k);}voidclock()//I2C總線時鐘,確認(rèn)應(yīng)答信號{unsignedchari=0;scl=1;flash();while((sda==1)&&(i<255))i++;scl=0;flash();}////////從24c08的地址address中讀取一個字節(jié)數(shù)據(jù)/////unsignedcharx24c08_read(unsignedcharaddress){unsignedchari;//先發(fā)寫命令、寫地址start();writex(0xa0);clock();writex(address);clock();//再發(fā)讀命令,讀數(shù)據(jù)start();writex(0xa1);clock();i=readx();stop();delay1(10);return(i);}//////向24c08的address地址中寫入一字節(jié)數(shù)據(jù)info/////voidx24c08_write(unsignedcharaddress,unsignedcharinfo){EA=0;start();writex(0xa0);clock();writex(address);clock();writex(info);clock();stop();EA=1;delay1(50);}/////////////以上24C08讀寫驅(qū)動程序完/////////////////////voidDelay(unsignedinttc)
//延時程序{while(tc!=0){unsignedinti;for(i=0;i<100;i++);tc--;}}voidLED()//LED顯示函數(shù){shiwei=0;P0=table[sec/10];Delay(5);shiwei=1;gewei=0;P0=table[sec%10];Delay(5);gewei=1;}voidt0(void)interrupt1using0//定時中斷服務(wù)函數(shù){TH0=(65536-50000)/256;//對TH0TL0賦值TL0=(65536-50000)%256;//重裝計數(shù)初值tcnt++;//每過250usttcnt加一if(tcnt==20)//計滿20次(1秒)時{tcnt=0;sec++;write=1;//1秒寫一次24C08if(sec==100)//定時100秒,在從零開始計時{sec=0;}}}voidmain(void){TMOD=0x01;//定時器工作在方式1ET0=1;EA=1;x24c08_init();//初始化24C08sec=x24c08_read(2);//讀出保存的數(shù)據(jù)賦于secTH0=(65536-50000)/256;//對TH0TL0賦值TL0=(65536-50000)%256;//使定時器0.05秒中斷一次TR0=1;//開始計時while(1){LED();if(write==1)//判斷計時器是否計時一秒{write=0;//清零x24c08_write(2,sec);//在24c08的地址2寫入數(shù)據(jù)sec}}}15、任務(wù):LCD1602液晶模塊應(yīng)用要求:LCD1602字符型液晶顯示實驗。在屏幕的第一行顯示“224166320@”,第二行則顯示“Tel:1308645xxxx”[實驗原理——LCD基礎(chǔ)知識]LCD顯示器是一種利用液晶的扭曲/向列效應(yīng)制成的新型顯示器。具有體積小、重量輕、功耗低、抗干擾能力強(qiáng)等優(yōu)點,因而在單片機(jī)系統(tǒng)中被廣泛應(yīng)用。[實驗原理——LCD結(jié)構(gòu)及工作原理]LCD本身不發(fā)光,是通過借助外界光線照射液晶材料而實現(xiàn)顯示的被動顯示器件。向列型液晶材料被封裝在上、下兩片導(dǎo)電玻璃電極之間,液晶分子平行排列,上下扭曲90度,外部入射光線通過上偏振片后形成偏振光,該偏振光通過平行排列的液晶材料后被旋轉(zhuǎn)90度,再通過與上偏振片垂直的下偏振片,被反射極反射過來,呈透明狀態(tài)。若在上、下電極之間加一定電壓,在電場的作用下迫使加在電極部分的液晶分子轉(zhuǎn)成垂直排列,其旋光作用也隨之消失,致使從上偏振片入射的偏振光不旋轉(zhuǎn),光無法通過下偏振片返回,呈黑色。去掉電壓后,液晶分子又恢復(fù)其扭轉(zhuǎn)結(jié)構(gòu)。實驗原理——SMC1602A液晶模塊引腳功能實驗原理——液晶控制器接口說明實驗原理——液晶控制器接口說明實驗原理——液晶控制器接口說明實驗原理——液晶控制器接口說明實驗原理——1602液晶控制器自帶標(biāo)準(zhǔn)字庫每一個字符都有一個固定的代碼,比如“A”的代碼是41H,顯示時模塊把41H中的點陣字符圖形顯示出來,就能看到字母“A”。#include<AT89x52.h>#include<INTRINS.h>#defineucharunsignedchar#defineuintunsignedint#defineDOUTP0sbitrs=P2^0;sbitrw=P2^1;sbite=P2^7;codeuchartab1[]={0x32,0x32,0x34,0x31,0x36,0x36,0x33,0x32,0x30,0x40,0x71,0x71,0x2e,0x63,0x6f,0x6d,0xff,};codeuchartab2[]={0x54,0x65,0x6c,0x3a,0x20, 0X31,0X33,0x30,0x38,0x36,0x34,0x35,0x78,0x78,0x78,0x78,0xff,};//延時函數(shù)voiddelayms(unsignedintms){unsignedchari;while(ms--){for(i=0;i<120;i++);}}參考示例程序(LCD16021.0版)//以下為讀忙狀態(tài)的時序程序unsignedcharread_status(void){unsignedcharLCD_Status;DOUT=0xff;rs=0;rw=1;e=1;delayms(1);LCD_Status=DOUT;e=0;returnLCD_Status;}//以下為寫命令的時序程序voidwrite_com(unsignedcharcmd){while((read_status()&0x80)==0x80);rs=0;rw=0;e=0;P0=cmd;e=1;delayms(1);e=0;}//以下為液晶初始化程序voidlcd_ini(void){write_com(0x38);delayms(1);write_com(0x01);delayms(1);write_com(0x06);delayms(1);write_com(0x0c);delayms(1);}//以下為寫數(shù)據(jù)的時序程序voidwrite_dat(unsignedchardat){while((read_status()&0x80)==0x80);rs=1;rw=0;e=0;P0=dat;e=1;delayms(1);e=0;}//以下為主函數(shù)voidmain(void){uchari=0;lcd_ini();write_com(0x80);//設(shè)置第一行數(shù)據(jù)地址指針,為80H+地址碼delayms(1);while(tab1[i]!=0xff){write_dat(tab1[i]);i++;delayms(1);}i=0;write_com(0xc0);//設(shè)置第二行數(shù)據(jù)地址指針,為80H+地址碼delayms(1);while(tab2[i]!=0xff){write_dat(tab2[i]);i++;delayms(1);}i=0;while(1);}思考:如何利用總線控制方式顯示字符?1、添加頭文件包含語句:#include“absacc.h”2、添加宏定義語句:#defineLCD_W_COMXBYTE[0x7cff]#defineLCD_W_DATXBYTE[0X7dff]#defineLCD_R_COMXBYTE[0x7eff]3、修改讀忙狀態(tài)、寫命令和寫數(shù)據(jù)的時序程序。例:unsignedcharread_status(void){unsignedcharLCD_Status;LCD_Status=LCD_R_COM;returnLCD_Status;}重要提示:參考程序://LCD1602.C//液晶控制與顯示程序#include<reg51.h>#include<intrins.h>sbitRS=P2^0;//寄存器選擇位,將RS位定義為P2.0引腳sbitRW=P2^1;//讀寫選擇位,將RW位定義為P2.1引腳sbitEN=P2^2;//使能信號位,將E位定義為P2.2引腳//延時函數(shù)voiddelayms(unsignedintms){unsignedchari;while(ms--){for(i=0;i<120;i++);}}該液晶顯示程序的另一種寫法(LCD16022.0版)//忙檢測函數(shù)unsignedcharbusy_check(void){unsignedcharLCD_Status;//定義忙狀態(tài)變量RS=0;RW=1;EN=1;delayms(1);LCD_Status=P0;//讀取忙狀態(tài)EN=0;returnLCD_Status;//返回忙狀態(tài)}//寫命令voidwrite_LCD_Command(unsignedcharcmd){while((busy_check()&0x80)==0x80);//等待忙狀態(tài)結(jié)束RS=0;RW=0;EN=0;P0=cmd;EN=1;delayms(1);EN=0;}//寫數(shù)據(jù)voidwrite_LCD_data(unsignedchardat){while((busy_check()&0x80)==0x80);RS=1;RW=0;EN=0;P0=dat;EN=1;delayms(1);EN=0;}//初始化voidinit_LCD(void){write_LCD_Command(0x38);//顯示模式設(shè)置delayms(1);write_LCD_Command(0x01);//清屏delayms(1);write_LCD_Command(0x06);//字符進(jìn)入模式:屏幕不動,字符后移delayms(1);write_LCD_Command(0x0c);//顯示開,關(guān)光標(biāo)delayms(1);}//顯示字符串voidShowString(unsignedcharx,unsignedchary,unsignedchar*str){unsignedchari=0;//設(shè)置起始位置if(y==0){write_LCD_Command(0x80|x);}if(y==1){write_LCD_Command(0xc0|x);}//輸出字符串for(i=0;i<16;i++){write_LCD_data(str[i]);}}//主函數(shù)voidmain(void){init_LCD();ShowString(0,0,"224166320@");ShowString(0,1,"Tel:1308645xxxx");while(1);}基本思路:將一個文件的程序按照其模塊功能劃分為兩個或兩個以上的文件,每個文件表示系統(tǒng)實現(xiàn)特定的功能。如本程序可分為主函數(shù)C文件、液晶顯示C文件、液晶顯示頭文件、includes頭文件。//main.c:#include"includes.h"voidmain(void){init_LCD();ShowString(0,0,"224166320@");ShowString(0,1,"Tel:1308645xxxx");while(1);}大型模塊化程序的肇始(LCD16023.0版)//lcd1602test.c:#include<reg51.h>#include<LCD1602.h>voidShowString(unsignedcharx,unsignedchary,unsignedchar*str){unsignedchari=0;if(y==0){write_LCD_Command(0x80|x);}if(y==1){write_LCD_Command(0xc0|x);}for(i=0;i<16;i++){write_LCD_data(str[i]);}}大型模塊化程序的肇始(LCD16023.0版)//includes.h:#ifndef__INCLUDES_H__#define__INCLUDES_H__#include<reg51.h>#include<intrins.h>voidShowString(unsignedcharx,unsignedchary,unsignedchar*str);init_LCD();#endif大型模塊化程序的肇始(LCD16023.0版)//lcd1602.h:#ifndefLCD_CHAR_1602_2010_11_8#defineLCD_CHAR_1602_2010_11_8sbitRS=P2^0;//寄存器選擇位,將RS位定義為P2.0引腳sbitRW=P2^1;//讀寫選擇位,將RW位定義為P2.1引腳sbitEN=P2^2;//使能信號位,將E位定義為P2.2引腳voiddelayms(unsignedintms){unsignedchari;while(ms--){for(i=0;i<120;i++);}}大型模塊化程序的肇始(LCD16023.0版)接上頁://忙檢測函數(shù)unsignedcharbusy_check(void){unsigne
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版?zhèn)€人二手房買賣擔(dān)保協(xié)議4篇
- 二零二五年度綠色金融項目擔(dān)保合作協(xié)議4篇
- 二零二五版民政局離婚協(xié)議書制作及審核流程3篇
- 2025年度個人車輛抵押借款協(xié)議(智能化風(fēng)險評估)4篇
- 2025年度航空航天行業(yè)個人勞動合同范本4篇
- 2025年度個人沙石環(huán)保處理與資源回收合同3篇
- 2025年度個人股東股權(quán)轉(zhuǎn)讓及綠色建筑項目合作協(xié)議4篇
- 評價幼兒大班課程設(shè)計
- 重塑睡眠生態(tài)課程設(shè)計
- 2025年鐵藝欄桿生產(chǎn)、銷售、安裝及維護(hù)合同3篇
- 四川省成都市武侯區(qū)2023-2024學(xué)年九年級上學(xué)期期末考試化學(xué)試題
- 初一到初三英語單詞表2182個帶音標(biāo)打印版
- 2024年秋季人教版七年級上冊生物全冊教學(xué)課件(2024年秋季新版教材)
- 2024年共青團(tuán)入團(tuán)積極分子考試題庫(含答案)
- 碎屑巖油藏注水水質(zhì)指標(biāo)及分析方法
- 【S洲際酒店婚禮策劃方案設(shè)計6800字(論文)】
- 鐵路項目征地拆遷工作體會課件
- 醫(yī)院死亡報告年終分析報告
- 中國教育史(第四版)全套教學(xué)課件
- 上海民辦楊浦實驗學(xué)校初一新生分班(摸底)語文考試模擬試卷(10套試卷帶答案解析)
- 圍手術(shù)期應(yīng)急預(yù)案
評論
0/150
提交評論