• 「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;                   //打开总中断,允许接收新数据
            }        
        }        
    }
  • 相关阅读:
    Vue Supermall蘑菇街API后端接口
    Vue UI库:ElementUI使用教程
    Python操作数据库,读取数据并按照json格式写入json文件
    css 轮播图
    ArcGIS Server密码重置
    JavaScript之箭头函数
    arcgis属性对比
    JavaScript之Promise
    很遥远
    请不要等到四十年后才明白
  • 原文地址:https://www.cnblogs.com/Donut/p/4047240.html
Copyright © 2020-2023  润新知