manhuami2007的个人空间 https://bbs.21ic.com/?741514 [收藏] [复制] [RSS]

日志

串口使用超时判断接收数据帧

已有 732 次阅读2017-1-29 08:23 |系统分类:ARM| stm32, uart, usart, 串口, 超时

"配合定时器中断,通过超时的方法,完成串口数据帧的接收。"

在嵌入式设计中,经常使用串口(UART)接收数据。通常我们接收数据使用串口中断函数,通过判断帧格式来确定接收到一个完整的帧。

这种方法有个缺点:当帧尾丢失,可能造成长时间等待,直到收到下一个数据帧的结尾才能停止。这样会造成接连的两个数据包接收错误。

image


但是配合定时器中断进行通讯的超时判断,可以解决包尾丢失的问题。不过这种方法适用于通讯不紧凑的情况。也就是每帧数据间隔时间需要长些。具体有多长,以115200的波特率为例,帧与帧的间隔最好大于3ms。


数据结构

使用的数据结构是

typedef struct
{
    uint8_t* buf;   //指向接收缓存区
    uint16_t length;    //接收的数据长度
    uint16_t state;     //一帧数据是否接收完成
    uint16_t timer;     //在定时器中断中,用于倒计时,判断是否超时

    uint16_t max_count_down_value;  //超时判断的时间,如3ms
    uint16_t buf_max_length;    //buf缓冲区的长度
}UartDataStruct

函数

共使用3个函数:

  1. 数据结构的初始化 uart_struct_init()

  2. 串口接收中断中的函数 uart_rx_IRQ_handler()

  3. 定时器中断中的函数   uart_timer_IRQ_handler()

流程图如下

首先初始化数据结构中的变量 uart_struct_init()


image


然后在相应串口的接收中断中添加函数 uart_rx_IRQ_handler()

函数流程图如下:


image


最后在定时器中断中添加函数 uart_timer_IRQ_handler() 。定时器最好是将周期设置成1ms,或者使用滴答中断。

函数流程图如下:


image


通过判断uart_timer_IRQ_handler()的返回值是否为0,得到是否接收到1个完整的数据帧。


总结

当然也可以单纯的使用超时判断的方法接收串口数据,等待一帧数据接收完成之后对数据进行处理。通过这种方法能够简化串口中断的处理程序,摆脱了帧格式的束缚。不过这个方法也有缺点,就是实时性较差,需要延时3ms才能得到完整的数据帧。因此,在使用中要根据情况选择不同的方法。

欢迎大家添加我的微信公众号“光豆儿”


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)