第二十四章 通用同步异步收发器(USART)
目录
1 USART 介绍
通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准 NRZ 异步串行数据格式的外部设备之间进行全双工数据交换。USART 利用分数波特率发生器提供宽范围的波特率选择。
它支持同步单向通信和半双工单线通信,也支持 LIN(局部互连网),智能卡协议和 IrDA(红外数据组织)SIRENDEC 规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的 DMA 方式,可以实现高速数据通信。
2 USART 主要特性
W55MH32的USART的主要特性有:
- 全双工的,异步通信
- NRZ 标准格式
- 分数波特率发生器系统
- 发送和接收共用的可编程波特率,最高达 4.5Mbits/s
- 可编程数据字长度(8 位或 9 位)
- 可配置的停止位-支持 1 或 2 个停止位
- LIN 主发送同步断开符的能力以及 LIN 从检测断开符的能力
- 当 USART 硬件配置成 LIN 时,生成 13 位断开符;检测 10/11 位断开符
- 发送方为同步传输提供时钟
- IRDASIR 编码器解码器
- 在正常模式下支持 3/16 位的持续时间
- 智能卡模拟功能
- 智能卡接口支持 ISO7816-3 标准里定义的异步智能卡协议
- 智能卡用到的 0.5 和 1.5 个停止位
- 单线半双工通信
- 可配置的使用 DMA 的多缓冲器通信
- 在 SRAM 里利用集中式 DMA 缓冲接收/发送字节
- 单独的发送器和接收器使能位
- 检测标志
- 接收缓冲器满
- 发送缓冲器空
- 传输结束标志
- 校验控制
- 发送校验位
- 对接收数据进行校验
- 四个错误检测标志
- 溢出错误
- 噪音错误
- 帧错误
- 校验错误
- 10 个带标志的中断源
- CTS 改变
- LIN 断开符检测
- 发送数据寄存器空
- 发送完成
- 接收数据寄存器满
- 检测到总线为空闲
- 溢出错误
- 帧错误
- 噪音错误
- 校验错误
- 多处理器通信--如果地址不匹配,则进入静默模式
- 从静默模式中唤醒(通过空闲总线检测或地址标志检测)
- 两种唤醒接收器的方式:地址位(MSB,第 9 位),总线空闲
3 USART 功能概述
接口通过三个引脚与其他设备连接在一起(见图 249)。任何 USART 双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。
RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。
TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的 I/O 端口配置。当发送器被激活,并且不发送数据时,TX 引脚处于高电平。在单线和智能卡模式里,此 I/O 口被同时用于数据的发送和接收。
- 总线在发送或接收前应处于空闲状态
- 一个起始位
- 一个数据字(8 或 9 位),最低有效位在前
- 0.5,1.5,2 个的停止位,由此表明数据帧的结束
- 使用分数波特率发生器——12 位整数和 4 位小数的表示方法。
- 一个状态寄存器(USART_SR)
- 数据寄存器(USART_DR)
- 一个波特率寄存器(USART_BRR),12 位的整数和 4 位小数
- 一个智能卡模式下的保护时间寄存器(USART_GTPR)
关于以上寄存器中每个位的具体定义,请参考寄存器描述第 23.6 节:USART 寄存器描述。在同步模式中需要下列引脚:
- CK:发送器时钟输出。此引脚输出用于同步传输的时钟,(在 Start 位和 Stop 位上没有时钟脉冲,软件可选地,可以在最后一个数据位送出一个时钟脉冲)。数据可以在 RX 上同步被接收。
这可以用来控制带有移位寄存器的外部设备(例如 LCD 驱动器)。时钟相位和极性都是软件可编程的。在智能卡模式里,CK 可以为智能卡提供时钟。在 IrDA 模式里需要下列引脚:
- IrDA_RDI:IrDA 模式下的数据输入。
- IrDA_TDO:IrDA 模式下的数据输出。下列引脚在硬件流控模式中需要:
接口通过三个引脚与其他设备连接在一起(见图 249)。任何 USART 双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。
RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。
TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的 I/O 端口配置。当发送器被激活,并且不发送数据时,TX 引脚处于高电平。在单线和智能卡模式里,此 I/O 口被同时用于数据的发送和接收。
- 总线在发送或接收前应处于空闲状态
- 一个起始位
- 一个数据字(8 或 9 位),最低有效位在前
- 0.5,1.5,2 个的停止位,由此表明数据帧的结束
- 使用分数波特率发生器——12 位整数和 4 位小数的表示方法。
- 一个状态寄存器(USART_SR)
- 数据寄存器(USART_DR)
- 一个波特率寄存器(USART_BRR),12 位的整数和 4 位小数
- 一个智能卡模式下的保护时间寄存器(USART_GTPR)
关于以上寄存器中每个位的具体定义,请参考寄存器描述第 23.6 节:USART 寄存器描述。在同步模式中需要下列引脚:
- CK:发送器时钟输出。此引脚输出用于同步传输的时钟,(在 Start 位和 Stop 位上没有时钟脉冲,软件可选地,可以在最后一个数据位送出一个时钟脉冲)。数据可以在 RX 上同步被接收。这可以用来控制带有移位寄存器的外部设备(例如 LCD 驱动器)。时钟相位和极性都是软件可编程的。在智能卡模式里,CK 可以为智能卡提供时钟。在 IrDA 模式里需要下列引脚:
- IrDA_RDI:IrDA 模式下的数据输入。
- IrDA_TDO:IrDA 模式下的数据输出。下列引脚在硬件流控模式中需要:
USART 框图
3.1 USART 特性描述
字长可以通过编程 USART_CR1 寄存器中的 M 位,选择成 8 或 9 位(见图 230)。在起始位期间,TX脚处于低电平,在停止位期间处于高电平。
空闲符号被视为完全由'1'组成的一个完整的数据帧,后面跟着包含了数据的下一帧的开始位(‘1'的位数也包括了停止位的位数)。
断开符号被视为在一个帧周期内全部收到'0'(包括停止位期间,也是'0')。在断开帧结束时,发送器再插入 1 或 2 个停止位(‘1')来应答起始位。
发送和接收由一共用的波特率发生器驱动,当发送器和接收器的使能位分别置位时,分别为其产生时钟。
随后将有每个功能块的详细说明。
字长设置
3.2 发送器
发送器根据 M 位的状态发送 8 位或 9 位的数据字。当发送使能位(TE)被设置时,发送移位寄存器中的数据在 TX 脚上输出,相应的时钟脉冲在 CK 脚上输出。
字符发送
在 USART 发送期间,在 TX 引脚上首先移出数据的最低有效位。在此模式里,USART_DR 寄存器包含了一个内部总线和发送移位寄存器之间的缓冲器(见图 249)。
每个字符之前都有一个低电平的起始位;之后跟着的停止位,其数目可配置。USART 支持多种停止位的配置:0.5、1、1.5 和 2 个停止位。
注: 1.在数据传输期间不能复位 TE 位,否则将破坏 TX 脚上的数据,因为波特率计数器停止计数。正在传输的当前数据将丢失。
2.TE 位被激活后将发送一个空闲帧。
可配置的停止位
随每个字符发送的停止位的位数可以通过控制寄存器 2 的位 13、12 进行编程。
1. 1 个停止位:停止位位数的默认值。
2. 2 个停止位:可用于常规 USART 模式、单线模式以及调制解调器模式。
3. 0.5 个停止位:在智能卡模式下接收数据时使用。
4. 1.5 个停止位:在智能卡模式下发送和接收数据时使用。
空闲帧包括了停止位。
断开帧是 10 位低电平,后跟停止位(当 m=0 时);或者 11 位低电平,后跟停止位(m=1 时)。不可能传输更长的断开帧(长度大于 10 或者 11 位)。
配置停止位
配置步骤:
1. 通过在 USART_CR1 寄存器上置位 UE 位来激活 USART
2. 编程 USART_CR1 的 M 位来定义字长。
3. 在 USART_CR2 中编程停止位的位数。
4. 如果采用多缓冲器通信,配置 USART_CR3 中的 DMA 使能位(DMAT)。按多缓冲器通信中的描述配置 DMA 寄存器。
5. 利用 USART_BRR 寄存器选择要求的波特率。
6. 设置 USART_CR1 中的 TE 位,发送一个空闲帧作为第一次数据发送。
7. 把要发送的数据写进 USART_DR 寄存器(此动作清除 TXE 位)。在只有一个缓冲器的情况下,
对每个待发送的数据重复步骤 7。
8. 在 USART_DR 寄存器中写入最后一个数据字后,要等待 TC=1,它表示最后一个数据帧的传输结束。当需要关闭 USART 或需要进入停机模式之前,需要确认传输结束,避免破坏最后一次传输。
单字节通信
清零 TXE 位总是通过对数据寄存器的写操作来完成的。TXE 位由硬件来设置,它表明:
- 数据已经从 TDR 移送到移位寄存器,数据发送已经开始
- TDR 寄存器被清空
下一个数据可以被写进 USART_DR 寄存器而不会覆盖先前的数据如果 TXEIE 位被设置,此标志将产生一个中断。
如果此时 USART 正在发送数据,对 USART_DR 寄存器的写操作把数据存进 TDR 寄存器,并在当前传输结束时把该数据复制进移位寄存器。
如果此时 USART 没有在发送数据,处于空闲状态,对 USART_DR 寄存器的写操作直接把数据放进移位寄存器,数据传输开始,TXE 位立即被置起。当一帧发送完成时(停止位发送后)并且设置了 TXE 位,TC 位被置起,如果 USART_CR1 寄存器中的 TCIE 位被置起时,则会产生中断。在 USART_DR 寄存器中写入了最后一个数据字后,在关闭 USART 模块之前或设置微控制器进入低功耗模式(详见下图)之前,必须先等待 TC=1。使用下列软件过程清除 TC 位:
1.读一次 USART_SR 寄存器;
2.写一次 USART_DR 寄存器。
注: TC 位也可以通过软件对它写'0'来清除。此清零方式只推荐在多缓冲器通信模式下使用。
发送时 TC/TXE 的变化情况
断开符号
设置 SBK 可发送一个断开符号。断开帧长度取决 M 位(见图 230)。如果设置 SBK=1,在完成当前数据发送后,将在 TX 线上发送一个断开符号。断开字符发送完成时(在断开符号的停止位时)SBK 被硬件复位。USART 在最后一个断开帧的结束处插入一逻辑'1',以保证能识别下一帧的起始位。
注意: 如果在开始发送断开帧之前,软件又复位了 SBK 位,断开符号将不被发送。如果要发送两个连续的断开帧,SBK 位应该在前一个断开符号的停止位之后置起。
空闲符号:置位 TE 将使得 USART 在第一个数据帧前发送一空闲帧。
3.3 接收器
USART 可以根据 USART_CR1 的 M 位接收 8 位或 9 位的数据字。
起始位侦测
在 USART 中,如果辨认出一个特殊的采样序列,那么就认为侦测到一个起始位。
该序列为:1110X0X0X0000
起始位侦测
注意: 如果该序列不完整,那么接收端将退出起始位侦测并回到空闲状态(不设置标志位)等待下降沿。如果 3 个采样点都为'0'(在第 3、5、7 位的第一次采样,和在第 8、9、10 的第二次采样都为'0'),则确认收到起始位,这时设置 RXNE 标志位,如果 RXNEIE=1,则产生中断。
如果两次 3 个采样点上仅有 2 个是'0'(第 3、5、7 位的采样点和第 8、9、10 位的采样点),那么起始位仍然是有效的,但是会设置 NE 噪声标志位。如果不能满足这个条件,则中止起始位的侦测过程,接收器会回到空闲状态(不设置标志位)。如果有一次 3 个采样点上仅有 2 个是'0'(第 3、5、7 位的采样点或第 8、9、10 位的采样点),那么起始位仍然是有效的,但是会设置 NE 噪声标志位
字符接收
在 USART 接收期间,数据的最低有效位首先从 RX 脚移进。在此模式里,USART_DR 寄存器包含的缓冲器位于内部总线和接收移位寄存器之间。
配置步骤:
1. 将 USART_CR1 寄存器的 UE 置 1 来激活 USART。
2. 编程 USART_CR1 的 M 位定义字长
3. 在 USART_CR2 中编写停止位的个数
4. 如果需多缓冲器通信,选择 USART_CR3 中的 DMA 使能位(DMAR)。按多缓冲器通信所要求的配置 DMA 寄存器。
5. 利用波特率寄存器 USART_BRR 选择希望的波特率。
6. 设置 USART_CR1 的 RE 位。激活接收器,使它开始寻找起始位。当一字符被接收到时,
- RXNE位被置位。它表明移位寄存器的内容被转移到 RDR。换句话说,数据已经被接收并且可以被读出(包括与之有关的错误标志)。
- 如果 RXNEIE 位被设置,产生中断。
- 在接收期间如果检测到帧错误,噪音或溢出错误,错误标志将被置起,
- 在多缓冲器通信时,RXNE 在每个字节接收后被置起,并由 DMA 对数据寄存器的读操作而清零。
- 在单缓冲器模式里,由软件读 USART_DR 寄存器完成对 RXNE 位清除。RXNE 标志也可以通过对它写 0 来清除。RXNE 位必须在下一字符接收结束前被清零,以避免溢出错误。
注意: 在接收数据时,RE 位不应该被复位。如果 RE 位在接收时被清零,当前字节的接收被丢失。
断开符号
当接收到一个断开帧时,USART 像处理帧错误一样处理它。
空闲符号
当一空闲帧被检测到时,其处理步骤和接收到普通数据帧一样,但如果 IDLEIE 位被设置将产生一个中断。
溢出错误
如果 RXNE 还没有被复位,又接收到一个字符,则发生溢出错误。数据只有当 RXNE 位被清零后才能从移位寄存器转移到 RDR 寄存器。RXNE 标记是接收到每个字节后被置位的。如果下一个数据已被收到或先前 DMA 请求还没被服务时,RXNE 标志仍是置起的,溢出错误产生。当溢出错误产生时:
- ORE 位被置位。
- RDR 内容将不会丢失。读 USART_DR 寄存器仍能得到先前的数据。
- 移位寄存器中以前的内容将被覆盖。随后接收到的数据都将丢失。
- 如果 RXNEIE 位被设置或 EIE 和 DMAR 位都被设置,中断产生。
- 顺序执行对 USART_SR 和 USART_DR 寄存器的读操作,可复位 ORE 位
注意: 当 ORE 位置位时,表明至少有 1 个数据已经丢失。有两种可能性:
- 如果 RXNE=1,上一个有效数据还在接收寄存器 RDR 上,可以被读出。
- 如果 RXNE=0,这意味着上一个有效数据已经被读走,RDR已经没有东西可读。当上一个有效数据在 RDR 中被读取的同时又接收到新的(也就是丢失的)数据时,此种情况可能发生。在读序列期间(在 USART_SR 寄存器读访问和 USART_DR 读访问之间)接收到新的数据,此种情况也可能发生。
噪音错误
使用过采样技术(同步模式除外),通过区别有效输入数据和噪音来进行数据恢复。
检测噪声的数据采样
检测噪声的数据采样
采样值 | NE 状态 | 接收的位 | 数据有效性 |
000 | 0 | 0 | 有效 |
001 | 1 | 0 | 无效 |
010 | 1 | 0 | 无效 |
011 | 1 | 1 | 无效 |
100 | 1 | 0 | 无效 |
101 | 1 | 1 | 无效 |
110 | 1 | 1 | 无效 |
111 | 0 | 1 | 有效 |
当在接收帧中检测到噪音时:
- 在 RXNE 位的上升沿设置 NE 标志。
- 无效数据从移位寄存器传送到 USART_DR 寄存器。
- 在单个字节通信情况下,没有中断产生。然而,因为 NE 标志位和 RXNE 标志位是同时被设置,RXNE 将产生中断。在多缓冲器通信情况下,如果已经设置了 USART_CR3 寄存器中 EIE 位,将产生一个中断。先读出 USART_SR,再读出 USART_DR 寄存器,将清除 NE 标志位。
帧错误
当以下情况发生时检测到帧错误:
由于没有同步上或大量噪音的原因,停止位没有在预期的时间上接和收识别出来。
当帧错误被检测到时:
- FE 位被硬件置起
- 无效数据从移位寄存器传送到 USART_DR 寄存器。
- 在单字节通信时,没有中断产生。然而,这个位和 RXNE 位同时置起,后者将产生中断。在多缓冲器通信情况下,如果 USART_CR3 寄存器中 EIE 位被置位的话,将产生中断。顺序执行对 USART_SR 和 USART_DR 寄存器的读操作,可复位 FE 位。接收期间的可配置的停止位被接收的停止位的个数可以通过控制寄存器 2的控制位来配置,在正常模式时,可以是 1或 2个,在智能卡模式里可能是 0.5 或 1.5 个。
1. 0.5 个停止位(智能卡模式中的接收):不对 0.5 个停止位进行采样。因此,如果选择 0.5 个停止位则不能检测帧错误和断开帧。
2. 1 个停止位:对 1 个停止位的采样在第 8,第 9 和第 10 采样点上进行。
3. 1.5 个停止位(智能卡模式):当以智能卡模式发送时,器件必须检查数据是否被正确的发送出去。所以接收器功能块必须被激活(USART_CR1 寄存器中的 RE=1),并且在停止位的发送期间采样数据线上的信号。如果出现校验错误,智能卡会在发送方采样 NACK 信号时,即总线上停止位对应的时间内时,拉低数据线,以此表示出现了帧错误。FE 在 1.5 个停止位结束时和RXNE 一起被置起。对 1.5 个停止位的采样是在第 16,第 17 和第 18 采样点进行的。1.5 个的停止位可以被分成 2 部分:一个是 0.5 个时钟周期,期间不做任何事情。随后是 1 个时钟周期的停止位,在这段时间的中点处采样。详见第 23.3.11 节:智能卡。
4. 2 个停止位:对 2 个停止位的采样是在第一停止位的第 8,第 9 和第 10 个采样点完成的。如果第一个停止位期间检测到一个帧错误,帧错误标志将被设置。第二个停止位不再检查帧错误。在第一个停止位结束时 RXNE 标志将被设置。
3.4 分数波特率的产生
接收器和发送器的波特率在 USARTDIV 的整数和小数寄存器中的值应设置成相同。
Tx/Rx波特率 = fck/(16 ∗ USARTDIV)这里的 fCK 是给外设的时钟(PCLK1 用于 USART2、3、4、5,PCLK2 用于 USART1)USARTDIV 是一个无符号的定点数。这 12 位的值设置在 USART_BRR 寄存器。
注: 在写入 USART_BRR 之后,波特率计数器会被波特率寄存器的新值替换。因此,不要在通信进行中改变波特率寄存器的数值
如何从 USART_BRR 寄存器值得到 USARTDIV
例 1:
如果 DIV_Mantissa=0d27,DIV_Fraction=0d12(USART_BRR=0x1BC),
于是:
Mantissa(USARTDIV)=0d27
Fraction(USARTDIV)=12/16=0d0.75
所以 USARTDIV=0d27.75
例 2:
要求 USARTDIV=0d25.62,
就有:
DIV_Fraction=16*0.62=0d9.92
最接近的整数是:10=0x0A
DIV_Mantissa=mantissa(0d25.620)=0d25=0x19
于是,USART_BRR=0x19A 因此 USARTDIV = 0d25.625
例 3:
要求 USARTDIV=0d50.99
就有:
DIV_Fraction=16*0d0.99=0d15.84
最接近的整数是:16=0x10=>DIV_frac[3:0]溢出=>进位必须加到小数部分
DIV_Mantissa=mantissa(0d50.990+进位)=0d51=0x33
于是:USART_BRR=0x330,USARTDIV=0d51.000
设置波特率时的误差计算
序号 | 波特率 (Kbps) | fPCLK=36MHz | fPCLK=72MHz | ||||
实际 | 置于波特率寄存器中的值 | 误差 % | 实际 | 置于波特率寄存器中的值 | 误差 % | ||
1 | 2.4 | 2.400 | 937.5 | 0% | 2.4 | 1875 | 0% |
2 | 9.6 | 9.600 | 234.375 | 0% | 9.6 | 468.75 | 0% |
3 | 19.2 | 19.2 | 117.1875 | 0% | 19.2 | 234.375 | 0% |
4 | 57.6 | 57.6 | 39.0625 | 0% | 57.6 | 78.125 | 0% |
5 | 115.2 | 115.384 | 19.5 | 0.15% | 115.2 | 39.0625 | 0% |
6 | 230.4 | 230.769 | 9.75 | 0.16% | 230.769 | 19.5 | 0.16% |
7 | 460.8 | 461.538 | 4.875 | 0.16% | 461.538 | 9.75 | 0.16% |
8 | 921.6 | 923.076 | 2.4375 | 0.16% | 923.076 | 4.875 | 0.16% |
9 | 2250 | 2250 | 1 | 0% | 2250 | 2 | 0% |
分享波特率和误差%之间有什么关系?
fPCLK为72MHz时,置于波特率寄存器中的值能否小于实际值?
如何根据实际需求选择合适的波特率?
注: 1.CPU 的时钟频率越低,则某一特定波特率的误差也越低。可以达到的波特率上限可以由这组数据得到。
只有 USART1 使用 PCLK2(最高 72MHz)。其它 USART 使用 PCLK1(最高 36MHz)。
3.5 USART 接收器容忍时钟的变化
只有当整体的时钟系统地变化小于 USART 异步接收器能够容忍的范围,USART 异步接收器才能正常地工作。影响这些变化的因素有:
- DTRA:由于发送器误差而产生的变化(包括发送器端振荡器的变化)
- DQUANT:接收器端波特率取整所产生的误差
- DREC:接收器端振荡器的变化
- DTCL:由于传输线路产生的变化(通常是由于收发器在由低变高的转换时序,与由高变低转换时序之间的不一致性所造成)。需要满足:DTRA+DQUANT+DREC+DTCL<USART 接收器的容忍度对于正常接收数据,USART 接收器的容忍度等于最大能容忍的变化,它依赖于下述选择:
- 由 USART_CR1 寄存器的 M 位定义的 10 或 11 位字符长度
- 是否使用分数波特率产生
当 DIV_Fraction=0 时,USART 接收器的容忍度
M 位 | 认为 NF 是错误 | 不认为 NF 是错误 |
0 | 3.75% | 4.375% |
1 | 3.41% | 3.97% |
当 DIV_Fraction!=0 时,USART 接收器的容忍度
M 位 | 认为 NF 是错误 | 不认为 NF 是错误 |
0 | 3.33% | 3.88% |
1 | 3.03% | 3.53% |
注: 在特殊的情况下,即当收到的帧包含一些在 M=0 时,正好是 10 位(M=1 时是 11 位)的空闲帧,上面 2 个表格中的数据可能会有少许出入
3.6 多处理器通信
通过 USART 可以实现多处理器通信(将几个 USART 连在一个网络里)。例如某个 USART 设备可以是主,它的 TX 输出和其他 USART 从设备的 RX 输入相连接;USART 从设备各自的 TX 输出逻辑地与在一起,并且和主设备的 RX 输入相连接。
在多处理器配置中,我们通常希望只有被寻址的接收者才被激活,来接收随后的数据,这样就可以减少由未被寻址的接收器的参与带来的多余的 USART 服务开销。未被寻址的设备可启用其静默功能置于静默模式。在静默模式里:
- 任何接收状态位都不会被设置。
- 所有接收中断被禁止。
- USART_CR1 寄存器中的 RWU 位被置 1。RWU 可以被硬件自动控制或在某个条件下由软件写入。
根据 USART_CR1 寄存器中的 WAKE 位状态,USART 可以用二种方法进入或退出静默模式。
- 如果 WAKE 位被复位:进行空闲总线检测。
- 如果 WAKE 位被设置:进行地址标记检测。
空闲总线检测(WAKE=0)
当 RWU 位被写 1 时,USART 进入静默模式。当检测到一空闲帧时,它被唤醒。然后 RWU 被硬件清零,但是 USART_SR 寄存器中的 IDLE 位并不置起。RWU 还可以被软件写 0。下图给出利用空闲总线检测来唤醒和进入静默模式的一个例子
利用空闲总线检测的静默模式
地址标记(addressmark)检测(WAKE=1)
在这个模式里,如果 MSB 是 1,该字节被认为是地址,否则被认为是数据。在一个地址字节中,目标接收器的地址被放在 4 个 LSB 中。这个 4 位地址被接收器同它自己地址做比较,接收器的地址被编程在 USART_CR2 寄存器的 ADD。
如果接收到的字节与它的编程地址不匹配时,USART 进入静默模式。此时,硬件设置 RWU 位。接收该字节既不会设置 RXNE 标志也不会产生中断或发出 DMA 请求,因为 USART 已经在静默模式。当接收到的字节与接收器内编程地址匹配时,USART 退出静默模式。然后 RWU 位被清零,随后的字节被正常接收。收到这个匹配的地址字节时将设置 RXNE 位,因为 RWU 位已被清零。当接收缓冲器不包含数据时(USART_SR 的 RXNE=0),RWU 位可以被写 0 或 1。否则,该次写操作被忽略。下图给出利用地址标记检测来唤醒和进入静默模式的例子。
利用地址标记检测的静默模式
3.7 校验控制
设置 USART_CR1 寄存器上的 PCE 位,可以使能奇偶控制(发送时生成一个奇偶位,接收时进行奇偶校验)。根据 M 位定义的帧长度,可能的 USART 帧格式列在下表中。
帧格式
M 位 | PCE 位 | USART 帧 |
0 | 0 | 起始位、8 位数据、停止位 |
0 | 1 | 起始位、7 位数据、奇偶检验位、停止位 |
1 | 0 | 起始位、9 位数据、停止位 |
1 | 1 | 起始位、8 位数据、奇偶检验位、停止位 |
注意: 在用地址标记唤醒设备时,地址的匹配只考虑到数据的 MSB 位,而不用关心校验位。(MSB 是数据位中最后发出的,后面紧跟校验位或者停止位)
偶校验:校验位使得一帧中的 7 或 8 个 LSB 数据以及校验位中'1'的个数为偶数。
例如:数据=00110101,有 4 个'1',如果选择偶校验(在 USART_CR1 中的 PS=0),校验位将是'0'。
奇校验:此校验位使得一帧中的 7 或 8 个 LSB 数据以及校验位中'1'的个数为奇数。
例如:数据=00110101,有 4 个'1',如果选择奇校验(在 USART_CR1 中的 PS=1),校验位将是'1'。
传输模式:如果 USART_CR1 的 PCE 位被置位,写进数据寄存器的数据的 MSB 位被校验位替换后发送出去(如果选择偶校验偶数个'1',如果选择奇校验奇数个'1')。如果奇偶校验失败,USART_SR寄存器中的 PE 标志被置'1',并且如果 USART_CR1 寄存器的 PEIE 在被预先设置的话,中断产生。
3.8 LIN(局域互联网)模式
LIN 模式是通过设置 USART_CR2 寄存器的 LINEN 位选择。在 LIN 模式下,下列位必须保持为 0:
- USART_CR2 寄存器的 CLKEN 位
- USART_CR3 寄存器的 STOP[1:0],SCEN,HDSEL 和 IREN
LIN 发送
23.3.2 节里所描述的同样步骤适用于 LIN 主发送,但和正常 USART 发送有以下区别:
- 清零 M 位以配置 8 位字长
- 置位LINEN位以进入LIN模式。这时,置位SBK将发送13位'0'作为断开符号。然后发一位'1',以允许对下一个开始位的检测。
LIN 接收
当 LIN 模式被使能时,断开符号检测电路被激活。该检测完全独立于 USART 接收器。断开符号只要一出现就能检测到,不管是在总线空闲时还是在发送某数据帧其间,数据帧还未完成,又插入了断开符号的发送。
当接收器被激活时(USART_CR1 的 RE=1),电路监测 RX 上的起始信号。监测起始位的方法同检测断开符号或数据是一样的。当起始位被检测到后,电路对每个接下来的位,在每个位的第 8,9,10 个过采样时钟点上进行采样。如果 10 个(当 USART_CR2 的 LBDL=0)或 11 个(当 USART_CR2 的LBDL=1)连续位都是'0',并且又跟着一个定界符,USART_SR 的 LBD 标志被设置。如果 LBDIE 位=1,中断产生。在确认断开符号前,要检查定界符,因为它意味 RX 线已经回到高电平。如果在第 10 或 11 个采样点之前采样到了'1',检测电路取消当前检测并重新寻找起始位。如果 LIN模式被禁止,接收器继续如正常 USART 那样工作,不需要考虑检测断开符号。如果 LIN 模式没有被激活(LINEN=0),接收器仍然正常工作于 USART 模式,不会进行断开检测。如果 LIN 模式被激活(LINEN=1),只要一发生帧错误(也就是停止位检测到'0',这种情况出现在断开帧),接收器就停止,直到断开符号检测电路接收到一个'1'(这种情况发生于断开符号没有完整的发出来),或一个定界符(这种情况发生于已经检测到一个完整的断开符号)。
LIN 模式下的断开检测(11 位断开长度–设置了 LBDL 位)
LIN 模式下的断开检测与帧错误的检测
3.9 USART 同步模式
通过在 USART_CR2 寄存器上写 CLKEN 位选择同步模式
在同步模式里,下列位必须保持清零状态:
- USART_CR2 寄存器中的 LINEN 位
- USART_CR3 寄存器中的 SCEN,HDSEL 和 IREN 位
USART 允许用户以主模式方式控制双向同步串行通信。CK 脚是 USART 发送器时钟的输出。在起始位和停止位期间,CK 脚上没有时钟脉冲。根据 USART_CR2 寄存器中 LBCL 位的状态,决定在最后一个有效数据位期间产生或不产生时钟脉冲。USART_CR2 寄存器的 CPOL 位允许用户选择时钟极性,USART_CR2 寄存器上的 CPHA 位允许用户选择外部时钟的相位(见图 239、图 260 和图 261)。在总线空闲期间,实际数据到来之前以及发送断开符号的时候,外部 CK 时钟不被激活。同步模式时,USART 发送器和异步模式里工作一模一样。但是因为 CK 是与 TX 同步的(根据 CPOL和 CPHA),所以 TX 上的数据是随 CK 同步发出的。
同步模式的 USART 接收器工作方式与异步模式不同。如果 RE=1,数据在 CK 上采样(根据 CPOL 和CPHA 决定在上升沿还是下降沿),不需要任何的过采样。但必须考虑建立时间和持续时间(取决于波特率,1/16 位时间)。
注意: 1.CK 脚同 TX 脚一起联合工作。因而,只有在使能了发送器(TE=1),并且发送数据时(写入数据至 USART_DR 寄存器)才提供时钟。这意味着在没有发送数据时是不可能接收一个同步数据的。
2.LBCL,CPOL 和 CPHA 位的正确配置,应该在发送器和接收器都被禁止时;当使能了发送器或接收器时,这些位不能被改变
3.建议在同一条指令中设置 TE 和 RE,以减少接收器的建立时间和保持时间。
4.USART 只支持主模式:它不能用来自其他设备的输入时钟接收或发送数据(CK 永远是输出)。
USART 同步传输的例子
USART 数据时钟时序示例(M=0)
USART 数据时钟时序示例(M=1)
RX 数据采样/保持时间
注: 在智能卡模式下 CK 的功能不同,有关细节请参考智能卡模式部分。
3.10 单线半双工通信
单线半双方模式通过设置 USART_CR3 寄存器的 HDSEL 位选择。在这个模式里,下面的位必须保
持清零状态:
- USART_CR2 寄存器的 LINEN 和 CLKEN 位
- USART_CR3 寄存器的 SCEN 和 IREN 位
- USART 可以配置成遵循单线半双工协议。在单线半双工模式下,TX 和 RX 引脚在芯片内部互连。使用控制位”HALF DUPLEX SEL”(USART_CR3 中的 HDSEL 位)选择半双工和全双工通信。当 HDSEL为'1'时
- RX 不再被使用
- 当没有数据传输时,TX 总是被释放。因此,它在空闲状态的或接收状态时表现为一个标准I/O 口。这就意味该 I/O 在不被 USART 驱动时,必须配置成悬空输入(或开漏的输出高)。
除此以外,通信与正常 USART 模式类似。由软件来管理线上的冲突(例如通过使用一个中央仲裁器)。特别的是,发送从不会被硬件所阻碍。当 TE 位被设置时,只要数据一写到数据寄存器上,发送就继续。
3.11 智能卡
设置 USART_CR3 寄存器的 SCEN 位选择智能卡模式。在智能卡模式下,下列位必须保持清零:
- USART_CR2 寄存器的 LINEN 位
- USART_CR3 寄存器的 HDSEL 位和 IREN 位
此外,CLKEN 位可以被设置,以提供时钟给智能卡。
该接口符合 ISO7816-3 标准,支持智能卡异步协议。USART 应该被设置为:
- 8 位数据位加校验位:此时 USART_CR1 寄存器中 M=1、PCE=1
- 发送和接收时为 1.5 个停止位:即 USART_CR2 寄存器的 STOP=11
注: 也可以在接收时选择 0.5 个停止位,但为了避免在 2 种配置间转换,建议在发送和接收时使用1.5 个停止位。下图给出的例子说明了数据线上,在有校验错误和没校验错误两种情况下的信号。
ISO7816-3 异步协议
当与智能卡相连接时,USART 的 TX 驱动一根智能卡也驱动的双向线。为了做到这点,SW_RX 必须和 TX 连接到相同的 I/O 口。在发送开始位和数据字节期间,发送器的输出使能位 TX_EN 被置起,在发送停止位期间被释放(弱上拉),因此在发现校验错误的情况下接收器可以将数据线拉低。
如果 TX_EN 不被使用,在停止位期间 TX 被拉到高电平:这样的话,只要 TX 配置成开漏,接收器也可以驱动这根线。智能卡是一个单线半双工通信协议
- 从发送移位寄存器把数据发送出去,要被延时最小 1/2 波特时钟。在正常操作时,一个满的发送移位寄存器将在下一个波特时钟沿开始向外移出数据。在智能卡模式里,此发送被延迟1/2 波特时钟。
- 如果在接收一个设置为 0.5 或 1.5 个停止位的数据帧期间,检测到一奇偶校验错误,在完成接收该帧后(即停止位结束时),发送线被拉低一个波特时钟周期。这是告诉智能卡发送到USART 的数据没有被正确地接收到。此 NACK 信号(拉低发送线一个波特时钟周期)在发送端将产生一个帧错误(发送端被配置成 1.5 个停止位)。应用程序可以根据协议处理重新发送数据。如果设置了 NACK 控制位,发生校验错误时接收器会给出一个 NACK 信号;否则就不会发送 NACK。
- TC 标志的置起可以通过编程保护时间寄存器得以延时。在正常操作时,当发送移位寄存器变空并且没有新的发送请求出现时,TC 被置起。在智能卡模式里,空的发送移位寄存器将触发保护时间计数器开始向上计数,直到保护时间寄存器中的值。TC 在这段时间被强制拉低。当保护时间计数器达到保护时间寄存器中的值时,TC 被置高。
- TC 标志的撤销不受智能卡模式的影响。
- 如果发送器检测到一个帧错误(收到接收器的 NACK 信号),发送器的接收功能模块不会把NACK 当作起始位检测。根据 ISO 协议,接收到的 NACK 的持续时间可以是 1 或 2 波特时钟周期。
- 在接收器这边,如果一个校验错误被检测到,并且 NACK 被发送,接收器不会把 NACK 检测成起始位。
注意: 1.断开符号在智能卡模式里没有意义。一个带帧错误的 00h 数据将被当成数据而不是断开符号。
2.当来回切换 TE 位时,没有 IDLE 帧被发送。ISO 协议没有定义 IDLE 帧。
下图详述了 USART 是如何采样 NACK 信号的。在这个例子里,USART 正在发送数据,并且被配置成 1.5 个停止位。为了检查数据的完整性和 NACK 信号,USART 的接收功能块被激活。
使用 1.5 停止位检测奇偶检验错
USART 可以通过 CK 输出为智能卡提供时钟。在智能卡模式里,CK 不和通信直接关联,而是先通过一个 5 位预分频器简单地用内部的外设输入时钟来驱动智能卡的时钟。分频率在预分频寄存器USART_GTPR 中配置。CK 频率可以从 fCK/2 到 fCK/62,这里的 fCK 是外设输入时钟。
3.12 IrDA SIR ENDEC 功能模块
通过设置 USART_CR3 寄存器的 IREN 位选择 IrDA 模式。在 IRDA 模式里,下列位必须保持清零:
- USART_CR2 寄存器的 LINEN,STOP 和 CLKEN 位
- USART_CR3 寄存器的 SCEN 和 HDSEL 位。
IrDA SIR 物理层规定使用反相归零调制方案(RZI),该方案用一个红外光脉冲代表逻辑'0'(见图 265)。
SIR 发送编码器对从 USART 输出的 NRZ(非归零)比特流进行调制。输出脉冲流被传送到一个外部输出驱动器和红外 LED。USART 为 SIR ENDEC 最高只支持到 115.2Kbps 速率。在正常模式里,脉冲宽度规定为一个位周期的 3/16。SIR 接收解码器对来自红外接收器的归零位比特流进行解调,并将接收到的 NRZ 串行比特流输出到 USART。在空闲状态里,解码器输入通常是高(标记状态 markingstate)。发送编码器输出的极性和解码器的输入相反。当解码器输入低时,检测到一个起始位。
- IrDA 是一个半双工通信协议。如果发送器忙(也就是 USART 正在送数据给 IrDA 编码器)IrDA 接收线上的任何数据将被 IrDA 解码器忽视。如果接收器忙(也就是 USART 正在接收从 IrDA解码器来的解码数据),从 USART 到 IrDA 的 TX 上的数据将不会被 IrDA 编码。当接收数据时,应该避免发送,因为将被发送的数据可能被破坏。
- SIR 发送逻辑把'0'作为高脉冲发送,把'1'作为低电平发送。脉冲的宽度规定为正常模式时位周期的 3/16(见图 266)。
- SIR 接收逻辑把高电平状态解释为'1',把低脉冲解释为'0'。
- 发送编码器输出与解码器输入有着相反的极性。当空闲时,SIR 输出处于低状态。
- SIR 解码器把 IrDA 兼容的接收信号转变成给 USART 的比特流。
- IrDA 规范要求脉冲要宽于 1.41us。脉冲宽度是可编程的。接收器端的尖峰脉冲检测逻辑滤除宽度小于 2 个 PSC 周期的脉冲(PSC 是在 IrDA 低功耗波特率寄存器 USART_GTPR 中编程的预分频值)。宽度小于 1 个 PSC 周期的脉冲一定被滤除掉,但是那些宽度大于 1 个而小于 2 个PSC 周期的脉冲可能被接收或滤除,那些宽度大于 2 个周期的将被视为一个有效的脉冲。当PSC=0 时,IrDA 编码器/解码器不工作。
- 接收器可以与一低功耗发送器通信。
- 在 IrDA 模式里,USART_CR2 寄存器上的 STOP 位必须配置成 1 个停止位。
IrDA 低功耗模式
发送器
在低功耗模式,脉冲宽度不再持续 3/16 个位周期。取而代之,脉冲的宽度是低功耗波特率的 3 倍,它最小可以是 1.42MHz。通常这个值是 1.8432MHz(1.42MHz<PSC<2.12MHz)。一个低功耗模式可编程分频器把系统时钟进行分频以达到这个值。
接收器
低功耗模式的接收类似于正常模式的接收。为了滤除尖峰干扰脉冲,USART 应该滤除宽度短于 1个 PSC 的脉冲。只有持续时间大于 2 个周期的 IrDA 低功耗波特率时钟(USART_GTPR 中的 PSC)的低电平信号才被接受为有效的信号。
注意: 1.宽度小于 2 个大于 1 个 PSC 周期的脉冲可能会也可能不会被滤除。
2.接收器的建立时间应该由软件管理。IrDA 物理层技术规范规定了在发送和接收之间最小要有10ms 的延时(IrDA 是一个半双工协议)。
IrDA SIR ENDEC 框图
IrDA 数据调制(3/16)普通模式
3.13 利用 DMA 连续通信
USART 可以利用 DMA 连续通信。Rx 缓冲器和 Tx 缓冲器的 DMA 请求是分别产生的。
利用 DMA 发送
使用 DMA 进行发送,可以通过设置 USART_CR3 寄存器上的 DMAT 位激活。当 TXE 位被置为'1'时,DMA 就从指定的 SRAM 区传送数据到 USART_DR 寄存器。为 USART 的发送分配一个 DMA 通道的步骤如下(x 表示通道号):
1. 在 DMA 控制寄存器上将 USART_DR 寄存器地址配置成 DMA 传输的目的地址。在每个 TXE 事件后,数据将被传送到这个地址。
2. 在 DMA 控制寄存器上将存储器地址配置成 DMA 传输的源地址。在每个 TXE 事件后,将从此存储器区读出数据并传送到 USART_DR 寄存器。
3. 在 DMA 控制寄存器中配置要传输的总的字节数。
4. 在 DMA 寄存器上配置通道优先级。
5. 根据应用程序的要求,配置在传输完成一半还是全部完成时产生 DMA 中断。
6. 在 DMA 寄存器上激活该通道。
当传输完成 DMA 控制器指定的数据量时,DMA 控制器在该 DMA 通道的中断向量上产生一中断。在发送模式下,当 DMA 传输完所有要发送的数据时,DMA 控制器设置 DMA_ISR 寄存器的 TCIF 标志;监视 USART_SR 寄存器的 TC 标志可以确认 USART 通信是否结束,这样可以在关闭 USART 或进入停机模式之前避免破坏最后一次传输的数据;软件需要先等待 TXE=1,再等待 TC=1。
利用 DMA 发送
利用 DMA 接收
可以通过设置 USART_CR3 寄存器的 DMAR 位激活使用 DMA 进行接收,每次接收到一个字节,DMA控制器就就把数据从 USART_DR 寄存器传送到指定的 SRAM 区(参考 DMA 相关说明)。为 USART 的接收分配一个 DMA 通道的步骤如下(x 表示通道号):
1. 通过 DMA 控制寄存器把 USART_DR 寄存器地址配置成传输的源地址。在每个 RXNE 事件后,将从此地址读出数据并传输到存储器。
2. 通过 DMA 控制寄存器把存储器地址配置成传输的目的地址。在每个 RXNE 事件后,数据将从USART_DR 传输到此存储器区。
3. 在 DMA 控制寄存器中配置要传输的总的字节数。
4. 在 DMA 寄存器上配置通道优先级。
5. 根据应用程序的要求配置在传输完成一半还是全部完成时产生 DMA 中断。
6. 在 DMA 控制寄存器上激活该通道。
当接收完成 DMA 控制器指定的传输量时,DMA 控制器在该 DMA 通道的中断矢量上产生一中断。
利用 DMA 接收
多缓冲器通信中的错误标志和中断产生在多缓冲器通信的情况下,通信期间如果发生任何错误,在当前字节传输后将置起错误标志。如果中断使能位被设置,将产生中断。在单个字节接收的情况下,和 RXNE 一起被置起的帧错误、溢出错误和噪音标志,有单独的错误标志中断使能位;如果设置了,会在当前字节传输结束后,产生中断。
3.14 硬件流控制
利用 nCTS 输入和 nRTS 输出可以控制 2 个设备间的串行数据流。下图表明在这个模式里如何连接2 个设备。
两个 USART 间的硬件流控制
通过将 UASRT_CR3 中的 RTSE 和 CTSE 置位,可以分别独立地使能 RTS 和 CTS 流控制。
RTS 流控制
如果 RTS 流控制被使能(RTSE=1),只要 USART 接收器准备好接收新的数据,nRTS 就变成有效(接低电平)。当接收寄存器内有数据到达时,nRTS 被释放,由此表明希望在当前帧结束时停止数据传输。下图是一个启用 RTS 流控制的通信的例子。
RTS 流控制
CTS 流控制
如果 CTS 流控制被使能(CTSE=1),发送器在发送下一帧前检查 nCTS 输入。如果 nCTS 有效(被拉成低电平),则下一个数据被发送(假设那个数据是准备发送的,也就是 TXE=0),否则下一帧数据不被发出去。若 nCTS 在传输期间被变成无效,当前的传输完成后停止发送。
当 CTSE=1 时,只要 nCTS 输入一变换状态,硬件就自动设置 CTSIF 状态位。它表明接收器是否准备好进行通信。如果设置了 USART_CT3 寄存器的 CTSIE 位,则产生中断。下图是一个启用 CTS 流控制通信的例子。
CTS 流控制
4 USART 中断请求
中断事件 | 事件标志 | 使能位 |
发送数据寄存器空 | TXE | TXEIE |
CTS 标志 | CTS | CTSIE |
发送完成 | TC | TCIE |
接收数据就绪可读 | RXNE | RXNEIE |
检测到数据溢出 | ORE | RXNEIE |
检测到空闲线路 | IDLE | IDLEIE |
奇偶检验错 | PE | PEIE |
断开标志 | LBD | LBDIE |
噪声标志,多缓冲通信中的溢出错误和帧错误 | NE 或 ORT 或 FE | EIE(1) |
(1)仅当使用 DMA 接收数据时,才使用这个标志位。USART 的各种中断事件被连接到同一个中断向量(见下图),有以下各种中断事件:
- 发送期间:发送完成、清除发送、发送数据寄存器空。
- 接收期间:空闲总线检测、溢出错误、接收数据寄存器非空、校验错误、LIN 断开符号检测、噪音标志(仅在多缓冲器通信)和帧错误(仅在多缓冲器通信)。
如果设置了对应的使能控制位,这些事件就可以产生各自的中断。
USART 中断映像图
5 例程设计
5.1 USART_Asyn
1.初始化部分调用delay_init()函数进行延时初始化。
调用UART_Configuration(115200)函数对串口 1 进行初始化,波特率设置为 115200。
获取系统时钟频率并打印相关信息。
2.主循环部分接收数据:禁用 DMA1 通道 5。
while (1)
{
// 禁用DMA1通道5(确保配置前停止通道)
DMA_Cmd(DMA1_Channel5, DISABLE);
// i. 使能串口1接收DMA请求
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
// ii. 配置DMA接收(通道5)
DMA_RecvConfiguration();
// iii. 等待接收完成标志(DMA1通道5传输完成)
while (DMA_GetFlagStatus(DMA1_FLAG_TC5) == RESET);
// iv. 打印接收完成信息及数据
printf("USART Asyn DMA Recv Complete\n");
for (i = 0; i < BUFFSIZE; i++)
{
printf("%c ,", Buff[i]);
}
printf("\n");
// 发送数据流程(与接收类似)...
}
使能串口 1 的接收 DMA 请求。
调用DMA_RecvConfiguration()函数配置 DMA 接收。
等待 DMA 接收完成标志(DMA1_FLAG_TC5)置位。
打印接收完成信息,并输出接收到的数据。
3.发送数据:禁用 DMA1 通道 4。
while (1)
{
// (接收流程代码略)...
// 禁用DMA1通道4(确保配置前停止通道)
DMA_Cmd(DMA1_Channel4, DISABLE);
// i. 使能串口1发送DMA请求
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
// ii. 配置DMA发送(通道4)
DMA_SendConfiguration();
// iii. 等待发送完成标志(DMA1通道4传输完成)
while (DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET);
// iv. 打印发送完成信息
printf("USART Asyn DMA Send Complete\n");
delay_ms(100); // 可选延时避免高频循环
}
使能串口 1 的发送 DMA 请求。
调用DMA_SendConfiguration()函数配置 DMA 发送。
等待 DMA 发送完成标志(DMA1_FLAG_TC4)置位。
打印发送完成信息。
4.函数实现部分UART_Configuration:对串口 1 的 GPIO 和串口参数进行初始化。
void DMA_RecvConfiguration(void)
{
DMA_InitTypeDef DMA_InitStructure;
// 使能DMA1时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 复位并配置DMA1通道5(USART1接收)
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; // 外设地址:USART数据寄存器
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buff; // 内存地址:接收缓冲区
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 方向:外设→内存
DMA_InitStructure.DMA_BufferSize = BUFFSIZE; // 缓冲区大小:8字节
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 8位数据
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel5, ENABLE); // 启动DMA接收
}
void DMA_SendConfiguration(void)
{
DMA_InitTypeDef DMA_InitStructure;
// 使能DMA1时钟(已使能可省略,但代码中保留健壮性)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 复位并配置DMA1通道4(USART1发送)
DMA_DeInit(DMA1_Channel4);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; // 外设地址:USART数据寄存器
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buff; // 内存地址:发送缓冲区
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // 方向:内存→外设
DMA_InitStructure.DMA_BufferSize = BUFFSIZE; // 缓冲区大小:8字节
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 8位数据
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel4, ENABLE); // 启动DMA发送
}
DMA_RecvConfiguration:对 DMA1 通道 5 进行初始化,用于串口 1 的接收。
DMA_SendConfiguration:对 DMA1 通道 4 进行初始化,用于串口 1 的发送。
SER_PutChar:实现字符发送功能。
fputc:重定向标准输出函数,使printf函数可以通过串口输出。
6 下载验证
6.1 USART_Asyn
初始化阶段
程序启动后,会进行一系列初始化操作,包括延时初始化、串口 1 初始化,并且获取系统时钟频率。
初始化完成后,会通过串口打印系统时钟频率信息,内容涵盖 SYSCLK、HCLK、PCLK1、PCLK2 和 ADCCLK 的频率,单位为 MHz。
随后会打印出USART Asyn DMA Test.,表明开始进行串口异步 DMA 测试。
主循环阶段
- 接收数据
程序会先禁用 DMA1 通道 5,然后使能串口 1 的接收 DMA 请求,并对 DMA 接收进行配置。
程序会等待 DMA 接收完成标志(DMA1_FLAG_TC5)置位,当接收完成后,会打印USART Asyn DMA Recv Complete信息。
接着将接收到的BUFFSIZE(即 8 个)字节数据逐字符打印出来,每个字符后会有一个逗号分隔。
- 发送数据
之后程序会禁用 DMA1 通道 4,使能串口 1 的发送 DMA 请求,并对 DMA 发送进行配置。
等待 DMA 发送完成标志(DMA1_FLAG_TC4)置位,发送完成后,会打印USART Asyn DMA Send Complete信息。
持续运行
上述接收和发送的过程会在主循环中不断重复,只要程序不停止运行,就会持续进行串口数据的接收和发送操作,并在每次操作完成后输出相应的提示信息。