单片机串口——如何判定接收一帧数据的完成

单片机串口接收不定长数据时,必须面对的一个问题为:怎么判断这一包数据接收完成了呢?常见的方法主要有以下两种:

1.在接收数据时启动一个定时器,在指定时间间隔内没有接收到新数据,认为数据接收完成;2.在数据中加入帧头、帧尾,通过在程序中判断是否接收到帧尾来确定数据接收完毕。这两种方法的缺点为,需要主程序来判断和处理,对主程序造成不小压力。

1)在串口接收的时候,有些通讯每一帧数据有帧头尾标识,这种情况比较好判定。但是也有些情况是,头尾没有固定的标识,也不知道一帧有多少字节,那么我们只能靠检测帧之间的间隔来判断是不是帧完成了。

例串口设置:9600波特率、8个数据位、1个停止位、无校验。

9600波特率表示,每秒传输9600个位,即每秒传输9600/(8位数据位+1位停止)=1066字节,

那么每秒传输一个字节的时间就是:1/1066=9.38*10^-4s≈0.94ms;

考虑硬件的损耗,保证数据传输的可靠性,留出余量,假设一个字节的传输时间为2ms。

例如波特率为9600,则说明每秒钟可以传输9600个二进制位,即传输一个二进制位需要的时间为1/9600秒。

那么我们就可以配置定时器,通过对时间的判断识别接收一帧未知长度的串口数据,

以定时2ms来说,当接收到一个字节的时候,我们打开定时器,开始计时,定时周期2ms。

如果过了2ms,没有新数据,那么我们认为一帧数据接收完成。

如果在2ms这个时间内,有新数据到来,那么我们认为是同一帧数据,此时定时器计数清零,重新计数。

初始化定义:一个足够大数组和一个记录字节数的变量。

3.使用单片机的串口空闲中断;
1)开启串口空闲中断;
2)在串口中断中判断是否是串口空闲中断,清除串口空闲中断的标志位。

### 51单片机串口通信实现英文字符和数据发送 #### 单片机串口初始化 为了使能51单片机串口功能,需先完成串口中断配置以及波特率设置。通常情况下,串口工作模式被设定为方式1(8位异步通信),并利用定时器T1作为波特率发生器[^1]。 以下是典型的串口初始化函数代码示例: ```c void uart_init() { TMOD |= 0x20; // 设置T1为模式2自动重装载 TH1 = 0xFD; // 波特率为9600bps, fosc=11.0592MHz SCON = 0x50; // 串口工作于方式1,允许接收 TR1 = 1; // 启动T1计数器 } ``` 上述代码中`TH1`寄存器用于定义波特率分频值,而`SCON`控制寄存器则设定了串口的工作模式及其基本属性。 #### 字符与字符串发送 对于简单的英文字母或ASCII码范围内的数值传输,可以调用专门设计好的子程序来逐字节处理待发的数据流。下面分别展示单独字符及整条消息传送的方法[^2]: - **单一字符发送** ```c void uart1_sendByte(unsigned char byte){ while(!TI); // 等待上一次发送结束 TI = 0; SBUF = byte; // 将要发送的数据放入SBUF缓冲区 } ``` 此部分逻辑等待直到前一帧完全送出后再加载新的目标值到移位寄存器里去。 - **字符串发送** 当需要连续传递多段信息时,则可循环调用前述基础单元操作构成更高级别的封装形式如下所示: ```c void uart1_sendstring(unsigned char *str){ unsigned int i=0; while (*(str+i) != '\0') { // 判断当前指针位置是否到达终止标志'\0' uart1_sendByte(*(str+i)); // 调用单字节发送函数 delay_ms(1); // 延迟一定时间防止冲突 i++; } } ``` 这里引入了一个额外延时环节以确保每轮交互之间留有足够的间隔避免潜在干扰现象的发生。 #### 数值转换成字符串再发送 如果打算把某些变量比如温度传感器读取结果之类的量化指标也纳入输出序列当中的话,那么就需要先把它们转化为对应的文本表达形式然后再按照前面介绍过的流程执行下去。例如针对无符号八比特整形参数的情况我们可以这样写: ```c void uart1_sendnum(unsigned char num1){ char buffer[4]; itoa(num1,buffer,10); uart1_sendstring(buffer); } ``` 其中运用到了标准库里的itoa函数负责完成从数字至相应进制编码下的字符串映射过程。 综上所述,借助以上几个核心组件即可轻松达成基于51系列MCU平台之上与其他设备间的基础级资料交换需求了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值