「51單片機(jī)」RS232串口通信代碼分析
想來想去不知道要怎么樣把232串口通信說清楚,想想還是直接把代碼分析一遍吧...
重點(diǎn)是“常用波特率與定時器1的參數(shù)關(guān)系”這張表格!波特率的設(shè)置很重要!
一、串口初始化
void usart_init()
{
SCON = 0x50; //REN=1允許串行接受狀態(tài),串口工作模式1
TMOD = 0x20; //定時器工作方式2
PCON = 0x00;
TH1 = 0xFD; //波特率9600、數(shù)據(jù)位8、停止位1。效驗(yàn)位無 (11.0592M)
TL1 = 0xFD;
ES = 1; //開串口中斷
EA = 1; //開總中斷
TR1 = 1; //啟動定時器
}
SCON寄存器
1.SM0、SM1:串行口工作方式控制位
2.SM2:多機(jī)通信控制位
3.REN:允許接收位
4.TB8:發(fā)送接收數(shù)據(jù)位8
5.RB8:接收數(shù)據(jù)位8
6.TI:發(fā)送中斷標(biāo)志位TI=1表示幀發(fā)送結(jié)束
7.RI:接收中斷標(biāo)志位RI=1表示幀接收完成
1.GATE:門控制位GATE=0,僅受TRX控制GATE=1,受TRX和外部中斷引腳共同控制
2.C/T:定時器模式和計(jì)數(shù)器模式選擇器C/T=1,計(jì)數(shù)器C/T=0,定時器
3.M1、M0:工作方式選擇位
PCON寄存器
SMOD:是波特率是否加倍的選擇位。
SMOD=0時:波特率不加倍。
SMOD=1時:波特率加倍。
二、串口數(shù)據(jù)發(fā)送
void send_data(unsigned char a)
{
SBUF = a; //SUBF接受/發(fā)送緩沖器
while(0 == TI); //每次等待發(fā)送完畢,再執(zhí)行下一條
TI=0; //手動清0
}
SBUF:有兩個物理上獨(dú)立的接收、發(fā)送緩沖器SBUF,它們占用同一地址99H ;接收器是雙緩沖結(jié)構(gòu) ;發(fā)送緩沖器,因?yàn)榘l(fā)送時CPU是主動的,不會產(chǎn)生重疊錯誤。
TI:發(fā)送中斷標(biāo)志位 TI=1表示幀發(fā)送結(jié)束
三、串口中斷程序
void ser_int (void) interrupt 4 using 1
{
if(1 == RI) //RI接受中斷標(biāo)志
{
RI = 0; //清除RI接受中斷標(biāo)志
ReData = SBUF; //SUBF接受/發(fā)送緩沖器
Flag=1; //標(biāo)志位置1表示有新數(shù)據(jù)進(jìn)來
}
}
RI:接收中斷標(biāo)志位 RI=1表示幀接收完成
四、總代碼
#include
//變量聲明
unsigned char SenData, //發(fā)送數(shù)據(jù)
Flag, //標(biāo)志位
ReData; //接收數(shù)據(jù)
//函數(shù)聲明
void usart_init(); //串口中斷初始化
void send_data(unsigned char a); //串口數(shù)據(jù)發(fā)送
//---------------------------
//串口中斷初始化
//---------------------------
void usart_init()
{
SCON = 0x50; //REN=1允許串行接受狀態(tài),串口工作模式1
TMOD = 0x20; //定時器工作方式2
PCON = 0x00;
TH1 = 0xFD; //波特率9600、數(shù)據(jù)位8、停止位1。效驗(yàn)位無 (11.0592M)
TL1 = 0xFD;
ES = 1; //開串口中斷
EA = 1; //開總中斷
TR1 = 1; //啟動定時器
}
//---------------------------
//串口數(shù)據(jù)發(fā)送
//---------------------------
void send_data(unsigned char a)
{
SBUF = a; //SUBF接受/發(fā)送緩沖器
while(0 == TI); //每次等待發(fā)送完畢,再執(zhí)行下一條
TI=0; //手動清0
}
//---------------------------
//串口中斷程序
//---------------------------
void ser_int (void) interrupt 4 using 1
{
if(1 == RI) //RI接受中斷標(biāo)志
{
RI = 0; //清除RI接受中斷標(biāo)志
ReData = SBUF; //SUBF接受/發(fā)送緩沖器
Flag=1; //標(biāo)志位置1表示有新數(shù)據(jù)進(jìn)來
}
}
//---------------------------
//主函數(shù)
//---------------------------
void main()
{
usart_init(); //串口中斷初始化
while(1)
{
if (Flag==1) //判斷是否有數(shù)據(jù)過來,有則進(jìn)入循環(huán)
{
EA=0; //進(jìn)入循環(huán)之后就把總中斷關(guān)閉,防止處理過程中又有中斷進(jìn)來
//----------------------該段即對接收的數(shù)據(jù)進(jìn)行處理
if(ReData=='a')
SenData = 'b';
else
SenData = 'c';
send_data(SenData); //串口數(shù)據(jù)發(fā)送
//----------------------
Flag=0; //數(shù)據(jù)處理完畢后將標(biāo)志位置0,表示沒有新數(shù)據(jù)要處理
EA=1; //打開總中斷,允許接收新數(shù)據(jù)
}
}
}