中斷方式可以提高CPU的效率,當(dāng)發(fā)生中斷事件時(shí)處理器可快速響應(yīng)中斷,沒(méi)有中斷事件時(shí)處理器正常工作,不必時(shí)刻查詢中斷事件的發(fā)生與否,提高代碼效率。
本例中,若采用電平觸發(fā)方式,則Key為低電平時(shí)Led亮,否則Led息滅;若采用邊沿觸發(fā)方式,則Key的每個(gè)下降沿,即Key由高變?yōu)榈蜁r(shí),Led的狀態(tài)改變一次。
void int0() interrupt 0 //邊沿觸發(fā)方式中斷函數(shù)。每次Key下降沿改變Led狀態(tài)
KEY EQU P3.2
LED EQU P1.0
ORG 0000H
LJMP MAIN
ORG 0003H
LJMP INIT
ORG 0010
MAIN: CLR IT0 ;電平觸發(fā)方式,邊沿觸發(fā)為SETB IT0
SETB EA
SETB EX0
SJMP $
INIT: CLR LED
JNB KEY,$
SETB LED
;INIT: CPL LED ;邊沿觸發(fā)方式中斷程序
1 實(shí)驗(yàn)?zāi)康?/strong>通過(guò)此次實(shí)驗(yàn)學(xué)習(xí)單片機(jī)串口的應(yīng)用,掌握串口相關(guān)寄存器的配置,并學(xué)會(huì)用串口做簡(jiǎn)單的雙機(jī)通信。
2 實(shí)驗(yàn)內(nèi)容通過(guò)串口實(shí)現(xiàn)雙機(jī)通信,用Key控制發(fā)光二極管。
3 實(shí)驗(yàn)器材STC89C52RC單片機(jī)、LED燈或?qū)嶒?yàn)箱。
4 實(shí)驗(yàn)步驟- 在Keil開(kāi)發(fā)環(huán)境下建立一個(gè)工程。
- 程序的編寫。
- 程序下載調(diào)試(可先進(jìn)行仿真)。
5 附注51單片機(jī)串行口的SBUF有兩個(gè):接收SBUF和發(fā)送SBUF,二者在物理結(jié)構(gòu)上是獨(dú)立的,單片機(jī)用它們來(lái)接收和發(fā)送數(shù)據(jù)。串行通訊的波特率隨串行口工作方式選擇的不同而不同,它除了與系統(tǒng)的振蕩頻率f,電源控制寄存器PCON的SMOD位有關(guān)外,還與定時(shí)器T1的設(shè)置有關(guān)。
1、在工作方式0時(shí),波特率固定不變,僅與系統(tǒng)振蕩頻率有關(guān),其大小為f/12。
2、在工作方式2時(shí),波特率也只固定為兩種情況:
當(dāng)SMOD=1時(shí), 波特率=f/32
當(dāng)SMOD=0時(shí), 波特率=f/64
3、在工作方式1和3時(shí),波特率是可變的:
當(dāng)SMOD=1時(shí), 波特率=定時(shí)器T1的溢出率/16
當(dāng)SMOD=0時(shí), 波特率=定時(shí)器T1的溢出率/32
其中,定時(shí)器T1的溢出率=f/(12*(256-N)),N為T1的定時(shí)時(shí)間常數(shù)。
在實(shí)際應(yīng)用中,往往是給定通訊波特率,而后去確定時(shí)間常數(shù)。例如:f=6.144MHZ,波特率等于1200,SMOD=0時(shí),則1200=6144000/(12*32*(256-N)),計(jì)算得N=F2H。
本例程中設(shè)置串行口工作于方式1,SMOD=0,波特率為1200。
6 附注例程中斷方式C代碼:
#include
#define unchar unsigned char
#define unint unsigned int
sbit Key = P1^1;
sbit Led = P1^0;
void uartsend(unchar dat);
void Uartsend(unchar k) //串口發(fā)送子函數(shù)
{
SBUF = k; //發(fā)送數(shù)據(jù)
while(!TI); //待待發(fā)送結(jié)束
}
void main()
{
unchar tmp;
TMOD = 0x20; //定時(shí)器1工作方式2
TH1 = 0xfa;
TL1 = 0xfa; //裝入定時(shí)器初值11.0592M晶振,波特率4800
PCON = 0; //波特率不倍增
ET1 = 0; //定時(shí)器1中斷允許
EA = 1; //總中斷允許
ES = 1; //串口中斷允許
TR1 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
SCON = 0x50; //串口工作方工1,準(zhǔn)備接收
while(1) //死循環(huán)
{
if(Key) //判斷是否有鍵按下
{
Uartsend(0xaa); //用串口發(fā)送0xaa
while(Key); //等待鍵釋放
}
else
{
Uartsend(0x55);
while(!Key);
}
}
}
void uart() interrupt 4
{
unchar temp;
if(RI) //判斷是否為接收中斷
{
temp = SBUF; //讀數(shù)據(jù)
switch(temp) //判斷數(shù)據(jù)
{
case 0x55:Led = 1;break;
case 0xaa:Led = 0;break;
default:break;
}
RI = 0; //清除中斷標(biāo)志
}
TI = 0; //清除中斷標(biāo)志
}
對(duì)應(yīng)匯編代碼:
KEY EQU P1.1
LED EQU P1.0
ORG 0000H
LJMP MAIN
ORG 0023H
LJMP UART
ORG 0100H
MAIN: MOV TMOD,#020H
MOV TH1,#0FAH
MOV TL1,#0FAH
MOV PCON,#00H
CLR ET1
SETB EA
SETB ES
SETB TR1
MOV SCON,#050H
KEYLED: JNB KEY,OFFL
MOV SBUF,#0AAH
KEY0: JB KEY,$
OFFL: MOV SBUF,#055H
KEY1: JNB KEY,$
SJMP KEYLED
UART: JNB RI,RRET
CLR RI
MOV R7,SBUF
CJNE R7,#0AAH,OFFLED
CLR LED
SJMP RRET
OFFLED: SETB LED
RRET: CLR TI
RETI
END
查詢方式C代碼:
#include
#define unchar unsigned char
#define unint unsigned int
sbit Key = P1^1;
sbit Led = P1^0;
void uartsend(unchar dat) //串口發(fā)送子函數(shù)
{
SBUF = dat; //發(fā)送數(shù)據(jù)
while(!TI); //待待發(fā)送結(jié)束
TI = 0; //清除中斷標(biāo)志
}
void uartrec() //串口接收數(shù)據(jù)子函數(shù)
{
unchar temp;
if(RI)
{
temp = SBUF; //讀數(shù)據(jù)
switch(temp) //判斷數(shù)據(jù)
{
case 0x55:Led = 1;break;
case 0xaa:Led = 0;break;
default:break;
}
RI = 0; //清除中斷標(biāo)志
}
}
void main()
{
TMOD = 0x20; //定時(shí)器1工作方式2
TH1 = 0xfa;
TL1 = 0xfa; //裝入定時(shí)器初值11.0592M晶振,波特率4800
PCON = 0; //波特率不倍增
ET1 = 0; //定時(shí)器0中斷允許
EA = 0; //總中斷關(guān)閉
ES = 1; //串口中斷允許
TR1 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
SCON = 0x50; //串口工作方工1,準(zhǔn)備接收
while(1)
{
if(Key) //判斷鍵是否按下
{
uartsend(0xaa);
while(Key)uartrec(); //等鍵釋放并接收數(shù)據(jù)
}
uartsend(0x55);
while(!Key)uartrec();
}
}
對(duì)應(yīng)匯編代碼:
KEY EQU P1.1
LED EQU P1.0
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN: MOV TMOD,#020H
MOV TH1,#0FAH
MOV TL1,#0FAH
MOV PCON,#00H
CLR ET1
CLR EA
SETB ES
SETB TR1
MOV SCON,#050H
KEYLED: JNB KEY,OFFL
MOV SBUF,#0AAH
JNB TI,$
CLR TI
SJMP KEY1
OFFL: MOV SBUF,#055H
JNB TI,$
CLR TI
KEY0: JB KEY,KEYLED
LCALL UARTRI
SJMP KEY0
KEY1: JNB KEY,OFFL
LCALL UARTRI
SJMP KEY1
UARTRI: JNB RI,RETT
CLR RI
MOV R7,SBUF
CJNE R7,#0AAH,OFFLED
CLR LED
RETT: RET
OFFLED: SETB LED
SJMP RETT
END
附實(shí)驗(yàn)仿真電路:
注:MCU1的TX接MCU2的RX,MCU1的RX接MCU2的TX。