找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 382|回复: 0
打印 上一主题 下一主题
收起左侧

校验和串口通信

[复制链接]
跳转到指定楼层
楼主
ID:299910 发表于 2025-3-18 15:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "STC15W4K.H"          // 包含 "STC15W4K.H"寄存器定义头文件

#define FMBEGIN 0x7e           // 帧头标志   

unsigned char RecCount;                   // 串口接收计数器,全局变量在没有赋值以前系统默认为0.

unsigned char RecBuf[5];            // 接收缓冲区(数据长度:帧头+3字节数据+校验和)

unsigned char SendBuf[5];            // 发送缓冲区(数据长度:帧头+3字节数据+校验和)

/*********************************************/

//描述:串口初始化函数,使用T1方式2自重载方式做波特率发生器

void UART_init(void)

{                  

        // 下面代码设置定时器1

        TMOD = 0x20;        // 0010 0000 定时器1工作于方式2(8位自动重装方式)

        TH1  = 0xFA;        // 波特率:9600 /22.1184MHZ

        TL1  = 0xFA;        // 波特率:9600 /22.1184MHZ

        TR1  = 1;

        // 下面代码设置定串口

        AUXR = 0x00;             // 很关键,使用定时器1作为波特率发生器,S1ST2=0

        SCON = 0x50;         // 01010 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允许接受)

        // 下面代码设置中断

        ES   = 1;                // 关键:开启了中断就必须编写相应的中断函数,哪怕是中断空函数,

                        // 但必须有,否则程序进入中断入口地址后(这里是0023H)不能跳出,必然出错

        EA   = 1;

}

/*********************************************/

//发送一帧完整数据

void sendcombytes(unsigned char *ptr, unsigned char len)

{  

        unsigned char i;        

        for(i=0;i<len;i++)

        {

                SBUF=*(ptr+i);         

                while(TI==0);

                TI=0;

        }        

}

/*********************************************/

// 串口 中断服务程序

void UART1(void) interrupt 4

{

        if(RI)                              // 只处理接收中断

        {

                if(RecCount==5) RecCount=0; //如果已经接收了5个字符,主程序还没来得及处理又发来下一帧数据

                                            //则RecCount清零,覆盖上一帧数据,保证数据接收不错位

                RecBuf[RecCount]=SBUF;

                RI=0;                          

                if (RecCount==0)                // 判断帧头是否正确

                {

                        if(RecBuf[RecCount]==FMBEGIN)

                        {

                                RecCount++;

                        }

                        else

                        {

                                RecCount=0;

                        }

                }

                else

                {

                        RecCount++;

                }

        }

}

/*********************************************/

unsigned char CheckSum(unsigned char *ptr, unsigned char len)

{

           unsigned char i;

        unsigned char a;         

        unsigned int Value=0;

        for(i=0;i<len;i++)  // len结束后第一个字节为接收到的校验和

        {

                Value = Value + ptr;   

        }

        a=Value;            // 长送短,传送完整低字节

        return(a);

}

/*********************************************/

void main(void)

{

        unsigned char i;               

        unsigned char CheckValue;          // 校验结果

        UART_init();                              // 串口初始化        

        while(1)

        {                       

                if(RecCount==5)    // RecCount是全局变量,表示串口已收到的字节数

                {         

                        RecCount=0;                                       

                        CheckValue=CheckSum(RecBuf,4);    // 接收缓冲区4字节校验(第5字节例外)               

                        if(CheckValue==RecBuf[4])         // 如果校验正确,数据加1后发回。

                        {                                 

                                P00=!P00;

                                SendBuf[0]=FMBEGIN;

                                for(i=1;i<4;i++)                          // 1、2、3、4、5字节中2、3、4为数据

                                {

                                         SendBuf=RecBuf+1;

                                }

                                CheckValue=CheckSum(SendBuf,4);  // 1、2、3、4 字节参与校验

                                SendBuf[4]=CheckValue;

                                sendcombytes(SendBuf,5);

                        }

                        else                                                          // 接收校验错误,发回帧头 + 4个aa。

                        {

                                SendBuf[0]=FMBEGIN;

                                for(i=1;i<5;i++)                          // 1、2、3、4、5字节中2、3、4、5为数据

                                {

                                         SendBuf=0xaa;

                                }

                                sendcombytes(SendBuf,5);

                        }                       

                }

        }  

}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表