zoukankan      html  css  js  c++  java
  • 51单片机串口通信(字符串接收和发送)

    转自:http://www.cnblogs.com/weifeng727/category/845655.html


    #include<reg52.h>
    
    //------------------串口通信协议-----------------//
    /*
        客户端数据包格式解释(长度恒为15):
        例如:A01_fmq_01Off___#
        A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种)
        01-----设备代号
        fmq_01Off___--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部
        #---------数据包的结束标记
    
        服务器端数据包格式解释(长度恒为15):
        例如:A02_SenT010250#
        A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种)
        02-----设备代号
        SenT010250--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部
        #---------数据包的结束标记
    */
    char buf_string[16];  //定义数据包长度为15个字符
    #define deviceID_1Bit '0'                //用于串口通信时,定义本地设备ID的第1位
    #define deviceID_2Bit '2'                //用于串口通信时,定义本地设备ID的第2位
    #define datapackage_headflag 'A'        //用于串口通信时,定义数据包头部的验证标记
    
    char DataPackage_DS18B20[16]={datapackage_headflag,deviceID_1Bit,deviceID_2Bit,'_','S','e','n','T','X','X','X','X','X','X','#'};
    char HeartBeat[16]={datapackage_headflag,deviceID_1Bit,deviceID_2Bit,'_','B','e','a','t','X','X','X','X','X','X','#'};
    //----------------------------------------------//
    /*******************************
                串口通信
        MCU:89C52RC        11.0592MHz
    
    //11.0592MHz 0xd0 1200bps
    //12MHz 0xcc 1200bps
    //11.0592MHz 0xfa 9600bps
    //0xf4 11.0592MHz  0xf3 12MHz 4800bps
    //均在SMOD=1的情况下(波特率倍增模式)
    *******************************/
    //串口发送函数
    void PutString(unsigned char *TXStr)  
    {                
        ES=0;     
         while(*TXStr!=0) 
        {                      
            SBUF=*TXStr;
            while(TI==0);
            TI=0;    
            TXStr++;
        }
        ES=1; 
    }                                                     
    //串口接收函数
    bit ReceiveString()    
    {
        char * RecStr=buf_string;
        char num=0;
        unsigned char count=0;
        loop:    
        *RecStr=SBUF;
        count=0;
        RI=0;    
        if(num<14)  //数据包长度为15个字符,尝试连续接收15个字符
        {
            num++;
            RecStr++;    
            while(!RI)
            {
                count++;
                if(count>130)return 0;    //接收数据等待延迟,等待时间太久会导致CPU运算闲置,太短会出现"数据包被分割",默认count=130
            }
            goto loop;
        }
        return 1;
    }
    //定时器1用作波特率发生器
    void Init_USART()  
    {
        SCON=0x50;  //串口方式1,使能接收
        TMOD|=0x20;  //定时器1工作方式2(8位自动重装初值)
        TMOD&=~0x10;
        TH1=0xfa;   //9600bps
        TL1=0xfa;  
        PCON|=0x80;  //SMOD=1
        TR1=1;
        TI=0;
        RI=0;
        //PS=1;   //提高串口中断优先级
        ES=1;  //开启串口中断使能
    }
    //比较指令头部
    bit CompareCMD_head(char CMD_head[])    
    {
        unsigned char CharNum;
        for(CharNum=0;CharNum<4;CharNum++)  //指令长度为10个字符
        {
            if(!(buf_string[CharNum+4]==CMD_head[CharNum]))
            {
                return 0;  //指令头部匹配失败
            }
        }
        return 1;        //指令头部匹配成功
    }
    //比较指令尾部(start:从哪里开始比较,quality:比较多少个字符,CMD_tail[]:要比较的字符串)
    bit CompareCMD_tail(unsigned char start,unsigned char quality,char CMD_tail[]) 
    {
        unsigned char CharNum;
        for(CharNum=0;CharNum<quality;CharNum++)
        {
            if(!(buf_string[start+CharNum]==CMD_tail[CharNum]))
            {
                return 0; 
            }
        }
        return 1;
    }
    bit Deal_UART_RecData()   //处理串口接收数据包函数(成功处理数据包则返回1,否则返回0)
    {
        //PutString(buf_string);
        if(buf_string[0]==datapackage_headflag&&buf_string[14]=='#')  //进行数据包头尾标记验证
        {        
            switch(buf_string[1])        //识别发送者设备ID的第1位数字
            {
                case '0':
                    switch(buf_string[2])        //识别发送者设备ID的第2位数字
                    {
                        case '3':
                            if(CompareCMD_head("Ligt"))    //判断指令头部是否为"Ligt"
                            {
                                //下面是指令尾部分析
                                switch(buf_string[8])
                                {
                                    case '0':
                                        switch(buf_string[9])
                                        {
                                            case '0':            
                                                
                                                return 0;
                                            case '1':
                                                if(CompareCMD_tail(10,3,"Off"))   //A03_Ligt01Off_#
                                                {
                                                    //要执行的代码
                                                    return 1;
                                                }
                                                if(CompareCMD_tail(10,3,"On_"))
                                                {
                                                    
                                                    return 1;
                                                }
                                                return 0;
                                            default:
                                                return 0;
                                        }
                                    case '1':
                                        
                                    default:
                                        return 0;
                                }            
                            }
                            if(CompareCMD_head("SenT"))  
                            {
                                            
                                
                            }
                            if(CompareCMD_head("jdq_"))  
                            {
                                
                                
                            }
                            if(CompareCMD_head("Try!"))  
                            {
                                
                                
                            }
                            return 0;
                        
                        default:
                            return 0;
                    }
                default:
                    return 0;
            }
        }
        return 0;
    }
    /************************
            中断函数
    ************************/
    //串口中断服务函数-----------
    void USART() interrupt 4   //标志位TI和RI需要手动复位,TI和RI置位共用一个中断入口
    {
        if(ReceiveString())    
        {
            //数据包长度正确则执行以下代码
            Deal_UART_RecData();   
        }
        else
        {
            //数据包长度错误则执行以下代码
            //LED1=~LED1;                
        }
        RI=0;  //接收并处理一次数据后把接收中断标志清除一下,拒绝响应在中断接收忙的时候发来的请求
    }
    /***************************
            主函数
    ***************************/
    void main()
    {
        EA=1;
        Init_USART();
        while(1)
        {
            //PutString(buf_string);//空格20H,回车0DH
            
        }
    }


  • 相关阅读:
    amaze(妹子~) 好像挺好玩
    php 获取图片base64编码格式数据
    一些laravel博文
    微信移动端(wap)开发调试工具
    深入理解控制反转(IoC)和依赖注入(DI)
    使用 composer 下载更新卸载类库
    ionic ui 框架
    laravel 添加 404 页面
    laravel 调试模式及日志配置
    iOS-方法之+ initialize 与 +load
  • 原文地址:https://www.cnblogs.com/alan666/p/8312112.html
Copyright © 2011-2022 走看看