打印
[应用相关]

STM32系统学习——USART(串口通信)

[复制链接]
手机看帖
扫描二维码
随时随地手机跟帖
21
2.数据寄存器
USART说数据寄存器(USART_DR)只有低 9 位有效,并且第 9 位数据是否有效要取决于USART 控制寄存器 1(USART_CR1)的 M 位设置,当 M 位为 0 时表示 8 位数据字长,当 M位为 1 表示 9 位数据字长,我们一般使用 8位数据字长。
USART_DR包含了已发送的数据或者接收到的数据。USART_DR实际是包含了两个寄存器,一个专门用于发送的可写 TDR,一个专门用于接收的可读 RDR。当进行发送操作时,往 USART_DR写入数据会自动存储在 TDR内;当进行读取操作时,向 USART_DR读取数据会自动提取 RDR 数据。
TDR和RDR都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把 TDR 内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接时把接收到的每一位顺序保存在接收移位寄存器内然后才转移到 RDR。
USART 支持 DMA 传输,可以实现高速数据传输。

使用特权

评论回复
22
范德萨大师傅|  楼主 | 2022-1-28 23:36 | 只看该作者
3.控制器
USART有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等。
使用USART之前需要向USART_CR1寄存器的UE位置1使能USART,UE位用于开启供给串口的时钟。发送或者接收数据字长可选8或9位,由USARTT_CR1的M位控制。

使用特权

评论回复
23
范德萨大师傅|  楼主 | 2022-1-28 23:42 | 只看该作者
1)发送器
当USART_CR1寄存器的发送使能位TE置1时,启动数据发送,发送移位寄存器的数据会在TX引脚输出,低位在前,高位在后。如果是同步模式SCLK也输出时钟信号。
一个字符帧发送需要3部分:起始位、数据帧、停止位。起始位是一个位周期的低电平,位周期就是每一位占用的时间 ;数据帧就是我们要发送的8或9位数据,数据是最低位开始传输的;停止位是一定时间周期的高电平。

使用特权

评论回复
24
范德萨大师傅|  楼主 | 2022-1-28 23:47 | 只看该作者
停止位的时间长短可以通过USART控制寄存器2(USART_CR2)的STOP[1:0]位控制,可选0.5个、1个、1.5个、2个停止位。默认使用1个停止位。2个停止位适用于正常USART模式、单线模式和调制解调器模式。0.5和1.5个停止位用于智能卡模式。
当发使能位TE置1之后,发送器开始会发送一个空闲帧(一个数据帧长度的高电平),接下来就可以往USART_DR寄存器写入要发送的数据。在写入最后一个数据后,需等待USART状态寄存器(USART_SR)的TC位为1,表示数据传输完成。USART_CR1寄存器的TCIE位置1,则产生中断。
发送数据时,几个重要的标志位如下:
TE:发送使能。
TXE:发送寄存器为空,发送单个字节时使用。
TC:发送完成,发送多个字节数据时候使用。
TXIE:发送完成中断使能。

使用特权

评论回复
25
范德萨大师傅|  楼主 | 2022-1-28 23:48 | 只看该作者
2)接收器
将CR1寄存器的RE位置1,使能USART接收,使得接收器在RX线开始搜索起始位。在确定起始位后,就根据RX线电平状态把数据存放在接收移位寄存器内。接收完成后就把接收移位寄存器的数据移到PDR内,并把USART_SR寄存器的RXNE位置。如果USART_CR2寄存器的RXNEIE置1可以产生中断。
——————————

使用特权

评论回复
26
范德萨大师傅|  楼主 | 2022-1-28 23:52 | 只看该作者
接收数据时,几个重要的标志位如下:
RE:    接收使能。
RXNE:读数据寄存器非空。
RXNEIE:发送完成中断使能。

使用特权

评论回复
27
范德萨大师傅|  楼主 | 2022-1-28 23:53 | 只看该作者
4.小数波特率生成
USART 的发送器和接收器使用相同的波特率。计算公式如下:

其中,f PLCK 为 USART 时钟, USARTDIV 是一个存放在波特率寄存器(USART_BRR)的一个无符号定点数。其中 DIV_Mantissa[11:0]位定义 USARTDIV 的整数部分,DIV_Fraction[3:0]位定义 USARTDIV 的小数部分。

