理解第一个通信模块串口

发布时间:2026/10/16 9:36:08
理解第一个通信模块串口 USART 串⼝本章节主要介绍 UART 串⼝ 的基础知识涉及 STM32 USART 相关知识部分可以参考《STM32F10xxx参考⼿册_CN.pdf》第 25 章节。 本节⽬标• 掌握通信领域常⻅概念⽐如串⾏并⾏、同步异步通信、1对1、1对多、全双⼯和半双⼯• 理解串⼝、MCU、GPIO、板⼦四⽅关系使⽤GPIO复⽤模式• 深刻理解⽐特率和波特率• 递进式理解串⼝通信、掌握USART帧格式• 深刻掌握USART原理完成USART阻塞式发送和接收的理论理解• 掌握USART常⻅寄存器标志位结合标志位理解USART通信详细过程1. 什么是 UART UART Universal Asynchronous Receiver/Transmitter 是⼀种叫做 “ 通⽤异步收发器 ” 的硬件电路⽤于设备间的串⾏通信即数据按位顺序逐次传输 ⼀次传输 1 位数据可以按照需求发送多次 。初步说明⼀下这⾥为什么是UART⽽不是USART重点记忆这里的串行异步全双工通用这是通信的基本精致和特征2. 初步理解UART定义2.1 UART接线UART 由 2 根数据线和⼀根地线组成。2 根数据线分别是 Tx ⽤于发送数据。 Rx ⽤于接收数据。其实还有⼀些其他的线但现在很少使⽤了不再介绍。这⾥缺少⼀个UART通过⾼低电平来传递信息的图。UART 是⽤来进⾏设备间通信的就如同⼈和⼈、猫和猫、狗和狗之间通信⼀样 UART 模块⼀般也是和另⼀个 UART 模块进⾏通信那么接线上可以如下设置• Tx 接对端 Rx Rx 接对端 Tx 构建双向通信的信道• 通信双⽅ GND 都接地或者叫做接⼊公共地• 上述过程细节对通信双⽅都有效即通信双⽅没有主从概念地位是对等的。实现了点对点的通信Tx/Rx中T、R分别表⽰“Transmit”发送和“Receive”接收)• x表⽰什么市⾯上说法不⼀我们把他理解成为exchange交换就可以了• 为了快速记忆x⾮常像 UART 的接线结果这样接⼊之后双⽅就可以互相进⾏通信了。 基本过程如下USART极简收发.ppt2.2 UART核⼼特点串⾏通信• 异步通信• 1 对 1 通信• 全双⼯通信关于 UART 串⼝ 的这些特点对于初学者⽽⾔可能⽐较陌⽣在继续学习UART之前我们⾸先以通俗易懂的⽅式分别对上述特点及其周边进⾏⼀下理论补充。2.2.1 串⾏ vs 并⾏如果设备间要进⾏通信从物理形式上通信基本可以分为两种并⾏通信和串⾏通信• 并⾏通信同时使⽤多条数据线如 8 条、 16 条、 32 条来传输⼀个数据字节 或半字、字 的所有位。如图中的 8位数据并⾏传输 ⽰意图⼀次性会传递完 8 位数据。并⾏通信的明显缺点• 成本⾼线多PCB布线难、接⼝插件贵• 速率受限所有数据位必须同时有效才能被正确采样但物理上⽆法做到绝对同步为了尽量同步时钟就必须慢⼀些给没有到达的信号⾜够时间。• 距离短串扰严重仅限板级通信• 扩展性差位宽升级必须改硬件连线 • 功耗⼤名词解释• 位0或1最⼩单位• 字节8位存⼀个字⺟/数字• 半字16位2字节STM32的 uint16_t• 字32位4字节STM32的 uint32_t CPU⼀次处理的⼤⼩并行通信虽然方便但是成本高但实用性不高成本价格昂贵串⾏通信只使⽤⼀条 或⼀对 数据线将数据字节的各 bit 按照时间顺序⼀ bit 接⼀bit 地依次传输。如图中的 8位数据串⾏传输 ⽰意图 8 位数据会分 8 次按位依次传输。串口是典型的低位先行的串行通信UART 发送、接收都只有 1 根信号线所以数据发送、接收都只能是串⾏⽅式。在 STM32 通信领域串⾏通信成本低速率⾼扩展性好功能低等优势让它成为主流实际 应⽤中串⾏类通信占绝对主导地位。注意• 串⾏ ! UART串⼝• 像 SPII2C, CAN, UART 等都是采⽤串⾏通信的主流通信技术• UART 串⼝只是串⾏通信的⼀种具体技术2.2.2 同步通信 vs 异步通信同步通信如 下图 中同步通信所⽰在时钟的下降沿(或者上升沿)对数据进⾏采样 ( 读取 ) 这就是同步通信使 ⽤时钟的边沿进⾏数据收、发同步如⽰意图中的波形就可以准确的解析为 11110000 ⼆进制数据 (下降沿采集)异步通信如下图中异步通信⽰意图所⽰传输信号中没有时钟信号 UART 就是这样的 那应该怎样才能识别输⼊数据波形表⽰的是 11110000 、 1100 、 10 、 ... 等哪种⼆进制情况呢这就需要通过通信收、发端约定的每⼀个数据位占⽤的时间 T 来区分 ( 如图中绿⾊分割线等分 ) 每⼀个数据位对于 UART ⽽⾔这就是波特率。光约定每⼀个数据位占⽤的时间还是不够的还需要知道从什么时刻开始等间隔截取数据需要截取多少位数据这就是需要数据帧格式来完成的⼯作关于 波特率、数据帧格式等话题我们后续会详细介绍此处重点是理解异步通信。总结通过上图我们可以发现同步通信比异步通信实际上多了一条时钟线他是用来约束传输速率的收发方有相同的速率异步通信就需要双方配置相同的波特率才能实现相同的效果多以同步通信是要依赖于时钟源的。UART 并没有⼀个⽤于同步的时钟信号因此 UART 是异步通信⽅式 A : asynchronous 异步 。 结论• stm32 中区分同步通信还是异步通信只看有没有时钟线 就可以判断出来这⾥暂留⼀个问题问什么通信的时候会存在同步通信和异步通信他们各⾃的本质是什么这个 我们后续回答。2.2.3 1对1通信 vs 1对多1 对 1 这个很好理解朴素的说就是串⼝单元只能和另⼀个串⼝单元通信不能⼀个串⼝单元和多个 串⼝单元通信。后续我们还会⻅到⼀个主设备可以和多个从设备通信的场景⽐如 I2C 或者 SPI 等后续再说。2.2.4 全双⼯ vs 半双⼯全双⼯可以同时双向传输 A → B 且 B → A 。如下图中的全双⼯⽰意图所⽰可以同时⾛红⾊和蓝⾊传输路径传输数据。简单来说就是发送和接受用的不是同一根线半双⼯可以双向传输但⼀次只能⼀个⽅向 A → B 或 B → A 。如下图中的半双⼯⽰意图所⽰同⼀时刻要么⾛红⾊传输路径要么⾛蓝⾊传输路径。单⼯只能单向传输 A → B B → A ⼆选⼀。如图中的单⼯⽰意图所⽰只有⼀条传输路径。秒理解• 半双⼯就是我们⼈类正常沟通我说你听。你说我听• 全双⼯就是我们⼈类吵架你说你的我说我的互相问候输⼊输出同时进⾏• 单双⼯就是吵架吵输了我不说了你说你的UART 有独⽴的发送 ( Tx )、接收 ( Rx ) 信号线因此可以同时进⾏数据发送与接收也就是全双⼯的通信⽅式。但是基于 UART 扩展⽽来的 RS-485 通信⽅式确是半双⼯通信⽅式此处我们说明⼀下3. MCU和串⼝3.1 串⼝属于MCU⽚上外设在 STM32 对应的 MCU 中为了让 MCU 能进⾏串⼝通信进⽽能获取或者和板级外设或者上位机通信的能⼒即让 MCU 和其他串⼝设备进⾏通信的能⼒ MCU 的设计者⽐如意法都会在对应的 MCU 内部内置串⼝模块。下⾯是 STM32 系列 MCU 的内部结构框图很明显串⼝是以⽚上外设的形式接⼊到 MCU 的 APB总线上的。所谓未来整个 MCU 要进⾏串⼝通信都由⽚上外设 USART* 来完成。所以我们后⾯研究串⼝通信都是我们的 MCU 通过⾃⼰的⽚上 USART 在和MCU外部的串⼝设备进 ⾏通信。类似于⽹卡和⽹卡通信但是⽹卡属于你的电脑你的电脑需要上⽹就给⾃⼰的电脑内 置⽹卡使⽤⽹卡的联⽹功能。可是为什么是 USART 难道不是 UART 吗3.2 UART 和 USART⼤家⼀定注意到了 STM32 参考/数据⼿册中都是 USART 不是我们⼀直说的 UART 。这两个名词的全称如下• UART Universal asynchronous receiver transmitter 。翻译过来就是通⽤异步收发器。• USART Universal synchronous asynchronous receiver transmitter 。 翻译过来就是通⽤同步、异步收发器。所以 USART 的功能要⽐ UART 的功能更强⼤因为 USART 多了⼀个同步 synchronous 功能。这个同步功能⼤概是怎么回事呢如 下图 所⽰ STM32 MCU 可以给 UART 额外提供⼀根时钟线以实现双⽅数据同步传输模式。但是这种同步⽅式的串⼝应⽤场景⾮常罕⻅⼏乎不⽤此处只做了解。所以如果忽略掉 USART 的同步通信功能那么 USARTUART . 注意• 区分同步异步看有没有时钟线即可• 从现在开始因为不⽤USART同步功能那么USART 就是 UART后续表述中我统⼀使⽤USART因为我们的MCU⽤的是USART3.3 4⽅关系两个GPIO口选择的是复用推挽输出细节• USART直接复⽤GPIO就可以通过MCU引脚对外输出信号也就是未来我们配置USART就⼀定会配套要有GPIO的配置具体更多细节后续介绍3.4 MCU 和 USART 设备通信的宏观过程和问题如下图所⽰使⽤ USART 进⾏通信的设备之间⽤ Tx 要和 Rx 交叉相连意思就是⼀端发送、⼀ 端接收。此处是 MCU 内部的 USART 模块和外部的 USART 设备之间进⾏通信。宏观数据传输流程如下1. 发送端 ( Tx ) 发送⼆进制数据 ‘ 1 ’ 时输出⾼电平2. 接收端 ( Rx ) 读取到⾼电平时代表得到⼆进制数据 ‘ 1 ’ 3. 发送端 ( Tx ) 发送⼆进制数据 ‘ 0 ’ 时输出低电平4. 接收端 ( Rx ) 读取到低电平时代表得到⼆进制数据 ‘ 0 ’ 5. 数据会按顺序拆分成⼀个⼀个的数据位并依次进⾏发送和接收。✨ ⽰例(以MCU端发送为例)假定 MCU 要传输 1 个字节的数据 0x55 ⼆进制序列为“ 0101 0101 ”1. 发送端依次输出以下电平序列 ⾼ 、 低 、 ⾼ 、 低 、 ⾼ 、 低 、 ⾼ 、 低 (为什么要直接解释)2. 接收端依次读取到电平序列 ⾼ 、 低 、 ⾼ 、 低 、 ⾼ 、 低 、 ⾼ 、 低 就代表接收到了⼆进制数“ 0101 0101 ”。但是上述的通信过程看似可⾏实则不⾏主要有以下 2 个问题• 通信双⽅发送和接收数据快慢的问题接收端怎么知道发送端什么时间开始或结束数据发送的⼀次计划携带多少数据后续讲解的 “ 波特率 ” 和 “ 帧格式 ” 就是为了解决这两个问题这两个我们⻢上说明。❓ 在继续讲解之前我们先来在沟通⼀下关于通信约定的话题。要真正通信必须要求通信 双⽅都要采⽤相同的规则• ⼈和⼈通信双⽅都要说中⽂不要说外语都说普通话不要说⽅⾔那么我们两个⼈要通信就都必须遵守这个规则。• 设备间通信未来也有通信的规则⽐如每秒收发的数据量⼀次发多少哪⾥开始哪⾥结束等等都是通信双⽅都要遵守的规则• 只有⼤家都遵守提前约定好的规则才能互相理解彼此完成通信过程结论• ⽆论未来设备怎么通信参与通信的设备间约定好的规则⼤家都要遵守。• 这点 USART 是这样未来其他通信⽅式也是如此。4. ⽐特率 vs 波特率通信双⽅发送和接收数据快慢的问题在 USART 中是受到波特率影响的。所以我们⾸先得补充⼀批新概念。4.1.1 ⽐特率说⼀个程序员容易搞混普通⼈不懂的常识。家⾥⾯的千兆带宽这⾥的兆指的是什么呢答案是⽐特率(Bit Rate)。 ⽐如 1000Mbit/s (注意这 ⾥是 Mb 不是 MB 哦), ⼀般含义是我们家的⽹络端⼝每秒最⼤可以接收的 0,1 ⽐特的数量是 1000*10^6 个⽐特。很明显每秒传送的⽐特数量越多单位时间内传递的信息就越多⽹速就快。⽐特率是每秒钟传送的⽐特位的个数也叫做传信率侧重点在传递有效信息的速度上。⽐特率单位是 bit/s 或者 bps(bits per second) 。我们常⻅的描述⽐特率的单位有 Kbit/s,Mbit/s, Gbit/s, 这⾥的 K、M、G 分别表⽰ 1000(10^3)、1000000(10^6)、1000000000(10^9) 。 注意• ⼆进制计算机领域 1Kbit2^10bit1024bit 1M2^201024*1024bit ,1G2^301024*1024*1024bit 。⽐如⼀张图⽚⼤⼩是 2KB 实际⼤⼩是2*1024*8 其中 K1024Bbyte8bit• ⽽上述描述中⽐特率表⽰的是数据传输的速度单位间的关系换算是 10 进制的。⽐如10Kbit10*1000bit 。⽐如你拿到 offer 薪资是 20K 实际是20*10002w ⽽不是 20*1024 。所以⽇常别⼈告诉我给我们安装⼀个 1000Mbit/s 的带宽时 bit 转换为 byte ,实际的⽹速是 1000Mbit/8125MB/s , 这⾥的 M 依旧是⼗进制 10^6 。如果更换成为程序员能理解的速度那么就是 实际峰值⽹速是 1000*(10^6)bit/s , 转换成为 Kbit/s 换算成程序员能理解的⼤⼩就是1000*(10^6)/1024 976562Kbit/s转换成为 Mbit/s 再算就是 953Mbit/s ⼤概就是转换成为 MB/s 再算就是 119MB/S [ Bbyte ,字节]⼤概就是这样我要下载⼀部 2GB 的电影按照峰值⽹速来算就是 2*1024MB/119MB17.2S 左右当然实际上不可能⼀直峰值此处不在解释。4.1.2 波特率波特率是每秒钟传送的符号(码元)数量也叫做传码率单位是波特( Baud 或者 Bd , B 就是 symbol/S )。在通信系统中携带数据信息的信号单元叫做码元也叫做符号( symbol )。虽然和⽐特率类似但是核⼼点在于 1 码元或者符号能承载 1 ⽐特数据也能承载多⽐特数据。举个例⼦张三和李四约定扔球玩不同的球表⽰不同的信息。波特率每秒钟张三给李四扔了⼀个球就类似每秒钟张三给李四发送了⼀次信息此时波特率就是 1Bd 。波特率就是衡量张三每秒扔球的速度。⽐特率虽然每次只扔⼀次球(波特率是 1Bd )但是球的颜⾊不同含义也不同每个球实际传递的 信息是 2 ⽐特信息所以⽐特率是 2bps 。 所以• ⽐特率是描述张三每秒传递的数据量 - 传信率• 波特率衡量的是张三每秒发⼏次球 - 传码率这个球叫做符号或者码元。像上⾯的例⼦每个码元就携带了 2 个 bit 信息。所以 所以就这个例⼦来说• ⽐特率 波特率 * 每个码元就携带的2个bit信息• 像上⾯的球的例⼦未来球能够描述 4 种状态我们叫做 4 状态码元• 码元未来⽀持N种状态我们就叫做N进制码元再⼀个例⼦⽐如我们⼈⽇常出⾏做出租⻋公交⻋⾼铁等等。注意• 实际上波特( Baud )已经表⽰速率了但是把波特叫做波特率或者翻译成为 BaudRate 是不太对的直接⽤ Baud 表⽰即可 Rate 是多余的。但是⽇常已经习惯叫做波特率所以后⾯我们依旧这么叫。• 另外如果叫做 Baud Per Secod 简称 BPS 也是不对的这就好像 m/s 已经是速度单位了突然⼜来了⼀个 m/s/s ⼀样不过有些时候如果出现了如果不是特别严谨的学术交流并且它仅仅是为了传递⼀些能让你秒懂的含义的话这样做也⾏。最后⽤⼀张图总结OK我们搞懂了这两个概念那么下⾯就开始解决问题了。5. USART速度与波特率结合之前所讲 USART 在串⾏通信的过程中速度由波特率 Baud Rate 决定( USART 是硬件电路速度问题侧重点应该在表⽰电⽓特性的波特率上)。后续在使⽤ USART 的过程中需要我们提前设置好通信双⽅的波特率进⽽让双⽅进⾏串⼝通信。单⽚机的 USART 使⽤的是⾼低电平两种状态传递码元的通信⽅式属于 2 进制码元也就是 波特 率 ⽐特率 所以如果后⾯我们⻅到很多⼯具在设置波特率的时候单位⽤ b/s 也不要觉得奇 怪尽管它不太对但是我们能理解。为了进⼀步让同学们理解波特率和速度的关系我们举⼀个极度极端的例⼦这部分后续在讲帧格式 的时候会进⼀步澄清。假设在⽐特率波特率的场景中不考虑什么帧格式1S内如果全部都是低电平波特率是10那么就 是传递10个0但是如果波特率是20就会被理解成为20个0结论• ⼀般⽽⾔波特率设置的越⾼单位时间内传递的信息量未来会越⼤换句话说波特率衡量传输速度• 波特率其实是⼀个个数单位只不过是单位时间的个数速度单位然后呢这个定义的本质意义⼜是什么呢波特率背后的潜在含义是单个信号在传输的过程中会持续多⻓时间⽐如有⼀个波特率为 10 的信号那么波特率会决定什么呢• 除了之前讲的速度问题• 波特率也会决定单位电平信息的持续时⻓❓ 那么未来给 USART 设置波特率我们另⼀个朴素的理解就是对于发送⽅你打算多⻓时间发⼀个数据持续发多⻓时间。对于接收⽅你就是打算多⻓时间收⼀个数据持续收多⻓时间这⾥的⼀个数据就理解成为 1bit❓ USART波特率• STM32 中 USART ⼀般的常⽤波特率是 9600 Bd 或者 115200Bd• 通信双⽅发送和接收数据快慢的问题可以由通信双⽅设置相同的波特率来解决。6. USART帧格式通过设置通信双⽅的波特率我们已经解决了通信速度的问题。可是对应接收⽅它怎么知道数据 开始发了它怎么知道有多少个数据它怎么知道数据什么时候传递完毕了这就需要通信双⽅继续 约定通信格式了这个格式我们叫做 - 帧格式。❓ 注意• 帧格式是⼈约定出来的相当于⼈让通信设备使⽤相同的规则通信• 这个约定的通信格式也可以叫做协议• 不过在单⽚机通信领域更喜欢叫做帧格式USART 是异步通信模式有了双⽅已知的数据帧格式这样接收端才能正确解析数据。如下图所⽰就是 UART 的通信帧格式。这个帧格式是串口的通信协议给我们设计好的整体的框架是固定不变的我们可以进行波特率和奇偶校验位的变化注意• 其中空闲起始位停⽌位都是必须要有的。• 数据帧的本质是约定上述表格中最重要的是数据帧由哪些部分组成的约定就是绿⾊字体部分。⽽数据位和校验位虽然可变或者可选但是你完全不⽤担⼼因为未来设置数据帧格式的时候通信双⽅都要设置相同的格式通信双⽅完全可以⾃由准确的识别。当然 STM32 官⽅⼿册中数据位通常是其中⼯作中⽤的最多的是 8 位数据位 1 位校验所以后续我们以下述格式进⾏阐述。6.1.1 空闲状态 ( Idle State )在没有数据传输时串⼝线路应保持逻辑⾼电平 (其实叫做逻辑 1 )也就是空闲状态如 通信帧格式中 ① 标识区域所⽰。为什么• 串⾏通信甚⾄单⽚机通信 在没有信号的时候默认很多都是处于⾼电平通常会从功耗确定性历史等⻆度来解释。• ⼩专题• ⽽未来 USART 需要⽤拉低电平表⽰起始所以USART这⾥默认也是⾼电平或者说默认是⾼电平所以起始位就只能⽤拉低电平来表⽰了。6.1.2 起始位 ( Start Bit )起始位的下降沿 ( 1 - 0 ) 是从空闲状态进⼊新帧的标志。起始位 逻辑低电平 ( 0 ) 持续 1 个⽐ 特位时间 ( 具体⻓度由波特率决定 )起始位⽤于告知接收端⼀个新数据帧的开始这是接收端进⾏ ⽐特位同步的关键信号如 通信帧格式 中 ② 标识区域所⽰。6.1.3 数据位 ( Data Bits )STM32 中数据位个数通常可选 8 位或者 9 位最常⻅的是 8 位 ( ⼀个字节 )承载实际要传输的信息内容逻辑⾼ ( 1 ) 或 逻辑低 ( 0 ) 代表数据位本⾝。USART中数据 LSB ( Least Significant Bit 最低有效位 ) 最先发送然后是次低位依此类推最后发送 MSB ( Most Significant Bit 最⾼有效位 )。如 通信帧格式 中 ③ 标识区域所⽰。这就是我们前面提到的低位先行的特点注意什么是 LSBLSB 是 Least Significant Bit 的缩写意为最低有效位。• 定义 在⼀个⼆进制数中LSB 是位于最右边的那个位具有最⼩的位权• ⽰例 在⼆进制数 1011 中最右边的 1 就是 LSB。◦ 1 × 23 0 × 22 1 × 21 1 × 20• 也就是要发送 1011 发送顺序是 1 1 0 1 先发送低有效位再发⾼有效位• 在USART中的应⽤ 在⼤多数异步串⾏通信如USART、RS-232中数据通常是从LSB 开始先传输LSB first。这是为了让接收设备能够更快地开始处理数据⽽不需要等待整个字节接收完毕。什 么是 MSBMSB 是 Most Significant Bit 的缩写意为最⾼有效位。• 定义 在⼀个⼆进制数中MSB 是位于最左边的那个位具有最⼤的位权。 • ⽰例 在⼆进制数 1011 中最左边的 1 就是 MSB。◦ 1 × 23 0 × 22 1 × 21 1 × 20• 也就是要发送 1011 发送顺序是 1 0 1 1 先发送⾼有效位再发低有效位• 在USART中的应⽤ 少数通信协议或系统可能配置为 MSB first 传输但不如 LSBfirst 常⻅。6.1.4 校验位 ( Parity Bit )校验位如 通信帧格式 中 ④ 标识区域所⽰。校验位是简单的错误检测机制⽤于检测传输过程中特定 数量的⽐特是否发⽣了翻转错误可配置的校验类型如下• ⽆校验 ( None )不发送校验位即⽆校验。• 奇校验 ( Odd )设置校验位使得数据位和校验位中 1 的总个数为奇数。• 偶校验 ( Even )设置校验位使得数据位和校验位中 1 的总个数为偶数。✨ ⽰例 8 位数据 1. 奇校验⽰例◦ 假定数据为 “ 11110000 ”那么校验位需要设置为 ‘ 1 ’变成 111100001 ,这样就有奇数个‘ 1 ’ 5 个‘ 1 ’ 。◦ 假定数据为 “ 1111 1110 ”那么校验位需要设置为 ‘ 0 ’变成 111111100 这样还是奇数个‘ 1 ’ 7 个‘ 1 ’ 。奇校验Odd Parity的核⼼⽬的就是确保包括数据位和校验位在内的整个数据包中⼆进 制 1 的总数是奇数个。2. 偶校验⽰例◦ 假定数据为 “ 11110000 ”那么校验位需要设置为 ‘ 0 ’变成 111100000 这样就有偶数个‘ 1 ’ 4 个‘ 1 ’ 。◦ 假定数据为 “ 11111110 ”那么校验位需要设置为 ‘ 1 ’变成 111111101 这样就有偶数个‘ 1 ’ 8 个‘ 1 ’ 。偶校验Even Parity的核⼼⽬的就是确保包括数据位和校验位在内的整个数据包中⼆进 制 1 的总数是偶数个 注意• ⽆论是奇校验还是偶校验都只能检测奇数个⽐特位翻转错误 ( 如: 1 位、 3 位翻转...)⽆法检测偶数个⽐特翻转错误也⽆法纠正错误。• 奇偶校验只能从概率上甄别出部分⽐特位翻转等错误问题说明想象我们⽤偶校验规则⼀袋苹果必须是偶数个。场景⼀1个错误奇数个错误1. 发送⽅装了 6 个完好的苹果偶数。2. 路上有 1 个苹果坏了。3. 接收⽅数到 5 个完好的苹果奇数。4. 接收⽅惊呼“不对应该都是好的偶数个出错了” 错误被发现场景⼆2个错误偶数个错误1. 发送⽅装了 6 个完好的苹果偶数。2. 路上同时有 2 个苹果坏了。3. 接收⽅数到 4 个完好的苹果偶数。4. 接收⽅满意地说“没错是偶数个好的⼀切正常。” 错误没被发现想 象我们⽤奇校验规则⼀袋完好的苹果必须是奇数个。场景⼀1个错误奇数个错误1. 发送⽅装了 5 个完好的苹果奇数。2. 路上有 1 个苹果坏了。3. 接收⽅数到 4 个完好的苹果偶数。4. 接收⽅惊呼“不对应该是奇数个好的出错了” 错误被发现场景⼆2个错误偶数个错误1. 发送⽅装了 5 个完好的苹果奇数。2. 路上同时有 2 个苹果坏了。3. 接收⽅数到 3 个完好的苹果奇数。4. 接收⽅满意地说“没错是奇数个好的⼀切正常。” 错误没被发现简单来说只是检查错误无法进行改正6.1.5 停⽌位 ( Stop Bits )停⽌位表⽰帧的结束固定为逻辑⾼电平 ( 1 )可以配置为 1 位、 1.5 位、 2 位停⽌位结束后会回到空闲状态。如 通信帧格式 中 ⑤ 标识区域所⽰。 注意• 这⾥说的 1 位、 1.5 位、 2 位是指逻辑⾼电平 ( 1 ) 需要保持的时间⻓度具体多⻓和波特率有关。问题1有没有可能在串⼝通信的时候把起始位当做数据位不可能因为串⼝通信的时候起始位数据位校验位有多少个都是双⽅约定好格式⽐如通信双 ⽅约定拉低的起始位8位数据位1位校验位刚开始遇到的第⼀个拉低位就⼀定会被接收⽅判 断成为起始位。问题2有没有可能在串⼝通信的时候把数据位当成结束位?为什么不可能因为串⼝通信的时候起始位数据位校验位有多少个都是双⽅约定好格式⽐如通信双⽅约定 1 位拉低的起始位 8 位数据位 1 位校验位 18110 如果在没有收到这 10 个bit 信息的时候是不会有判断结束位逻辑的也就不会把数据位当成结束位。问题3有没有可能在串⼝通信的时候把结束位当成数据位的⼀部分?为什么不可能因为串⼝通信的时候起始位数据位校验位有多少个都是双⽅约定好格式⽐如通信双⽅约定 1 位拉低的起始位 8 位数据位 1 位校验位 18110 也就是固定⼤⼩的10个⽐特位只要收完有效数据传输就完成了再收到⾼电平就判定数据帧结束了不会把结束位当做数 据位。 问题4: 为什么结束位需要拉⾼起始位需要拉低电平表征起始位。如果当前帧传递完毕没有结束位即没有强制拉⾼电平此时 tx 输出的电平就取决于当前帧的最 后⼀位这个⾼低电平都有可能。那么传递下⼀帧它的起始位就不能100%有⼀个拉低的动作会影响下⼀帧的正确开始。如果当前帧传递完毕必须有结束位即强制拉⾼电平就保证了在下⼀帧的起始位到来之前线路 上⾄少有 1 个或 1.5/2 个⽐特周期的⾼电平⽅便下⼀帧拉低。当然停⽌位之后如果没有发送下⼀帧数据线路就会维持⾼电平恢复默认状态。✨ 让⼀切具有确定性是USART追求的。 细节• 每⼀帧格式起始位数据位校验位(可选)停⽌位都必须要有尤其是起始和结束。• 发送 5 个 8 位数据时会形成 5 个独⽴的数据帧Frame。每⼀帧都必须包含⾃⼰的起始位、数据位和停⽌位。因此发送 5 个 8 位数据确实会有 5 个 停⽌位。 整个传输过程是这样的• 发送第 1 个数据字节[起始位] [8个数据位] [停⽌位]• 发送第 2 个数据字节[起始位] [8个数据位] [停⽌位]• 发送第 3 个数据字节[起始位] [8个数据位] [停⽌位]• 发送第 4 个数据字节[起始位] [8个数据位] [停⽌位]• 发送第 5 个数据字节[起始位] [8个数据位] [停⽌位]• 如果你把停⽌位看作是每⼀帧数据的“结束标志”或“句号”那么每发送⼀个数据都需要画上⼀个句号以便接收端知道这⼀帧结束了准备接收下⼀帧的起始位它是 UART 通信中最核⼼的参数之⼀直接决定了通信双⽅能否正确解读数据。波特率的单位为 bps ( baud per second )例如 9600 波特率表⽰每秒传输 9600 个信号单元。这⾥的单位是不是就不太对了不过历史原因也可以这样叫7. USART帧格式与波特率有了 USART 帧格式和波特率的理解那么我们来算⼀笔账 ⽰例1• 假定波特率为 9600 Bd在 USART 中波特率⽐特率。• 假定帧结构 1 起始位 8 数据位 ⽆校验位 1 停⽌位 10 位。• 理论每秒传输字节(即字节传输速率) 9600bps / 10bits/byte 960 字节/秒⽰例2• 假定波特率为 115200 Bd在 USART 中波特率⽐特率。• 假定帧结构 1 起始位 8 数据位 ⽆校验位 1 停⽌位 10 位。• 理论每秒传输字节(即字节传输速率) 115200bps / 10bits/byte 11520 字节/秒。注意• 关于 USART 波特率 9600 和 115200 这两个数字我们样例中在详细解释• 通过上⾯的计算主要是让⼤家对 USART 的速度有⼀个量化的认识也能直观看到波特率对于 USART 传输速度的影响8. USART简化原理结构图前⾯若⼲⼩结我们讨论的都是 USART 的通信协议特性下⾯我们把重点放在 STM32 单⽚机中关于 USART 的功能结构中即重点放在 USART 硬件功能构成和如何发出 USART 数据帧上。❓ 注意• STM32 的 USART 完全兼容之前讲解的 UART 的全部特性。• 除此之外它还⽀持同步单向通信和半双⼯单线通信也⽀持 LIN ( 局部互连⽹ )智能卡协议和 IrDA ( 红外数据组织 ) SIR ENDEC 规范以及调制解调器 ( CTS / RTS ) 操作它还允许多处理器通信的能⼒。总之 STM32 的 USART 有丰富的扩展功能。• 但是其中⼀些的应⽤场景是极少⻅的我们在⼊⻔课中只讲解 USART 标准的异步通信功能 这也是最关键、核⼼的功能 。如果我们要看到 USART 功能框图我们可以移步⾄《 STM32F10xxx 参考⼿册》通⽤同步异步收发 器( USART )章节。此处我们节选到课件中。我们把串口的通讯结构图分成不同的区域进行理解如上图所⽰是 STM32 的 USART 的功能框图其中各部分的主要功能如下1. 图中 ① 标识区域是 USART 相关的管脚2. 图中 ② 标识区域是 USART 波特率控制相关3. 图中 ③ 标识区域是 USART 控制寄存器相关4. 图中 ④ 标识区域是 USART 状态寄存器相关5. 图中 ⑤ 标识区域是 USART 数据收、发相关核⼼功能框图6. 图中 ⑥ 标识区域在 IrDA ( 红外模式 ) 和智能卡模式下才会使⽤。该图所⽰的功能模块对于⼊⻔课⽽⾔太过于庞杂。对于仅使⽤ USART 标准通信功能⽽⾔最核⼼的 就是图中 ⑤ 标识的区域部分我们只把 ⑤ 标识的区域部分拿出来进⾏简化移位寄存器是我们不可见的是硬件电路进行设计的,我们关系TDR和RDR当⽤⼾将待发送的字节数据写⼊到数据寄存器 ( USART_DR / TDR ) 中 USART 控制器会⾸先把TDR的数据平移⾄发送移位寄存器然后USART的发送控制器就会将发送移位寄存器中的数据⾃动按照数据位通过 Tx 管脚依次发送出去。 2. USART 控制器会通过 Rx 管脚依次接收收到的数据位到接收移位寄存器当接收完⼀个数据段 ( 8 / 9 位) 时会⾃动将接收移位寄存器中的数据平移拷⻉到数据寄存器 (USART_DR / RDR ) 中。后续⽤⼾从数据寄存器 ( USART_DR / RDR ) 读取数据就能得到最近⼀次接收到的数据字节。在这⾥我们正式认识两个 USART 寄存器分别是• 发送寄存器TDRTransmit Data Register• 接收寄存器RDRReceive Data Register其中发送和接收移位寄存器在 USART 硬件单元内部对⽤⼾不可⻅。❓ 注意• 除了TDR和RDR我们把USART的其他模块当成⿊盒的整个拷⻉移动移位发送和移位接收都是USART模块⾃⼰完成的9. STM32 USART 发送和接收速览有了上⾯结构图的简化过程下⾯我们⽤最快的时间来看⼀下 STM32 USART 是如何完成基本⽐特 位的数据收和发的包括之前讨论的TDR和RDR寄存器起什么作⽤等。9.1 STM32 USART 发送速览忘记之前所学的所有内容忘所谓的帧格式我们先来理解 USART 是如何发送 8 个⽐特位的。 如果理解了发送数据位的过程后续引⼊帧格式⽆⾮就是给数据位置规定含义的问题。为了⽅便演⽰我们以发送 0x55 为例 0x55 ⼆进制是 0101 0101 暂时不考虑 USART 本⾝ 的数据帧格式问题。发送过程我们只需要考虑发送模块先只看发送逻辑9.2 STM32 USART 接收速览有了之前发送的过程的理解那么接收过程就很好理解了。讨论接收那么我们只需要考虑接收相关 的内容即可10. 查⽂档理思路10.1 理解CPU读写TDR和RDR这两个寄存器属于 USART 模块内部⽽其中 STM32F103ZET6 有 5 个串⼝模块每⼀个都有⼀套独⽴的寄存器结构我们以 USART1 为例。我们再次对统一编制的地址框架进行理解上图可知 USART1 的地址范围是 0x4001 3800 - 0x4001 3BFF该地址范围是 0x4001 3800 到 0x4001 3BFF 。• USART1 拥有的范围⼤⼩ 结束地址 - 起始地址 1• 0x4001 3BFF - 0x4001 3800 1 0x3FF 1 0x400 (⼗六进制)• 将 0x400 转换为⼗进制 1024 字节。所以这个地址空间⼀共是 1024 字节也就是 1KB 。注意虽然CPU内核只为 USART1 分配了 1KB 的地址空间但实际使⽤的只有最开头的很少⼀部分。后续的地址是保留的访问它们可能产⽣不可预知的⾏为。⽽后续 USART1 中寄存器⼀共有 7 个(暂时不管是什么我们也不需要全部熟悉需要的时候查就⾏了)其中每⼀个寄存器都有⼀个偏移量地址最终访问任何⼀个寄存器访问⽅式都是0x4001 3800 寄存器偏移。有了这些地址 CPU 就可以直接访问任意⼀个寄存器。包括我们的数据寄存器 DR 。⽽我们的 STM32F103ZET6 系列单⽚机内部包含 5 个串⼝模块每⼀个都有⾃⼰的地址范围。串⼝模块详细地址清单主要差别是• APB2 : ⾼速外设总线 USART1 挂载于此通常运⾏在最⾼ 72MHz• APB1 : 低速外设总线其他串⼝挂载于此最⾼频率 36MHz• 有的是 USART 有的是 UART 注意区分。 ⽽其中每⼀个串⼝模块都有 1KB 地址空间每⼀个地址空间都有⼀套寄存器族来⽀持每⼀个串⼝模块独⽴数据收发。具体理解⽅式就是之前我们以 USART1 为例的内容。10.2 TDR 与 RDROK现在我们通过查阅⽂档的过程理清了 USART 寄存器⽅⾯的思路知道 CPU 核⼼可以直接通过物理地址访问任意⼀个 USART 寄存器。 注意• CPU 能访问 USART 内部的寄存器那么是谁让 CPU 访问这些寄存器的呢答案是CPU 执⾏的是你未来写的代码你的代码写了要访问寄存器的指令那么 CPU 才去访问的换句话说 CPU 访问 USART 寄存器就是程序员让 CPU 访问的 CPU 控制USART ⼈控制 CPU 编程的本质之⼀就是指导 CPU ⼯作。在物理上USART_DR寄存器有两个⼀个是TDR⼀个是RDR分别让⽤⼾来发和收数据• 这两个寄存器被映射到了同⼀个物理地址但是官⽅没有披露具体是怎么做到访问同⼀个地址从⽽做到访问不同寄存器我们可以推测通过操作类型(rw)来区分要访问哪⼀个寄存器。• rw : 寄存器中特定的⽐特位具有 read 和 write 权限 • 地址偏移结合我们之前查阅⽂档的经历该字段很容易理解。• 虽然 USART_DR 寄存器是 32 位的但是实际使⽤的只有 9 位因为 USART 可编程数据位最多是 9 位。11. STM32 USART 发送详细过程11.1 USART 数据帧发送有了之前基本发送 8 ⽐特位的过程理解知道了 TDR 和 RDR 和对应的移位寄存器那么我们现在知道了 USART 只要能发送多个⽐特位就能发送多个⽐特位构成的数据帧。所谓的数据帧本质也全部都是 01 ⽐特位只不过被 USART 模块包装或者解析接收的时候把数据帧中数据部分提供给 RDR 发送的时候把 TDR 的数据包装成为数据帧。为了⽅便表述我们以实际中最常⽤的场景来进⾏阐述。假设要发送的数据帧是 1 起始位 8 数据位 1 校验位 1 停⽌位 11 位。其中校验位奇校验偶校验⼆选⼀即可。 我们依旧以发送 0x55 为例⼆进制是 0101 0101 采⽤奇校验那么对应的数据位总共是9位0101 0101 1 位校验位。❓ 注意校验位本⾝和数据的⼆进制中1的个数是有关的需要和数据⼀起发送给对⽅那么校验位就应该作为数据的⼀部分发送给接收⽅。USART发送数据帧.pptx❓ 总结• USART传递⽐特位是USART传递数据帧的底层技术⽀持• 起始位和结束位是USART发送模块⾃⼰加的⽤⼾没有感知• ⽤⼾只知道数据⾃⼰设置的校验⽅式(详⻅代码部分)• 理解数据帧格式的顺序最好站在接受者⻆度理解顺序和物理过程才是⼀致的减少不必要的理解成本11.2 USART发送标志位介绍OK 有了上述发送数据帧的理解那么我们就可以继续谈后续内容了。 当发送⽅要发送数据主要过程分为• ⽤⼾把数据拷⻉到 TDR• 然后你就别管了 USART ⾃⼰移动到移位寄存器然后再时钟的驱使下开始进⾏发送也就是USART 发送对⽤⼾来讲是⿊盒的可是USART 发送不是⼀蹴⽽就的⽽是⼀步⼀步发的那么万⼀在发送期间⽤⼾⼜往 TDR 写数据了会发⽣什么问题只要 TDR 有数据 USART 就要移动到移位寄存器如果没发完数据覆盖错误场景2 USART 把⾃⼰的数据发完 TDR 还有数据 USART 再移动到移位寄存器再发。 USART 真实采⽤的是这种情况。但是潜台词是⽤⼾的数据会因为USART在忙⽽暂时保存在 TDR 中可是这个过程对⽤⼾来讲都是透明的⽤⼾⼜不知道⽤⼾写完到 TDR 如果再写就 ⾃⼰把⾃⼰的数据覆盖了可是⽆论是场景 1 还是场景 2 ⽤⼾不管啊⽤⼾⼜不知道 USART 有没有发完如果覆盖了这个锅谁背啊肯定是 USART 要是 TDR 我不能写 USART 你得告诉我啊。所以 USART 在⾃⼰的收发过程中必须要提供⾃⼰收发状态的信息这部分信息叫做 USART 的 状态寄存器( USART_SR USART Status Register),可以预⾔该寄存器内部⼀定有标志位来表明 ⽤⼾是否可以写⼊ TDR 的寄存器这个时候就引入了状态标志位USART 发送状态信息由这 10 个标志位标识此处可以打开《STM32F103xx参考⼿册》看到所有 标志位信息。但是现在没必要需要再查现在我们只需要关⼼的是两个标志位这两个标志位与发送有关。• TXE(Transmit data register empty) ⽬前需要关注的是◦ 当 TDR 寄存器中的数据被 USART 硬件模块转移到移位寄存器的时候该为被硬件设置为1 潜台词就是⽤⼾需要检测这个⽐特位当 TXE 是 1 的时候表明 TDR 空了⽤⼾才可以写。这样USART数据覆盖的锅甩给了⽤⼾从此丰俭由⼈。◦ 对 USART_DR 进⾏写⼊ TXE 会⾃动清 0 。这句话的潜台词就是⽤⼾发现 TXE 是 1 表明 TDR 空了⽤⼾可以写⽤⼾写⼊ TXE 清零表明 TDR 正在被占⽤请勿在写。• TC(Transmission complete) ⽬前需要关注的是◦ 当包含有数据的⼀帧发送完成之后并且 TEX1 ( TDR 为空)USART硬件模块会⾃动将该位设置为1• rc: 通常代表 Read Clear。这表⽰这是⼀个“读取并清除”的操作• w0: 代表 Write Zero。这表⽰向某个寄存器写⼊0。向该位写0来清除标志写1则⽆影响这是STM32的标准做法• r: 代表 Read。这表⽰⼀个读取操作TC简单来说就是即检查TXE又检查了数据移位寄存器是否移交完成来判断数据是否发送完成11.3 USART数据帧发送和标志位11.4 阻塞模式发送之前我们讲述的发送过程就是要求⽤⼾发送数据的时候必须对 TXE 进⾏检测如果TXE0 表⽰ TDR 数据并没有平移到发送移位寄存器那么⽤⼾就必须阻塞在检测 TXE 标志位的位置处进⾏等待这种模式就叫做阻塞式发送。在⽤⼾⻆度如果使⽤阻塞模式进⾏数据发送⼀个或者多个数据之后怎么知道 USART 彻底把数据 发送出去发送移位寄存器和 TDR 都为空如 下图 中 ③ 标识的区域是 TC 标志被置 1 时表⽰ 要发送的数据已全部发送完成这时如果还有待发送的数据就可以进⾏发送12. STM32 USART 接收详细过程12.1 USART 数据帧接收有了之前 USART 发送数据的所有详细过程在结合USART接收速览那么其实我们后续学习数据接 收⼀定会容易很多。所谓的数据帧本质也全部都是 01 ⽐特位只不过被 USART 模块包装或者解析接收的时候把 数据帧中数据部分提供给 RDR 发送的时候把 TDR 的数据包装成为数据帧。为了⽅便表述我们以实际中最常⽤的场景来进⾏阐述。假设接收的数据帧是 1 起始位 8 数据位 1 校验位 1 停⽌位 11 位。其中校验位奇校验偶校验⼆选⼀即可。我们依旧以接收 0x55 为例⼆进制是 0101 0101 采⽤奇校验那么对应的数据位总共是9位0101 0101 1 位校验位。校验位本⾝和数据的⼆进制中1的个数是有关的需要和数据⼀起发送给对⽅那么校验位 就应该作为数据的⼀部分被接收⽅收到进⽽由对⽅进⾏进⾏校验。总结• USART 传递⽐特位是 USART 传递数据帧的底层技术⽀持• 起始位和结束位是 USART 发送模块⾃⼰加的⽤⼾没有感知• ⽤⼾只知道数据⾃⼰设置的校验⽅式(详⻅代码部分)• 理解数据帧格式的顺序最好站在接受者⻆度理解顺序和物理过程才是⼀致的减少不必要的理解成本12.2 USART接收标志位介绍OK 有了上述接收数据帧的理解那么我们就可以继续谈后续内容了。当接收⽅要接收数据主要过程分为• 然后再时钟的驱使下 USART ⾃⼰识别起始位接受数据移动数据到移位寄存器识别结束位判定接受⼀个数据帧结束⾃动校验校验成功⾃动将数据位平移到 RDR 寄存器 • ⽤⼾只需要读取 RDR 寄存器中的数据即可❓ 注意• 根据之前查阅标准⽂档的经历我们知道⽤⼾是可以直接⽤物理地址读取RDR的所以读取RDR并不困难可是⽤⼾怎么知道 RDR 内部已经有数据了呢 USART 需要有⽅式能表⽰ RDR 寄存器的状态类似发送接收的时候也是状态寄存器 USART_SR 来标识接收状态其中 RXNE 标志位就是完成该项⼯作的。当 RDR 寄存器中没有数据的时候RXNE标志位被设置为0• 当 RDR 寄存器中有数据的时候 RXNE 标志位被设置为1• RXNE: Read data register not empty如 下图 中 ① ② ③ 标识的区域是 RXNE 标志表⽰读数据寄存器⾮空 ( Read data registernot empty )。当接收移位寄存器中的数据被转移到 USART_DR 寄存器中该位被硬件⾃动置位。对 USART_DR 寄存器的读操作可以将该标志位清零。所以当 USART 在接受数据期间那么⽤⼾就应该⼀直检测 RXNE 标志位只要该标志位⼀直是 0 那么⽤⼾就应该⼀直阻塞在检测的位置直到 RXNE 1 表⽰有数据了才能读取。12.4 阻塞模式如果使⽤阻塞模式进⾏数据接收程序需要轮询判断如 下图 所⽰的 ① ② ③ 的 RXNE 标志主要逻辑 如下1. RXNE 标志被置 0 表⽰暂时没有数据要求⽤⼾轮训检测该标志位标志位为0就有⼀直阻塞在这⾥。2. 收到数据 RXNE 标志被置 1 表⽰接收到 1 字节数据⽤⼾将读到的数据保存到⾃⼰定义内存区域读取的时候会⾃动触发清除 RXNE 标志 然后继续检测 RXNE 等待接收下⼀个数据。3. 达到期望接收的数据个数或等待数据超时退出本次阻塞模式接收流程。下期开始讲解串口底层代码讲解和寄存器配置原理

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询