理论学习-ARM-通用串口学习

通用串口学习

  • 串口(UART/USART)综述
  • UART(Asynchronous 异步)
  • USART(Synchronous/Asynchronous 同步/异步)
      • 同步需要下面引脚配置:
      • 硬件流控制的引脚配置:
    • USART的功能描述
      • USART的特性描述
      • 发送
        • 停止位
        • 以STM32F407为例,UART的配置过程如下:
        • 单字节通讯
        • 打断字符
        • 空闲字符
      • 接收
        • 开始位检测
        • 字节接收
        • 打断字符
        • 空闲字符
        • 溢出错误
        • 选择合适的过采样方法
        • 帧错误
        • 在接收期间配置停止位
      • 分数波特率发生器
        • 多处理器通讯
      • 奇偶校验
      • ~~串口局域网模式~~
      • ~~串口同步模式~~
      • ~~单总线半双工通讯~~
      • ~~智能卡~~
      • ~~红外模块~~
      • 用DMA实现数据流通讯
      • 硬件流控制
      • 串口中断
      • USART 的模式配置
  • 串口的工程应用
    • 工程实践案例
  • 串口发送&接收概述

串口(UART/USART)综述

对于普通应用来说,最常用的是 中断发送DMA发送。如果是裸机,且数据量不大,交互频繁,推荐中断方式;如果是系统机,或者数据量较大,通讯不那么频繁,最适合用MDA方式。
中断方式:CPU频繁进入中断,然后保存栈,浪费栈内存和CPU。
MDA方式:把数据内存地址和发送长度告诉MDA后,由DMA自主发送数据。但是依旧占用RAM总线。但是RAM会给CPU预留一部分出来,防止RAM总线占尽,卡机。

UART(Asynchronous 异步)

USART(Synchronous/Asynchronous 同步/异步)

同步需要下面引脚配置:

CK:发送时钟输出。其与SPI基本类似(在起始位和停止位没有时钟脉冲,软件设置在最后一个数据位发送时钟脉冲)。RX引脚可以并行接收数据。这个特性可以去驱动内嵌移位寄存器的外围设备(比如,LCD)。其时钟相位和极性是可编程的。在smart卡模式下,CK可以为smart卡提供时钟。

硬件流控制的引脚配置:

CTS:
RTS:

USART的功能描述

USART的特性描述

1,数据长度:8、9字节可选
2,TX:开始位->低电平
停止位->高电平
空闲->高电平
3,空闲帧(idle character):
开始位+数据位+停止位全部为“1”,下一帧正常
4,打断帧(break character):
开始位+数据位+停止位全部为“0”,下一帧的开始位用“停止 位“应答。

发送

Bus USART_DR Shift_Register to to Bus USART_DR Shift_Register

可以见stm32的参考手册
理论学习-ARM-通用串口学习_第1张图片

停止位
  • 1 stop bit:默认
  • 2 stop bit:支持normal USART、single-wire 、modem modes
  • 0.5 stop bit:在智能卡模式下接收数据使用
  • 1.5 stop bit:在智能卡模式下发送、接收数据使用
以STM32F407为例,UART的配置过程如下:
  1. 将USART_CR1寄存器的UE位置“1”,使能USART.
  2. 通过编写USART_CR1寄存器的M位,定义字长。
  3. 在USART_CR2编写停止位数
  4. 如果多缓冲信息交互,需在USART_CR3(DMAT)使能DMA
  5. 配置期望的波特率
  6. 使能USART_CR1寄存器的TE位,发送一个空闲帧作为第一帧数据
  7. 将要发送的数据写入USART_DR寄存器(并需要清空TXE位),对于单个缓冲区,每发送一个字节重复一次。
  8. 将最后的数据写入USART_DR后,直到等待TC=1。这是,最后一帧数据发送完成。失能串口或者进入暂停模式,这是必要的,以避免冲撞最后一次发送。
单字节通讯

TXE位通过写寄存器清除
TXE位是硬件置位:

  • 数据已经从TDR移到移位寄存器,并且数据传输已经开始。
  • TDR寄存器已经空了
  • 下一个数据写入USART_DR不会覆盖先前的数据

如果TXEIE位被置位,这个标志位会产生一个中断。

当一个传输发生时,一条写入USART_DR寄存器的指令将数据存储在TDR reaister中,并在当前传输结束时复制到移位寄存器中。

当没有传输发生时,写入USART_DR寄存器的指令将数据直接放在移位寄存器中,数据传输开始,并立即设置TXE位。

