「51單片機」RS232串口通信代碼分析


想來想去不知道要怎么樣把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.SM0SM1:串行口工作方式控制位

 

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.M1M0:工作方式選擇位

 

 

                                                        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;                   //打開總中斷,允許接收新數據
        }        
    }        
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM