电子产业一站式赋能平台

PCB联盟网

搜索
查看: 12|回复: 0
收起左侧

串口(UART)自动波特率识别程序设计

[复制链接]

300

主题

305

帖子

1843

积分

三级会员

Rank: 3Rank: 3

积分
1843
发表于 2021-6-12 11:34:00 | 显示全部楼层 |阅读模式
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是嵌入式里串口(UART)自动波特率识别程序设计与实现
% ?0 [. U! w" B- n9 C0 a1 |1 @* `串口(UART)是嵌入式里最基础最常用也最简单的一种通讯(数据传输)方式,可以说是工程师入门通讯领域的启蒙老师,同时串口打印也是嵌入式项目里非常经典的调试与交互方式。
7 X# @+ d) Y0 X: k( l& D最精简的串口仅使用两根单向信号线:TXD、RXD,这两根信号线是独立工作的,因此数据收发既可分开也可同时进行,这就是所谓的全双工。串口没有主从机概念,并且没有专门的时钟信号 SCK,所以串口通信也属于异步传输。; C# r8 s2 {* _) G9 M+ U
说到异步传输,这就不得不提波特率(每秒钟传输bit数)的问题了,通信双方必须使用一致的波特率才能完成正确的数据传输。正常情况下,我们都是为两个串口设备事先约定好波特率,比如 MCU 与上位机通信,在 MCU 程序里按 115200 的波特率去初始化 UART 外设,然后上位机串口调试助手也设置 115200 波特率,双方再联合工作。
$ Y" M% K  ^: f. `有时候,我们也希望能有一种灵活的波特率约定方式,比如建立通信前,在上位机串口调试助手里随意设置一种波特率,然后按这个波特率发送数据,MCU 端能自动识别出这个波特率,并用识别出来的波特率去初始化 UART 外设,然后再进行后续数据传输,这种方式就叫自动波特率识别。痞子衡今天要分享的就是在 MCU 里实现自动波特率识别的程序设计:$ @+ N/ h1 S) W, q, V/ |: ]/ ]
  • 程序主页:https://github.com/JayHeng/cortex-m-apps/tree/master/components/autobaud一、串口(UART)自动波特率识别程序设计1.1 函数接口定义首先是设计自动波特率识别程序头文件:autobaud.h ,这个头文件里直接定义如下 3 个接口函数原型。涵盖必备的初始化流程 init()、deinit(),以及最核心的波特率识别功能 get_rate()。
    + m- q5 d" z6 r3 |4 ~//! @brief 初始化波特率识别
    # `, ~1 ~: Z  E3 V) Q6 Xvoid autobaud_init(void);! P# c3 v3 K3 V5 l4 I
    //! @brief 检测波特率识别是否已完成,并获取波特率值  a3 C9 W% W5 h/ k( [
    bool autobaud_get_rate(uint32_t *rate);
    # k" L+ B9 r3 k: L( {# j//! @brief 关闭波特率识别+ T& m* A, p) D0 r" t
    void autobaud_deinit(void);
    ' N" o+ B7 O' T2 L) w. N- x: l1.2 识别设计思想关于识别,因为上位机数据是从 RXD 引脚过来的,所以在 MCU 里需要先将 RXD 引脚配置成普通数字输入 GPIO(这个引脚需要上拉,默认保持高电平),然后检测这个 GPIO 的电平跳变(一般用下降沿)并计时。
    7 V  D" l+ P! s5 m0 @下图是典型的 UART 单字节传输时序,I/O 空闲状态是高电平,传输时总是由 1bit 低电平起始位开启,然后是从 LSB 到 MSB 的 8bit 数据位,校验位是可选项(我们暂不开启),最后由 1bit 高电平停止位结束,I/O 回归高电平空闲状态。
    ! ?0 g: E/ I% a# O; w% W' O
  • Note 1:检测下降沿跳变,是因为 I/O 空闲为高,起始位的存在保证了每 Byte 传输周期总是从下降沿开始。
  • Note 2:起始位和停止位两个 bit 的存在还兼有波特率容错的功能,通信双方波特率在 3% 的误差内数据传输均可以正常进行。
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表