USART发送与接收

本文围绕STM32的USART展开,介绍了发送过程,包括TX、TXE、USART_DR等相关寄存器及标志位;接收分为多种情况,如有无开启RxFIFO、多缓存通讯模式等;还阐述了超出错误、采样(时钟、模式、数据)以及波特率产生的相关内容,给出了不同模式下的波特率公式。

发送

在这里插入图片描述

  • TX:发生引脚,发生的数据会从 USART_DR 寄存器移位到发送移位寄存器,发送移位寄存器会将数据一位一位的通过 TX 引脚发送出去。
  • TXE:看后文。
  • USART_DR:发送数据寄存器,软件将数据写入该寄存器,从而发送出去。
  • TC:发送完成标志位。如果发送一个帧,并且没有新的数据(帧)写入 USART_DR 寄存器(等价于没有清零 TXE 标志位),当该帧发送结束就会设置 TC 标志位。可以产生相关的 TC 中断。

TXE

在这里插入图片描述
在发送数据时,我们将32位的数据写到 USART_TDR 寄存器中,如果没有启动 TxFIFO 那么该数据就会被移动到 TX Shift Reg 发送移位寄存器上,然后一位一位的发送出去。

如果我们启动了 TxFIFO,那么该数据就会从 USART_TDR 被缓存到 TxFIFO 里,然后我们就可以接着往 USART_TDR 寄存器中写入数据,而不用担心覆盖 USART_TDR 中的数据。

至于 TXE 标志位在这两种情况下有不同的表意:

  • 当没有启动 FIFO :

    • 表明数据已经从 USART_TDR 移动到了 TX Shift Reg 寄存器。
    • USART_TDR 寄存器此时是空的,即可以往 USART_TDR 写入数据。
    • 此时写入 USART_TDR 寄存器不会覆盖先前在 USART_TDR 中的数据。

    我们可以通过设置控制寄存器中的 TXEIE 位,使得 TXE 被设置时,产生中断。

  • 当启动 FIFO :

    • TxFIFO 此时还没有满。

      只要 TxFIFO 没有满,此标志位就会一直被设置为1,即使我们往 USART_TDR 写入了数据,最后该数据填充进了 TxFIFO。只要 TxFIFO 最终没有满,TXE 就会被设置为1。

    • USART_TDR 寄存器此时是空的,即可以往 USART_TDR 写入数据。

    • 此时写入 USART_TDR 寄存器不会覆盖先前在 USART_TDR 中的数据。

    此时我们可以使用 TXFNF 这个中断(当 FIFO 没有满时触发)来代替前面 TXE 中断,通过设置 TXFNFIE 位来设置。

接收

Start bit 检测

在这里插入图片描述

读数据

在这里插入图片描述
接收数据分为三种情况:

  • 情况一:没有开启 RxFIFO

    • 通过设置控制寄存器中的 RXNE 位,来设置将 RX Shift Reg 接收的数据移动到 USART_RDR 寄存器里。
    • 可以通过设置 RXNEIE 位,来使能 RXNE 中断,指示 USART_RDR 中有新的数据到来。
  • 情况二:开启 RxFIFO

    • RXFNE 位用于表明 RxFIFO 不为空。此时我们读取 USART_RDR 寄存器,读取的数据为最先存入 RxFIFO 中的数据,即可严格按照先进先出。
    • 可以设置 RXFNEIE 位来产生 RXFNE 中断,用于表示 RxFIFO 中有新的数据。
  • 情况三:启动了多缓存通讯模式

    • 如果禁止 FIFO。每次接收到数据后 RXNE 会被置位,DMA 会读取 USART_RDR 中的值,然后自动清除 RXNE 位。
    • 如果启动 FIFO。当 RxFIFO 中有数据时 RXFNE 会被置位,这时会触发 DMA 请求,DMA 会从 RxFIFO 中获取数据,直到 RxFIFO 为空。
  • 情况四:单一缓存模式

    • 如果禁止 FIFO。当读取了 USART_RDR 寄存器后,RXNE 会被清除。可以通过写 USART_RQR 寄存器中的 RXFRQ 位来清除 USART_RDR 中的数据,进而清除 RXNE 标志位。

      The RXNE flag must be cleared before the end of the reception of the next character to avoid an overrun error.

    • 如果启动 FIFO。只要 RxFIFO 不为空 RXFNE 就会被置位,读取 USART_RDR 寄存器,会读取最先存入 RxFIFO 中的数据。但 RxFIFO 为空会清除 RXFNE 标志位。可以通过置位 USART_RQR 寄存器的 RXFRQ 位来清空 RxFIFO 内的数据,进而清除 RXFNE 标志位。

      When the RXFIFO is full, the first entry in the RXFIFO must be read before the end of the reception of the next character, to avoid an overrun error.

      如果要读取数据块,可以设置 RxFIFO threshold,当 RxFIFO 中累积接收的数据达到 threshold 值时,可以触发一个 RxFNE 中断。

