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