电子产业一站式赋能平台

PCB联盟网

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

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

[复制链接]

355

主题

360

帖子

2833

积分

三级会员

Rank: 3Rank: 3

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

    使用道具 举报

    发表回复

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

    本版积分规则


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