如果有帧传输(在停止位之后),并且设置了TXE位,TC位会变高。如果在USART CR1寄存器中设置了TCIE位,则产生一个中断。

在将最后的数据写入USART DR寄存器后,在禁用USART或使微控制器进入低功耗模式之前,必须等待TC=1(参见图299:传输时的TC/TXE行为)

清除TC位的软件顺序如下:

  1. 从USART SR寄存器读取
  2. 写入USART DR寄存器

note:也可以通过在TC位上写一个"0"来清除TC位。此清除顺序仅推荐用于多缓冲区通信。

理论学习-ARM-通用串口学习_第2张图片

打断字符

如果SBK位设置为’1,则在完成当前字节传输后在TX线上发送中断字符。当中断字符发送完成后,SBK位将被硬件重置(在中断字符的停止位期间重置)。在最后的一个打断帧的末尾,串口嵌入一个逻辑“1”,保证识别下一帧的起始位。

note:如果软件在打断传输开始前就复位了SBK位,则此次的打断字符不会传输。要想实现两次连续的打断字符,SBK位应当在前一个打断字符停止位后置位。

空闲字符

设置TE位驱动USART在第一个数据帧之前发送一个空闲帧。

接收

USART可以接收8位或9位的数据字,具体取决于USART CR1寄存器中的M位。

开始位检测

并非是简单的一个falling edge detection。而是存在一个8 or 16过采样的问题。
这个过采样,就带来了一个采样标准问题。结果以对“start bit”过采样得到的序列为准,但标准序列是:111 0 x 0 x 0 x 0000

16或者8倍过采样的的开始位检测序列相同。在 USART,开始位以一个特定的采样序列识别出来。此序列就是:111 0 x 0 x 0 x 0000 。具体时序图图下:
理论学习-ARM-通用串口学习_第3张图片
Note:
如果序列没有完成,开始位检测中止,接收器返回到空闲状态(没有设置标志),等待下降沿。

如果3个采样bit都是 “0”(第一次采样在第三次【从0开始】sample clock开始,5、6、7bits是3
bits的“0”,第二次对 8,9,10bits过采样也都是”0“),开始位就被确认了(RXNE flag 设置的话,并且RXNEIE =1,会产生中断).

如果开始位被验证通过,并且NE噪声标志位也开启了,那么需要 5,6,7 sample clock 和8,9,10 sample clock 的3bits 至少2bits是”0“。如果上述条件不满足,那么开始位检测就会中断,并且接收器会返回空闲状态(没有标志位会被置位)
如果,三位采样sample clock 中恰是2位为”0“,开始位虽然也会被确认,但是噪声标志NE也会被置位。

字节接收

在USART接收期间,数据开始从低有效位开始通过RX引脚移位接收。在这种模式下,USART DR寄存器由内部总线和接收的移位寄存器之间的缓冲区(RDR)组成。

步骤:
1.在USART_CR1寄存器的UE位写”1“,使能 USART
2.在USART_CR1寄存器编写M位,定义字长
3.在USART_CR2,编写停止位
4.在USART_CR3选择DMA使能,如果需要多缓冲接收。依据多缓冲通讯配置DMA寄存器
5.用USART_BRR波特率发生寄存器选择期望的波特率
6.在USART_CR1设置RE位。这使能接收器开始监测一个”开始位“。

在字节接收的时候:

  • RXNE位被置位。说明移位寄存器的内容已经移到了RDR。换言之,数据已经被接收并且可读(以及与之相关的错误标志)
  • 如果设置了RXNEIE位,则产生一个中断。
  • 如果在接收过程中检测到帧错误,噪声或溢出错误,则可以设置错误标志。
  • 在单缓冲区模式下,清除RXNE位是由一个读USART DR寄存器的软件指令执行的。RXNE标志也可以通过向其写入0来清除。RXNE位必须在接收下一个字符结束之前清除,以避免溢出错误。

Note:当接收数据时,RE位不应该被重置。如果在接收期间禁用RE位,则当前字节的接收将被中止

打断字符

当接收到中断字符时,USART将其作为帧错误处理。

空闲字符

当检测到空闲帧时。如果设置了IDLEIE位,则与数据接收字符加上中断的过程相同

溢出错误