超出错误(Overrun error)

  • 情况一:没有启动 FIFO

    当 USART_RDR 寄存器中的数据还未被读取(RXNE 未被置位),而此时又有新的数据到达 RX Shift Reg 寄存器,导致 RX Shift Reg 寄存器中的数据无法转移到 USART_RDR 寄存器就会发送 Overrun error。当发送 Overrun error 后:

    • ORE 位会被设置;
    • USART_RDR 寄存器的内容不会丢失,之前的数据仍然有效,可以从 USART_RDR 寄存器中读取;
    • RX Shift Reg 寄存器中的数据将会被覆盖;
    • 将会产生中断,如果设置了 RXNEIE 或者 EIE;
  • 情况二:启动了 FIFO

    这时 Overrun error 会发送在 RX Shift Reg 寄存器有新的数据到来,而 RxFIFO 已经满了。当发送 Overrun error 后:

    • ORE 位会被设置;
    • RxFIFO 中的数据将不会丢失,之前的数据仍然有效,可以从 USART_RDR 寄存器中读取;
    • RX Shift Reg 寄存器中的数据将会被覆盖;
    • 将会产生中断,如果设置了 RXFNEIE 或者 EIE;

    可以通过 USART_ICR 寄存器重置 ORE 。

注意:一旦 ORE 位被设置,则说明至少有一个数据丢失了

如果没有设置 FIFO,有以下两种情况可能会出现 ORE 被设置:

  • RXNE = 1,然后最后一个有效数据存储在 RDR 寄存器。后续的数据发送了 Overrun error。
  • RXNE = 0,这种情况发送在当我们读取 RDR 寄存器的同时有一个新数据达到 RX Shift Reg 寄存器。

采样

采样时钟

USART 的原始时钟来自于 usart_ker_ck 时钟源,该时钟源的来源可以参考下图:
在这里插入图片描述
usart_ker_ck 时钟还可以进一步分频,通过设置 USARTx_PRESC[3:0] 来实现:
在这里插入图片描述
寄存器 USARTx_BBR 记录了 USART 的波特率
在这里插入图片描述

采样模式

STM32H7 系列支持 2 种采样模式,可以通过设置 USART_CR1 寄存器中的 OVER8 位来设置,当其为1时,会采样一个比特会8次,否则采样16次。详细如下:
在这里插入图片描述
采样8次和采样16次影响的是通讯的速率:

  • 采样8次,最大的接收速率为 u s a r t _ k e r _ c k _ p r e s / 8 usart\_ker\_ck\_pres/8 usart_ker_ck_pres/8
  • 采样16次,最大的接收速率为 u s a r t _ k e r _ c k _ p r e s / 16 usart\_ker\_ck\_pres/16 usart_ker_ck_pres/16

采样数据

USART_CR3 寄存器的 ONEBIT 位用于评估逻辑水平,有两种评估方式可选:

  • 在中间的比特中选3个主要的采样结果,当这三者不同时,设置 NE bit;
  • 单一采样:
    • 选择3个采样结果,如果三者不同则拒绝该数据,同于 noise 环境中;
    • 选择单一采样结果,在这种情况下不会设置 NE 位。

当在一个帧中有 noise 后:

  • 当设置 RXNE 或 RXFNE 位时,NE 位会被设置;(Noise detection)
  • 无效的数据会从 Rx Shift Reg 寄存器转移到 USART_RDR 寄存器;
  • single byte communication 模式不会触发中断,因为在该模式下可以设置触发 RXNE 或者 RXFNE 中断。在 multibuffer communication 模式下,也就是使用 DMA,这时如果设置 USART_CR3 寄存器的 EIE 位(Error Interrupt enable)就会触发中断。

例子:
在这里插入图片描述

波特率产生

波特率:表示单位时间内传送的码元符号的个数,它是对符号传输速率的一种度量,它用单位时间内载波调制状态改变的次数来表示,波特率,即指一个单位时间内传输符号的个数。

公式1:标准 USART 模式波特率 (SPI mode included) (OVER8 = ‘0’ or ‘1’)

In case of oversampling by 16, the baud rate is given by the following formula:

T x / R x b a u d = u s a r t _ k e r _ c k p r e s U S A R T D I V Tx/Rx baud = \frac{usart\_ker\_ckpres}{USARTDIV} Tx/Rxbaud=USARTDIVusart_ker_ckpres

In case of oversampling by 8, the baud rate is given by the following formula:

T x / R x b a u d = 2 ∗ u s a r t _ k e r _ c k p r e s U S A R T D I V Tx/Rx baud = \frac{2 * usart\_ker\_ckpres}{USARTDIV} Tx/Rxbaud=USARTDIV2usart_ker_ckpres

公式2:Smartcard, LIN 和 IrDA 模式(OVER8 = 0)

