电子产业一站式赋能平台

PCB联盟网

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

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

[复制链接]

359

主题

364

帖子

2891

积分

三级会员

Rank: 3Rank: 3

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

    使用道具 举报

    发表回复

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

    本版积分规则


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