使用特权

评论回复
28
范德萨大师傅|  楼主 | 2022-1-28 23:54 | 只看该作者
例如:DIV_Mantissa=24(0x18),DIV_Fraction=10(0x0A),此时 USART_BRR 值为0x18A;那么USARTDIV的小数位10/16=0.625;整数位24,最终USARTDIV的值为24.625。
如果知道 USARTDIV 值为 27.68,那么 DIV_Fraction=16*0.68=10.88,最接近的正整数为 11,所以 DIV_Fraction[3:0]为 0xB;DIV_Mantissa=整数(27.68)=27,即为 0x1B。
波特率的常用值有 2400、9600、19200、115200。下面以实例讲解如何设定寄存器值得到波特率的值。

使用特权

评论回复
29
范德萨大师傅|  楼主 | 2022-1-28 23:56 | 只看该作者
我们知道 USART1 使用 APB2 总线时钟,最高可达 72MHz,其他 USART 的最高频率为 36MHz。我们选取 USART1 作为实例讲解,即 f PLCK =72MHz。为得到 115200bps 的波特率,此时:

115200 =72000000/(16 ∗ USARTDIV)

解 得 USARTDIV=39.0625 , 可 算 得 DIV_Fraction=0.0625*16=1=0x01 ,DIV_Mantissa=39=0x27,即应该设置 USART_BRR 的值为 0x171。

使用特权

评论回复
30
范德萨大师傅|  楼主 | 2022-1-28 23:57 | 只看该作者
5.校验控制
STM32F103系列控制器USART支持奇偶校验。使用校验位时,串口传输的长度将在8位数据帧上加上1位的校验位,总共9位,此时USART_CR1寄存器的M位需要设置位1,即9数据位。将USART_CR1寄存器的PCE位置1就可以启动奇偶校验控制,奇偶校验由硬件自动完成。启动了奇偶校验控制之后,发送数据帧时会自动添加校验位,接收数据自动验证校验位。接收数据时如果出现奇偶校验位验证失败,会将USART_SR寄存器的PE置1,并可以产生奇偶校验中断。
使用了奇偶校验控制位后,每个字符帧的格式变成了:起始位+数据帧+校验位+停止位。

使用特权

评论回复
31
范德萨大师傅|  楼主 | 2022-1-29 15:32 | 只看该作者
6.中断控制

使用特权

评论回复
32
范德萨大师傅|  楼主 | 2022-1-29 15:33 | 只看该作者
五、USART初始化结构体
初始化结构体的定义在stm32f10x_usart.h文件中,初始化库函数定义在stm32f10x_usart.c中。

                                    USART初始化结构体

使用特权

评论回复
33
范德萨大师傅|  楼主 | 2022-1-29 15:36 | 只看该作者
typedef struct {
uint32_t USART_BaudRate; // 波特率
uint16_t USART_WordLength; // 字长
uint16_t USART_StopBits; // 停止位
uint16_t USART_Parity; // 校验位
uint16_t USART_Mode; // USART 模式
uint16_t USART_HardwareFlowControl; // 硬件流控制
} USART_InitTypeDef;

使用特权

评论回复
34
范德萨大师傅|  楼主 | 2022-1-29 15:36 | 只看该作者
1)USART_BaudRate:波特率设置。标准库函数会根据设定值计算得到USARTDIV值,从而设置USART_BRR的寄存器值。
2)USART_WordLength:.数据帧字长,它设定USART_CR1寄存器M位的值。如果没有使能奇偶位校验控制,一般使用8数据位。
3)USART_StopBits停止位设置。
4)USART_Parity:奇偶校验控制选择。
5)USART_Mode:USART模式选择有USART_Mode_Rx和USART_Mode_Tx,允许使用逻辑或运算选择两个,它设定 USART_CR1寄存器的 RE 位和 TE位。
6)USART_HardwareFlowControl:硬件流控制选择,只有在硬件流控制模式下才有效,可选有,使能RTS、使能CTS、同时使能RTS和CTS、不使用硬件流。

使用特权