The baud rate is given by the following formula:

T x / R x b a u d = u s a r t _ k e r _ c k p r e s U S A R T D I V Tx/Rx baud = \frac{usart\_ker\_ckpres}{USARTDIV} Tx/Rxbaud=USARTDIVusart_ker_ckpres

详细参考:《STM32HT750BX 参考手册》

### 回答1: 好的,下面是关于STM32 USART发送接收使用DMA的回答: DMA (Direct Memory Access)是一种在不占用CPU的情况下直接进行数据传输的技术。对于STM32USART模块,使用DMA可以大大减轻CPU的负担,提高数据传输效率。 首先,需要配置USART和DMA。可以使用STM32的CubeMX工具来快速生成初始化代码。在配置USART时,需要设置USART的波特率、数据位、停止位和校验位等参数。在配置DMA时,需要设置DMA的传输方向、数据长度、传输模式、优先级和中断等参数。 接下来,可以使用HAL库提供的函数来启动DMA传输。在发送数据时,可以使用函数HAL_UART_Transmit_DMA()启动DMA传输,该函数会将数据存储在指定的缓冲区中,将缓冲区的地址传递给DMA进行传输。在接收数据时,可以使用函数HAL_UART_Receive_DMA()启动DMA传输,该函数会将接收到的数据存储在指定的缓冲区中,将缓冲区的地址传递给DMA进行传输。 在DMA传输完成后,可以使用HAL库提供的回调函数来进行处理。对于发送完成,可以使用函数HAL_UART_TxCpltCallback();对于接收完成,可以使用函数HAL_UART_RxCpltCallback()。 需要注意的是,在使用DMA进行数据传输时,需要确保缓冲区的大小足够大,以便存储需要传输的数据。 希望这个回答能够帮助你了解STM32 USART发送接收使用DMA的相关知识。如果你有任何其他问题,可以随时提出。 ### 回答2: STM32是一种基于ARM Cortex-M内核的微控制器。在STM32中,USART是其中一种通信接口,它可以用于串口通讯,支持同步和异步模式,而DMA是指直接存储器访问,是一种通过硬件优化(减少中央处理器的干预)直接访问外设(如USART)数据的技术。 在STM32中,USART发送接收都可以使用DMA技术来实现。DMA可以减少CPU的干预,提高数据传输效率。使用DMA时,USART的数据传输不再需要中断和CPU参,而是通过DMA控制器直接完成。 在USART发送中,使用DMA可以提高发送速率和可靠性,减轻CPU的 burden。具体实现步骤包括:初始化USART和DMA,选择传输方向设置数据长度和地址,启动DMA传输,检查传输是否完成。 在USART接收中,同样使用DMA可以提高接收速度和减轻CPU压力,具体操作步骤和发送时类似,首先初始化USART和DMA,设置数据长度和地址,选择传输方向启动DMA传输,然后等待数据接收完成,在回调函数中处理接收到的数据。 总之,使用DMA技术可以极大地提高USART的数据传输效率和可靠性。但也要注意在配置和使用时遵循相关规范,避免发生错误。 ### 回答3: STM32是一类广泛应用于微控制器中的芯片,其中USART是一种通信协议,可以实现串行通信。在STM32上,USART不仅支持单字节发送接收,还可以使用DMA实现数据的快速传输。在本文中,我们将探讨STM32USART发送接收时如何使用DMA。 首先,让我们来了解一下DMA(直接存储器访问)的概念。DMA是一种高效的数据传输方式,允许数据在外设和内存之间直接传输,而不需要CPU的干预。在使用DMA进行数据传输时,我们需要设置源地址、目的地址和传输长度,然后启动DMA传输,再次目标数据传输完成,DMA会自动发出传输完成的中断信号。 在STM32中,我们可以通过代码来配置DMA。首先,我们需要定义源地址、目的地址和传输长度,然后将它们写入DMA控制器的相关寄存器。为了使用USARTDMA进行数据传输,我们还需要将DMAUSART相关的寄存器连接起来。在最后一步,我们需要启动DMA传输,等待传输完成中断信号。 使用DMA进行USART发送接收操作,需要针对每个操作分别进行配置。在发送方面,我们需要设置USART的数据寄存器作为源地址,DMA的数据寄存器作为目的地址,将传输长度设置为待发送的字节数。在接收方面,我们需要设置USART的数据寄存器作为目的地址,DMA的数据寄存器作为源地址,将传输长度设置为接收缓冲区的大小。 总之,使用DMA进行USART发送接收操作可以大大提高数据传输效率和操作速度。但是,需要注意的是,在进行DMA配置时需要仔细处理相关寄存器和缓冲区,否则可能会导致数据传输错误。因此,在使用DMA进行通信之前,我们应该对USART和DMA的相关概念有一定的理解,根据具体的需求进行合理的配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值