一、匯編語言 編寫51單片機(jī)定時(shí)/計(jì)數(shù)中斷響應(yīng)程序
ORG 0000H
LJMP MAIN
ORG 000Bh
LJMP ZD0
ORG 0040H
MAIN: MOV TH0,#0d8h
MOV TL0,#0e8h
MOV A,#0FEh
SETB EA
SETB ET0
SETB TR0
SJMP $
ZD0: MOV P2,A
MOV TH0,#0d8h
MOV TL0,#0f0h
inc r3
CJNE r3,#99D,ddd
mov r3,#00h
inc r4
CJNE r4,#9D,ddd
mov r4,#00h
RL A
DDD:reti
end
二、C語言編寫51單片機(jī)定時(shí)/計(jì)數(shù)中斷響應(yīng)程序
#include"reg51.h"
int ms,i,k,n,m,temp=0x01;
void delay(ms)
{
while(ms--)
for(i=0;i<120;i++);
}
void main()
{
TMOD=0x01;
EA=1;
ET0=1;
TR0=1;
while(1);
}
void timer0() interrupt 1
{
TH0=(65536-10000-6)/256;
TL0=(65536-10000-6)%256;
k++;
if(k==100)
{
k=0;
m++;
}
if(m==8)m=0;
P2=temp<<m;//這個(gè)語句是將變量temp左移m位給P2,不改變temp的值。
//如果改成temp=temp<<m,就改變了temp的值
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
定時(shí)器中斷c語言解析interrupt x using y
interrupt 表示中斷優(yōu)先級,using表示所用工作寄存器組。
interrupt x using y
跟在interrupt 后面的x 值是中斷號,就是說這個(gè)函數(shù)對應(yīng)第幾個(gè)中斷端口,一般在51中,x對應(yīng)的中斷如下:
0 外部中斷0
1 定時(shí)器0
2 外部中斷1
3 定時(shí)器1
4 串行中斷
其它的根據(jù)相應(yīng)的單片機(jī)有自己的含義,實(shí)際上c在編譯的時(shí)候就是把你這個(gè)函數(shù)的入口地址放到這個(gè)對應(yīng)中斷的跳轉(zhuǎn)地址
using y 這個(gè)y是說這個(gè)中斷函數(shù)使用的那個(gè)寄存器組就是51里面一般有4個(gè) r0 -- r7寄存器,如果你的中斷函數(shù)和別的程序用的不是同一個(gè)寄存器組則進(jìn)入中斷的時(shí)候就不會(huì)將寄存器組壓入堆棧,返回時(shí)也不會(huì)彈出來 節(jié)省代碼和時(shí)間
外部中斷INT0
void intsvr0(void) interrupt 0 using 1
定時(shí)/計(jì)數(shù)器T0
void timer0(void) interrupt 1 using 1
外部中斷INT1
void intsvr1(void) interrupt 2 using 1
定時(shí)/計(jì)數(shù)器T1
void timer1(void) interrupt 3 using 1
串口中斷
void serial0(void) interrupt4 using 1
一,中斷的概念
中斷:當(dāng)計(jì)算機(jī)執(zhí)行正常程序時(shí),系統(tǒng)中出現(xiàn)某些急需處理的異常情況和特殊請求.
中斷的執(zhí)行:當(dāng)CPU正在執(zhí)行某一程序時(shí),若有中斷響應(yīng),則CPU轉(zhuǎn)而執(zhí)行中斷服務(wù)程序,當(dāng)中斷服務(wù)程序執(zhí)行完畢后,CPU自動(dòng)返回原來的程序繼續(xù)執(zhí)行.
中斷服務(wù)程序的語句寫法與函數(shù)的寫法完全相同,所以,中斷服務(wù)程序也是函數(shù),只在函數(shù)頭部有不同(后續(xù)).
中斷服務(wù)程序的執(zhí)行與函數(shù)的執(zhí)行不同:函數(shù)的執(zhí)行是有固定位置的,是通過函數(shù)的調(diào)用來完成的;而中斷服務(wù)程序的執(zhí)行是不固定位置的,只要有中斷響應(yīng),在一定條件下都會(huì)去響應(yīng)中斷,即執(zhí)行中斷服務(wù)程序.
二,中斷源
中斷源:任何引起計(jì)算機(jī)中斷的事件,一般一臺機(jī)器允許有許多個(gè)中斷源.
8051系列單片機(jī)至少有5個(gè)可能的中斷(8052有6個(gè),其它系列成員最多可達(dá)15個(gè)).下面以5個(gè)中斷源為例.
8051單片機(jī)的五個(gè)中斷源是:
外部中斷請求0,由INT0(P3.2)輸入;
外部中斷請求1,由INT1(P3.3)輸入;
片內(nèi)定時(shí)器/計(jì)數(shù)器0溢出中斷請求;
片內(nèi)定時(shí)器/計(jì)數(shù)器1溢出中斷請求;
片內(nèi)串行口發(fā)送/接收中斷請求.
三,與中斷有關(guān)的寄存器
1,定時(shí)/計(jì)數(shù)器控制寄存器TCON
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
D7 D6 D5 D4 D3 D2 D1 D0
. IT0,IT1:外部中斷0,1觸發(fā)方式選擇位,由軟件設(shè)置;
1→下降沿觸發(fā)方式,INT0/INT1管腳上高到低的負(fù)跳變可引起中斷;
0→電平觸發(fā)方式, INT0/INT1管腳上低電平可引起中斷.
. IE0,IE1:外部中斷0,1請求標(biāo)志位;
當(dāng)外部中斷0,l依據(jù)觸發(fā)方式滿足條件,產(chǎn)生中斷請求時(shí)由硬件置位 (IE0/IE1=1);當(dāng)CPU響應(yīng)中斷時(shí)由硬件清除(IE0/IE1= 0).
. TR0,TR1: 啟動(dòng)定時(shí)/計(jì)數(shù)器0,1.
. TF0,TF1:定時(shí)器/計(jì)數(shù)器0,1(T/C0,T/C1)溢出中斷請求標(biāo)志;
當(dāng)T/C0,1計(jì)數(shù)溢出時(shí)由硬件置位(TF0/TF1=l);
當(dāng)CPU響應(yīng)中斷由硬件清除(TFO/TF1=0).
三,與中斷有關(guān)的寄存器
2,串行口控制寄存器SCON
TI RI
D7 D6 D5 D4 D3 D2 D1 D0
. RI:串行口接收中斷請求標(biāo)志位;
當(dāng)串行口接收完一幀數(shù)據(jù)后請求中斷,由硬件置位(RI=1)
RI必須由軟件清"0".
. TI:串行口發(fā)送中斷請求標(biāo)志位.
當(dāng)串行口發(fā)送完一幀數(shù)據(jù)后請求中斷,由硬件置位(TI=1)
TI必須由軟件清"0".
三,與中斷有關(guān)的寄存器
3,中斷允許寄存器IE
EA ET2 ES ET1 EX1 ET0 EX0
D7 D6 D5 D4 D3 D2 D1 D0
. EX0,EX1:外部中斷0,1的中斷允許位;
l→外部中斷0,1開中斷;0→外部中斷0,1關(guān)中斷.
. ET0,ET1:定時(shí)器/計(jì)數(shù)器0,1(T/C0,T/C1)溢出中斷允許位;
1→T/C0,T/Cl開中斷;0→T/C0,T/Cl關(guān)中斷.
. ES:串行口中斷允許位;
1→串行口開中斷;0→串行口關(guān)中斷.
. ET2:定時(shí)器/計(jì)數(shù)器2(T/C2)溢出中斷允許位;
1→T/C2開中斷;0→T/C2關(guān)中斷.
. EA:CPU開/關(guān)中斷控制位.
1→CPU開中斷.0→CPU關(guān)中斷.
8051復(fù)位時(shí),IE被清"0",此時(shí)CPU關(guān)中斷,各中斷源的中斷也都屏蔽
三,與中斷有關(guān)的寄存器
4,中斷優(yōu)先級寄存器IP
PS PT1 PX1 PT0 PX0
D7 D6 D5 D4 D3 D2 D1 D0
. PX0,PX1:外部中斷0,1中斷優(yōu)先級控制位;
1→高優(yōu)先級;0→低優(yōu)先級.
. PT0,PT1:定時(shí)器/計(jì)數(shù)器0,1中斷優(yōu)先級控制位;
1→高優(yōu)先級;0→低優(yōu)先級.
. PS:串行口中斷優(yōu)先級控制位;
1→高優(yōu)先級;0→低優(yōu)先級.
8051復(fù)位時(shí),IP被清"0",5個(gè)中斷源都在同一優(yōu)先級,其內(nèi)部優(yōu)先級的順序從高到低為: 外部中斷0(IE0)
定時(shí)器/計(jì)數(shù)器0(TF0)
外部中斷1(IE1)
定時(shí)器/計(jì)數(shù)器1(TF1)
串行口中斷(RI+TI)
四,中斷響應(yīng)
8051的CPU在每個(gè)機(jī)器周期采樣各中斷源的中斷請求標(biāo)志位,如果沒有下述阻止條件,將在下一個(gè)機(jī)器周期響應(yīng)被激活了的最高級中斷請求:
1.CPU正在處理同級或更高級的中斷;
2.現(xiàn)行機(jī)器周期不是所執(zhí)行指令的最后一個(gè)機(jī)器周期;
3.正在執(zhí)行的是RETI或是訪問IE或IP的指令.
CPU在中斷響應(yīng)后完成如下的操作:
1.硬件清除相應(yīng)的中斷請求標(biāo)志;
2.執(zhí)行一條硬件子程序,保護(hù)斷點(diǎn),并轉(zhuǎn)向中斷服務(wù)程序人口
3.結(jié)束中斷時(shí)執(zhí)行RETI指令,恢復(fù)斷點(diǎn),返回主程序.
8051的CPU在響應(yīng)中斷請求時(shí),由硬件自動(dòng)形成轉(zhuǎn)向與該中斷源對應(yīng)的服務(wù)程序入口地址,這種方法為硬件向量中斷法.
五,中斷服務(wù)程序的入口地址
編號 中斷源 人口地址
0 外部中斷0 0003H
1 定時(shí)器/計(jì)數(shù)器0 000BH
2 外部中斷1 0013H
3 定時(shí)器/計(jì)數(shù)器1 001BH
4 串行口中斷 0023H
各中斷服務(wù)程序入口地址僅間隔8個(gè)字節(jié),編譯器在這些地址放入無條件轉(zhuǎn)移指令跳轉(zhuǎn)到服務(wù)程序的實(shí)際地址.
六,中斷服務(wù)程序的語法規(guī)則
中斷服務(wù)程序的語法規(guī)則如下:
函數(shù)的返回值 函數(shù)名([參數(shù)]) interrupt n [using m]
{
函數(shù)體;
}
對中斷程序而言,函數(shù)的返回值和參數(shù)一般為void.
interrupt n 中n的取值為0~31的常數(shù),不允許用表達(dá)式,表示中斷向量的編號.
using m 中m的取值為0~3的常數(shù),不允許用表達(dá)式,表示內(nèi)部RAM中的工作寄存器.
七,中斷說明
中斷不允許用于外部函數(shù),它對函數(shù)目標(biāo)代碼影響如下z
·當(dāng)調(diào)用函數(shù)時(shí),SFR中的ACC,B,DPH,DPL和PSW(當(dāng)需要時(shí))入錢;
.如果不使用寄存器組切換,甚至中斷函數(shù)所需的所有工作寄存器都入錢;
.函數(shù)退出前,所有的寄存器內(nèi)容出錢;
·函數(shù)由8051的指令"RETI"終止.
中斷服務(wù)程序使用的任何程序也使用同一寄存器組.
八,中斷例子
#include 〈reg51.h〉
unsigned char status;
bit flag;
void service_int() interrupt 2 using 2
{
flag=1;
status=P1;
}
void main(void)
{
IP=0x04; IE=0x84;
for(;;){
if(flag){
switch(status){
case 0: break;
case 1: break;
case 2: break;
case 3: break;
default: ;}
flag=0;
}
}
}
習(xí)題
試設(shè)計(jì)滿足下列要求的電路圖:
1 單片機(jī)采用89C51,時(shí)鐘11.0592MHz;
2 有4個(gè)指示燈表示狀態(tài);
3 外接12位A/D芯片AD574;
4 有4 * 4的鍵盤;
5 有字符型LCD(畫成插座形式,12Pin插座,管腳接法見書P253);
6 有串行接口與計(jì)算機(jī)連接;
7 設(shè)置8位二進(jìn)制的地址,地址范圍可表示為0~255;
8 外接EEPROM.
定時(shí)器/計(jì)數(shù)器(T/C)
8051系列單片機(jī)至少有兩個(gè)16位內(nèi)部定時(shí)器/計(jì)數(shù)器,8052有三個(gè)定時(shí)器/計(jì)數(shù)器,其中有兩個(gè)是基本定時(shí)器/計(jì)數(shù)器是定時(shí)器/計(jì)數(shù)器.它們既可以編程為定時(shí)器使用,也可以編程為計(jì)數(shù)器使用.
若是計(jì)數(shù)內(nèi)部晶振驅(qū)動(dòng)時(shí)鐘,它是定時(shí)器;若是計(jì)數(shù),8051的輸入管腳的脈沖信號,它是計(jì)數(shù)器.
當(dāng)T/C工作在定時(shí)器時(shí),對振蕩源12分頻的脈沖計(jì)數(shù),即每個(gè)機(jī)器周期計(jì)數(shù)值加1,計(jì)數(shù)率=1/12f osc.例當(dāng)晶振為12MHz時(shí),計(jì)數(shù)率=1000kHz,即每1μs計(jì)數(shù)值加1.
當(dāng)T/C工作在計(jì)數(shù)器時(shí),計(jì)數(shù)脈沖來自外部脈沖輸入管腳T0(P3.4)或T1(P3.5),當(dāng)T0或T1腳上負(fù)跳變時(shí)計(jì)數(shù)值加1.識別管腳上的負(fù)跳變需兩個(gè)機(jī)器周期,即24個(gè)振蕩周期.所以T0或T1腳輸入的可計(jì)數(shù)外部脈沖的最高頻率為1/24fosc,當(dāng)晶振為12MHZ時(shí),最高計(jì)數(shù)率為500kHz,高于此頻率將計(jì)數(shù)出錯(cuò).
一,與T/C有關(guān)的SFR
1,計(jì)數(shù)寄存器Th和TL
T/C是16位的,計(jì)數(shù)寄存器由TH高8位和TL低8位構(gòu)成.
在特殊功能寄存器(SFR) 中,
對應(yīng)T/C0為TH0和TL0;
對應(yīng)T/C1為TH1和TL1.
定時(shí)器/計(jì)數(shù)器的初始值通過TH1/TH0和TL1/TL0設(shè)置.
2,定時(shí)器/計(jì)數(shù)器控制寄存器TCON
前面已介紹.
二,與T/C有關(guān)的SFR
3,T/C的方式控制寄存器TMOD
. C/T:計(jì)數(shù)器或定時(shí)器選擇位;
1→為計(jì)數(shù)器;0→為定時(shí)器.
. GATE :門控信號;
1 → T/C的啟動(dòng)受到雙重控制,即要求TR0/TR1和INT0/INT1同時(shí)為高;
0 → T/C的啟動(dòng)僅受TR0或TR1控制.
GATE C/T M1 M0 GATE C/T M1 M0
D7 D6 D5 D4 D3 D2 D1 D0
T/C1
T/C0
三,四種工作方式
M1 M0 方式 功 能
0 0 0 13位定時(shí)器/計(jì)數(shù)器,TL是低5位,TH是高8位
0 1 1 16位定時(shí)器/計(jì)數(shù)器
1 0 2 常數(shù)自動(dòng)重裝的8位定時(shí)器/計(jì)數(shù)器
1 1 3 僅用于T/C0,是兩個(gè)8位定時(shí)器/計(jì)數(shù)器
利用定時(shí)器編寫時(shí)鐘程序.
四,T/C工作方式的說明
1. 方式0:
當(dāng)TMOD中MlM0=00時(shí),T/C工作在方式0;
方式0為13位的T/C,由TH的高8位,TL的低5位的計(jì)數(shù)值,滿計(jì)數(shù)值213,但啟動(dòng)前可以預(yù)置計(jì)數(shù)初值.
若T/C開中斷(ET=1)且CPU開中斷(EA=1)時(shí),則定時(shí)器/計(jì)數(shù)器溢出時(shí),CPU轉(zhuǎn)向中斷服務(wù)程序時(shí),且TF白動(dòng)清0.
2. 方式1:
當(dāng)TMOD中MlM0=01時(shí),T/C工作在方式1;
方式1與方式0基本相同.唯一區(qū)別在于計(jì)數(shù)寄存器的位數(shù)是16位的,由TH和TL寄存器各提供8位,滿計(jì)數(shù)值為216.
四,T/C工作方式的說明
3. 方式2:
當(dāng)TMOD中MlM0=10時(shí),T/C工作在方式2;
方式2是8位的可自動(dòng)重載的T/C,滿計(jì)數(shù)值為28;
在方式0和方式1中,當(dāng)計(jì)數(shù)滿后,若要進(jìn)行下一次定時(shí)/計(jì)數(shù),須用軟件向TH和TL重裝預(yù)置計(jì)數(shù)初值;
方式2中TH和TL被當(dāng)作兩個(gè)8位計(jì)數(shù)器,計(jì)數(shù)過程中,TH寄存8位初值并保持不變,由TL進(jìn)行8位計(jì)數(shù).計(jì)數(shù)溢出時(shí),除產(chǎn)生溢出中斷請求外,還自動(dòng)將TH中初值重裝到TL,即重裝載.
4. 方式3:
方式3只適合于T/C0.當(dāng)T/CO工作在方式3時(shí),TH0和TL0成為兩個(gè)獨(dú)立的8位計(jì)數(shù)器.
五,定時(shí)器/計(jì)數(shù)器的初始化
在使用8051的定時(shí)器/計(jì)數(shù)器前,應(yīng)對它進(jìn)行編程初始化,主要是對TCON和TMOD編程;計(jì)算和裝載T/C的計(jì)數(shù)初值.一般完成以下幾個(gè)步驟:
(1)確定T/C的工作方式——編程TMOD寄存器;
(2)計(jì)算T/C中的計(jì)數(shù)初值,并裝載到TH和TL;
(3)T/C在中斷方式工作時(shí),須開CPU中斷和源中斷——編程IE寄存器;
(4)啟動(dòng)定時(shí)器/計(jì)數(shù)器——編程TCON中TR1或TR0位.
六,定時(shí)器/計(jì)數(shù)器的初值計(jì)算
在定時(shí)器方式下,T/C是對機(jī)器周期脈沖計(jì)數(shù)的,若fosc=12MHz,一個(gè)機(jī)器周期為12/fosc=1μs,則:
方式0 13位定時(shí)器最大定時(shí)間隔=8.192ms;(2的13次方=8192)
方式1 16位定時(shí)器最大定時(shí)間隔=65.536ms;(2的16次方=65536)
方式2 8位定時(shí)器最大定時(shí)間隔=256μs.
若使T/C工作在定時(shí)器方式1(16位二進(jìn)制),要求定時(shí)1ms,求計(jì)數(shù)初值.設(shè)計(jì)數(shù)初值為x,則有:
(65536-x)×1μs=1000μs
或x=65536一1000
因此,TH,TL可置-1000;
即:TH= -1000/256;TL= -1000%256.
對一般fosc有下列公式(設(shè)定時(shí)時(shí)間為timeμs):
(216-x)×12/fosc= time μs
例1,設(shè)單片機(jī)的fosc=12MHz,要求在P1.0腳上輸出周期為2ms的方波
采用查詢方式.
#include 〈reg51.h〉
sbit P1_0=P1^0;
void main(void〉
{ TMOD=0x01; TR0=1;
for(;;)
{TH0= -1000/256;
TL0= -1000%256;
do {} while(!TF0);
P1_0=!P1_0;
TF0=0;
}
}
采用中斷方式.
#include 〈reg51.h>
sbit P1_0=P1^0;
void timer0(void) interrupt 1using 1 {P1_0=!P1_0; TH0= -1000/256;
TL0= -1000%256;}
void main(void)
{TMOD=0x01; P1_0=0;
TH0= -1000/256;
TL0= -1000%256;
EA=1;ET0=1;TR0=1;
do {} while(1);
}
例2,設(shè)單片機(jī)的fosc=6MHz,要求在P1.7腳上的指示燈亮一秒滅一秒.
void main(void)
{P1_7=0; P1_0=1;
TMOD=0x61;
TH0= -50000/256;
TL0= -50000%256;
TH1= -5; TL1= -5;
IP=0x08;
EA=l; ET0=1;
ET1=l; TR0=l;
TR1=1;
for (;;){}
}
#include
sbit P1_0=P1^0;
sbit P1_7=P1^7;
void timer0( ) interrupt 1 using 1
{P1_0=!P1_0;
TH0= -50000/256;
TL0= -50000%256;
}
void timer1( ) interrupt3 using 2
{P1_7=!P1_7;}
例3,設(shè)單片機(jī)的fosc=10MHz,要求在P1.0腳上輸出周期為2.5μs,占空比20%.
#include
#define uchar unsigned char
uchar time;
uchar period=250;
uchar high=50;
void timer0( ) interrupt l using 1
{TH0= -8333/256;
TL0= -8333%256;
if(++time==high)P1=0;
else if(time==period)
{time=0; P1=1;}
}
void main(void)
{
TMOD=0x01;
TH0= -8333/256;
TL0= -8333%256;
EA=l;
ET0=1;
TR0=1;
do {)while(1);
}
#include
#define uchar unsigned char
#define uint unsigned int
uchar time,status,percent,period;
bit one_round;
uint oldcount,target=500;
void pulse(void) interrupt 1using l
{TH0= -833/256;
TL0= -833%256; ET0=l;
if(++time==percent)P1=0;
else if (time ==100)
{time=0;P2=l;}
void tachmeter(void) interrupt 2 using 2
{union {uint word;
struct{uchar hi;uchar lo;}byte; }newcount;
newcount_byte.hi=TH1;
newcount_byte.lo=TLl;
period=newcount.word--oldcounts;
oldcount=newcount.word;
one -round=1;
void main(void)
{IP=0x04;
TMOD=0x01;
TCON=0x54;
TH1=0;TL1=0;
IE=0x86;
for(;;)
{if(one_round)
{if(period
{if(percent0)
--percent;
}
}
}
串行口
8051系列單片機(jī)有一個(gè)標(biāo)準(zhǔn)的串行通信接口,發(fā)送數(shù)據(jù)時(shí)由TXD端口送出,接收數(shù)據(jù)時(shí)由RXD端口輸入.
內(nèi)置兩個(gè)緩沖器SBUF,一個(gè)接受緩沖器,另一個(gè)是接收緩沖器,可實(shí)行全雙工的串行通信.
近距離可直接用TTL電平,若與計(jì)算機(jī)通信,則需要將電平轉(zhuǎn)換成RS232電平形式,若需長距離通信可以采用RS485電平形式,通信的數(shù)據(jù)必須通過軟件的編寫來完成.
一,與串行口有關(guān)的SFR
1,串行口控制寄存器SCON
SM0 SM1 SM2 REN TB8 RB8 TI RI
D7 D6 D5 D4 D3 D2 D1 D0
. SM0,SM1:串行口工作方式控制位(見書P158).
. SM2:多機(jī)通信控制位(方式2,3);
1→只有接收到第9位(RB8)為1,RI才置位;
0→接收到字符RI就置位.
. REN :串行口接收允許位;
1→允許串行口接收;0→禁止串行口接收.
. TB8:方式2和方式3時(shí),為發(fā)送的第9位數(shù)據(jù),也可以作奇偶
校驗(yàn)位.
. RB8:方式2和方式3時(shí),為接收到的第9位數(shù)據(jù);方式1時(shí),
為接收到的停止位.
. TI:發(fā)送中斷標(biāo)志;由硬件置位,必須由軟件清0.
. RI:接收中斷標(biāo)志;由硬件置位,必須由軟件清0.
一,與串行口有關(guān)的SFR
2,電源控制寄存器PCON
SMOD
D7 D6 D5 D4 D3 D2 D1 D0
PCON的第7位SMOD是與串行口的波特率設(shè)置有關(guān)的選擇位.
. SMOD:串行口波特率加倍位.
1→方式1,3波特率=定時(shí)器1溢出率/16;方式2波特率為fosc/32;
0→方式1,3波特率=定時(shí)器1溢出率/32;方式2波特率為fosc/64.
二,串行口的工作方式
1. 方式0
方式0為移位寄存器輸入/輸出方式,串行數(shù)據(jù)通過RXD輸入/輸出 ,TXD則用于輸出移位時(shí)鐘脈沖.
方式0時(shí),收發(fā)的數(shù)據(jù)為8位,低位在前.波特率固定為fosc/12,其中fosc為單片機(jī)外接晶振頻率.
發(fā)送是以寫SBUF寄存器的指令開始的,8位輸出結(jié)束時(shí)TI被置位.
方式0接收是在REN=1和RI=0同時(shí)滿足時(shí)開始的.接收的數(shù)據(jù)裝入SBUF中,結(jié)束時(shí)RI被置位.
移位寄存器方式的也可用于兩個(gè)單片機(jī)之間的通信.和通常9600波特相比,lMHz通信能力對短距離通信很吸引人.
二,串行口的工作方式
2. 方式1
方式1是10位異步通信方式,1位起始位(0),8位數(shù)據(jù)位和1位停止位(1).其中的起始 位和停止位在發(fā)送時(shí)是自動(dòng)插入的.
任何一條以SBUF為目的寄存器的指令都啟動(dòng)一次發(fā)送,發(fā)送的條件是TI=0,發(fā)送完置TI為1;
方式l接收的前提條件是SCON中的REN為l,同時(shí)下列兩個(gè)條件都滿足,本次接收有效,將其裝入SBUF和RB8位.否則放棄接收結(jié)果.兩個(gè)條件是:(1)RI=0;(2)SM2=0或
接收到的停止位為1;
方式1的波特率是可變的,波特率可由以下計(jì)算公式計(jì)算得到: 方式1波特率=2SMOD.(定時(shí)器1的溢出率)/32
其中的SMOD為PCON的最高位.定時(shí)器1的方式0,1,2,都可以使用,其溢出率為定時(shí)時(shí)間的倒數(shù)值.
二,串行口的工作方式
3. 方式2和方式3
這兩種方式都是11位異步接收/發(fā)送方式,它們的操作過程完全一樣,所不同的是波特率:
方式2波特率=2SMOD.(fosc/64);
方式3波特率同方式1(定時(shí)器l作波特率發(fā)生器).
方式2和方式3的發(fā)送起始于任何一條"寫SBUF"指令,當(dāng)?shù)?位數(shù)據(jù)(TB8)輸出之后,置位TI.
方式2和方式3的接收前提條件也是REN為1.在第9位數(shù)據(jù)接收到后,如果下列條件同時(shí)滿足(1)RI=0;(2)SM2=0或接收到的第9位為1,則將已接收的數(shù)據(jù)裝入SBUF和RB8,并置位RI,如果條件不滿足,則接收無效.
三,串行口的初始化
在使用串行口之前,應(yīng)對它進(jìn)行編程初始化,主要是設(shè)置產(chǎn)生波特率的定時(shí)器1,串行口控制和中斷控制寄存器.具體步驟如下:
(1) 確定定時(shí)器1的工作方式——編程TMOD寄存器;
(2) 計(jì)算定時(shí)器1的初值——裝載TH1,TL1,具體TH1和
TL1的值可查表得到;
(3) 啟動(dòng)定時(shí)器1——編程TCON中的TR1位,即置TR1為1;
(4) 確定串行口的控制——編程SCON;
(5) 串行口在中斷方式工作時(shí),須開CPU和源中斷——編程IE寄存器.
四,串行口舉例1
#include 〈reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar idata trdata[10]=
{'M','C','S','-','5','1', 0x0d,
0x0a,0x00};
void main(void)
{ uchar i; uint j;
TMOD=0x20;
TL1=0xfd;TH1=0xfd;
SCON=0xd8;PCON=0x00;
TR1=1;
while(1)
{i=0;
while(trdata[i]!=0x00)
{SBUF=trdata[i];
while(TI==0);
TI=0; i++;
}
for (j=0;j
void main(void〉
{unsigned char a;
TMOD=Ox20;
TL1=0xfd;TH1=0xfd;
SCON=Oxd8;PCON=0x00;
TR1=1;
while (1)
{while (RI==0); RI=0;
a=SBUF; SBUF=a;
while (TI==O); TI=0;
}
}
#include 〈reg51.h〉
#define uchar unsigned char
uchar xdata r_buf[32];
uchar xdata t_buf[32];
uchar r_in,r_out,t_in,t_out;
bit r_full,t_empty,t_done;
code uchar m[]={"this is a test
program\r\n"};
serial( ) interrupt 4 using 1
{ifRI&&~r_full)
{ r_buf[r_in]=SBUF; RI=0;
r_in=++r_in&0xlf;
if(r_in==r_out) r_full=1;}
else if (TI &&~t_empty)
{SBUF=t_buf[t_out]; TI=0;
t_out=++t_out&0x1f;
if{t_out==t_in)t_empty=l;
else if(TI){TI=0;
t_done =1;
}
}
void loadmsg(uchar code *msg)
{ while((*msg!=0)&&((((t_in+1)^ t_out)&0xlf)!=0))
{ t_buf[t_in]= *msg; msg++;
t_in=++t_in&0x1f;
if(t-done){TI=1;
t_empty=t_done =0 ;}
}
}
void process(uchar ch){return;}
void processmsg(void)
{while(((r_out+1)^r_in)!=0)
{process(r_buf[r_out]);
r_out=++r_out&0x1f;}
}
void main()
{TMOD=0x20;TH1=0xfd;TCON=0x40;
SCON=0x50;IE=0x90;
t_empty=t_done =1;r_full=0;
r_out=t_in=t_out=l;r_in=1;
for(;;){loadmsg(&m);
processmsg();}
}