当RXNE未被重置时接收到字符时发生溢出错误。在清除RXNE位之前,数据不能从移位寄存器转移到RDR寄存器。
RXNE标志在接收到每个字节后被置位。如果在接收到下一个数据或上一个DMA请求还没有响应完成时设置了RXNE标志,就会发生溢出错误。当发生溢出错误时:

  • ORE位被置位。
  • RDR内容不会丢失。当执行对USART DR的读操作时,前面的数据是可用的。
  • 移位寄存器将被覆盖。在此点之后,在溢出期间接收的任何数据都将丢失。
  • 如果RXNEIE位被设置,或者EIE位和DMAR位都被设置,就会产生一个中断。
  • ORE位通过读USART_SR寄存器和读USART_DR寄存器操作来重置。

Note:
当ORE位被置位时,表示至少有1个数据丢失。有两种可能:

  • 如果RXNE=1,则最后的有效数据存储在接收寄存器RDR中,可以读取。
  • 如果是RXNE=0,则意味着已经读取了最后一个有效数据,因此RDR中没有要读取的数据。当在RDR中读取最后一个有效数据的同时接收到新的(和丢失的)数据时,就会发生这种情况。它也可能发生在读序列期间(在USART SR寄存器读访问和USART DR读访问之间)接收到新数据时。
选择合适的过采样方法

接收器完成不同的用户过采样配置,来做数据恢复。是通过甄别合法数据和噪声来实现的。过采样的方式可以通过在 USART_CR1 寄存器 的OVER8 bit 来选择。可以是 16 或者 8 倍的波特率时钟。

相关配置应用:

  • 选择过采样8 (OVER8=1)以实现更高的速度(高达fpcLk/8)。在这种情况下,最大的接收clock误差裕度被降低。
  • 选择过采样16(OVER8=0)增加了接收clock误差裕度。在这种情况下,最大速度限制在最大fpcLk/16。

对USART CR3寄存器中的ONEBIT位进行编程,选择用于评估逻辑电平的方法。有两种选择:

  • 在接收比特中心的三个采样进行多数投票。在这种情况下,当用于多数投票的3个样本不相等时,置NF位
  • 在接收位中心单次采样

相关配置应用:

  • 在噪声环境下操作时,选择三次采样的多数投票法(ONEBIT=0),当检测到噪声时拒绝数据(见图133),因为这表明在采样过程中发生了小故障。
  • 当信号线上无噪声时,选择单次采样方法(ONEBIT=1)以增加接收器对时钟偏差的容忍。在这种情况下,不会设置NF位。

当在一帧中检测到噪声时:

  • 在RXNE的上升沿时,NF位会被置位
  • 非法数据从移位寄存器转移到USART DR寄存器。
  • 在单字节通信的情况下不会产生中断。然而,这个位与RXNE位同时上升,RXNE位本身产生一个中断。在多缓冲区通信的情况下,如果在USART CR3寄存器中设置了ElE位,就会发出中断

NF位由USART SR寄存器读操作和USART DR寄存器读操作复位。

Note:在智能卡、IrDA和LIN模式下不能进行8倍过采样。在这些模式下,OVER8位被硬件强制为0。
理论学习-ARM-通用串口学习_第4张图片
理论学习-ARM-通用串口学习_第5张图片
理论学习-ARM-通用串口学习_第6张图片

帧错误

当以下情况时检测到帧错误:
在去同步或过度噪音之后,停止位在预期的接收时间上不能被识别。
当检测到帧错误时:

  • FE位是由硬件置位
  • 无效数据从移位寄存器转移到USART DR寄存器。
  • 在单字节通信的情况下不会产生中断。然而,这个位与RXNE位同时上升,RXNE位本身产生一个中断。在多缓冲区通信的情况下,如果在USART_CR3寄存器中设置了ElE位,就会发出中断。

FE位由USART SR寄存器读操作和USART DR寄存器读操作复位。

在接收期间配置停止位