评论回复
35
范德萨大师傅|  楼主 | 2022-1-29 15:37 | 只看该作者
当使用同步模式,需配置SCLK引脚输出脉冲的属性,标准库使用一个时钟初始化结构体USART_ClockInitTypeDef来设置,该结构体内容只有在同步模式下才设置。
                USART时钟初始化结构体
typedef struct {
uint16_t USART_Clock; // 时钟使能控制
uint16_t USART_CPOL; // 时钟极性
uint16_t USART_CPHA; // 时钟相位
uint16_t USART_LastBit; // 最尾位时钟脉冲
} USART_ClockInitTypeDef;


使用特权

评论回复
36
范德萨大师傅|  楼主 | 2022-1-29 15:40 | 只看该作者
1)USART_Clock:同步模式下SCLK引脚上时钟输出使能控制,可选禁止时钟输出(USART_Clock_Disable)或开启时钟输出(USART_Clock_Enable);如果使用同步模式发送,一般都需要开启时钟。它设定 USART_CR2 寄存器的 CLKEN 位的值。 ݶ
2)USART_CPOL:同步模式下 SCLK 引脚上输出时钟极性设置,可设置在空闲时SCLK引脚为低电平(USART_CPOL_Low)或高电平(USART_CPOL_High)。它设定USART_CR2寄存器的 CPOL位的值。
3)USART_CPHA:同步模式下 SCLK 引脚上输出时钟相位设置,可设置在时钟第一个变化沿捕获数据(USART_CPHA_1Edge)或在时钟第二个变化沿捕获数据。它设定 USART_CR2寄存器的 CPHA位的值。USART_CPHA与 USART_CPOL配合使用可以获得多种模式时钟关系。
4)USART_LastBit:选择在发送最后一个数据位的时候时钟脉冲是否在SCLK引脚输出,可以是不输出脉冲(USART_LastBit_Disable) 、 输出脉冲(USART_LastBit_Enable)。它设定 USART_CR2 寄存器的 LBCL位的值。

使用特权

评论回复
37
范德萨大师傅|  楼主 | 2022-1-29 15:40 | 只看该作者
六、USART1接发通信实验
USART 只需两根信号线即可完成双向通信,对硬件要求低,使得很多模块都预留USART 接口来实现与其他模块或者控制器进行数据传输,比如 GSM 模块,WIFI 模块、蓝牙模块等等。在硬件设计时,注意还需要一根“共地线”。
来编写一个程序实现开发板与电脑通信,在开发板上电时通过USART发送一串字符串给电脑,然后开发板进入中断接收等待状态,如果电脑有发送数据过来,开发板就会产生中断,我们在中断服务函数接收数据,并马上把数据返回发送给电脑。

使用特权

评论回复
38
范德萨大师傅|  楼主 | 2022-1-29 15:42 | 只看该作者
1、编程思路

使能 RX和 TX 引脚 GPIO时钟和 USART时钟;
初始化 GPIO,并将 GPIO复用到 USART上;
配置 USART 参数;
配置中断控制器并使能 USART接收中断;
使能 USART;
在 USART接收中断服务函数实现数据接收和发送。

使用特权

评论回复
39
范德萨大师傅|  楼主 | 2022-1-29 15:42 | 只看该作者
2、代码分析

1)GPIO和USART宏定义
/**
* 串口宏定义,不同的串口挂载的总线和 IO 不一样,移植时需要修改这几个宏
*/
// 串口 1-USART1
#define DEBUG_USARTx USART1
#define DEBUG_USART_CLK RCC_APB2Periph_USART1
#define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200
// USART GPIO 引脚宏定义
#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd

#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10

#define DEBUG_USART_IRQ USART1_IRQn
#define DEBUG_USART_IRQHandler USART1_IRQHandler

使用特权

评论回复
40
范德萨大师傅|  楼主 | 2022-1-29 15:43 | 只看该作者
使用宏定义方便程序移植和升级 。开发板中的 CH340G 的收发引脚默认通过跳帽连接到 USART1,如果想使用其他串口,可以把 CH340G 跟 USART1 直接的连接跳帽拔掉,然后再把其他串口的 IO用杜邦线接到 CH340G的收发引脚即可。
这里我们使用USART1,设定波特率为115200,选定USART的GPIO为PA9和PA10。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则