接收的停止位数可以通过控制寄存器2的控制位来配置——正常模式下可以是1或2,智能卡模式下可以是0.5或1.5。

  1. 0.5停止位(智能卡接收):0.5停止位不做采样。因此,当选择0.5停止位时,不会检测到帧错误和中断帧。
  2. 1停止位第8、9、10次采样完成1位停止位采样
  3. 1.5 stop bits(智能卡模式):使用智能卡模式传输时,需要检查数据是否正确发送。因此,必须启用接收块(在USART CR1寄存器中RE =1),并检查停止位以测试智能卡是否检测到奇偶校验错误。在奇偶校验错误的情况下,智能卡强制数据信号在采样期间低- NACK信号-,这被标记为帧错误。然后,在1.5停止位的末尾用RXNE设置FE标志。1.5停止位的采样在16、17和18个采样点完成(停止位开始后的1波特时钟周期)。1.5停止位可以分解为两个部分:一个0.5波特的时钟周期,在此期间没有发生任何事情,然后是一个正常的停止位周期,在此期间采样发生了一半。
  4. 2停止位:在第1停止位的第8、9、10次采样时对2停止位进行采样。如果在第一个停止位检测到帧错误,将设置帧错误标志。第二个停止位没有检查帧错误。RXNE标志位将在第一个停止位的结束时被置位。

分数波特率发生器

发送和接收的波特率设置为相同的值,在USARTDIV的尾数和分数值中编程。

等式1:标准USART的波特率(包括SPI模式)
在这里插入图片描述
等式2:智能卡、LIN和IrDA模式下的波特率
在这里插入图片描述
USARTDIV是一个在USART BRR寄存器上编码的无符号定点数字。

  • 当OVER8=0时,分数部分在4位上编码,即USART BRR寄存器中的DIV分数[3:0]位编程。
  • 当OVER8=1时,小数部分在3位上编码,即USART BRR寄存器中的DIV分数[2:0]位编程,并且 DIV_fraction[3]必须保持被清状态。

Note:当波特率寄存器(USART_BRR)被执行了写操作,波特率计数器将也别更新为新值。因此,波特率寄存器的值不应该在通信期间改变

多处理器通讯

将主机的TX和多从机RX引脚相连,可以连接成一个多处理器通讯方式。
在多处理器配置中,通常希望只有预期的消息接收者主动接收完整的消息内容,从而减少所有非寻址接收者的冗余USART服务开销。
通过静音功能,可以将非寻址设备置于静默模式。
在静默模式下:

  • List item1
  • List item2
  • List item3
    串口退出静默模式,需要配置USART_CR1的WAKE 位
  • List item1
  • List item1

地址标记检测(WAKE=1)

奇偶校验

偶校验
奇校验
接收时的校验核算

Note:

发送时校验码的产生

串口局域网模式

串口同步模式

单总线半双工通讯

智能卡

红外模块

用DMA实现数据流通讯

硬件流控制

串口中断

USART 的模式配置

串口的工程应用

工程实践案例

  1. stm32u575 芯片,uart + dma,其芯片没有dma的 循环接收模式,只有正常模式和链表模式,所以在采用正常模式的情况下,需要设计一个uart_receive();函数,其配置dma接收字长,源,目的寄存器。当把此函数放到while循环中的,串口接收解析函数中,即认为接收到了一帧函数,就开启接收另一帧的准备。这么想没有错,但是由于while()循环只有3ms的周期,接收一帧数据的耗时也是1.5ms。那么接收数据的1.5ms期间,有较大概率,执行uart_receive()函数,就会从头接收,导致接收错乱。那么在配置的时候,给发送了数据怎么办,恐怕也有问题,甚至是发生接收完成中断,好麻烦。我们需要把uart_receive()配置接收寄存器函数和接收完成有更强的时序逻辑,才可避免这些问题。放到接收完成中断中,那么就会是真正的在接收到一帧数据后,立即准备好接收下一帧数据,并且有着中断高优先级的保护,不会被打算,有点原子操作的味道。完美解决!
      从上面可总结:1. 嵌入式程序的严密时序逻辑极其重要。2. 配置寄存器和全局变量等都是全局资源,需要格外保护,此例中放到了中断中,有其优先级的保护。

串口发送&接收概述

串口的经典应用无外乎发送接收。其围绕发送和接收的展开以下面为核心,构建工程。

理论学习-ARM-通用串口学习_第7张图片
以服务为核心,即以应用协议为核心展开。
目前我所知串口协议的经典模式,可分为:定长(eg: can),不定长(eg: mudbus)。

  • 定长:以长度判断帧为主,时间为辅,帧头、帧尾为辅。
  • 不定长:以时间判断为辅,帧长度为辅,帧头、帧尾为辅。

以前一种为主。

对于鲁棒性的支持,可分为:数据丢失处理、数据校验错误处理、连接中断处理(token)、重连恢复(token)。

对于总线的类型管理,可分为: 一主多从,分布式。

你可能感兴趣的:(C/C++编程,嵌入式,理论指导,arm,单片机,stm32,1024程序员节)