1. USART和UART
USART(Universal Synchronous Asynchronous Receiver and Transmitter)即通用同步异步收发器,它是一个串行通信设备,与外部设备可灵活进行全双工数据交换。在这之前我们常用到的是UART(Universal Asynchronous Receiver and Transmitter),它是在USART基础上裁剪掉了同步通信功能,只有异步通信。区分同步和异步最简单的方法就是看通信时需不需要对外提供时钟输出,我们平时使用的串口通信基本都是UART。关于串口通信其他基本概念,在上一篇文章http://blog.youkuaiyun.com/qq_29344757/article/details/75246263已有详细解析,这里不再赘述。
2. STM32中USART功能框图
2.1 功能引脚
(1)TX:输出引脚,用于发送数据
(2)RX:输入引脚,用于接收数据
(3)SW_RX:输入引脚,用于单线和智能卡模式,属于内部引脚,没有具体外部引脚引出
(4)IRDA_OUT:输出引脚,用于发送红外数据
(5)IRDA_IN:输入引脚,用于接收红外数据
(6)nRTS:请求以发送(Request To Send),n表低电平有效。若使能RTS硬件流控制,当USART接收器准备好接收数据时,nRTS有效,即它为低电平;当接收寄存器已满时,nRTS被设置为高电平
(7)nCTS:请求以发送(Clean To Send),n表低电平有效。若使能CTS硬件流控制,发送器在发送下一帧数据前会检测nCTS引脚状态,若为低电平表可以发送数据,若为高电平则在发送完当前数据帧之后停止发送。
(8)SCLK:发送器时钟输出引脚,仅适用于同步模式。
2.2 数据寄存器
USART数据寄存器(USART_DR)只有低9位有效,
第9位数据是否有效要取决于USART_CR1(USART控制寄存器1)的M位设置,
当M位为0时表示8位数据字长,当M位为1时表9位数据字长,一般我们使用8位数据字长。
USART_DR实际是包含了两个寄存器,一个专门用于发送的TDR,一个专门用于接收的RDR。进行发送数据操作时,往USART_DR写入数据会自动存储在TDR内,当进行读取数据操作时,向USART_DR读取数据会自动提取RDR数据。串行通信时一位一位传输的,所以TDR和RDR寄存器都是介于系统总线和移位寄存器间的:发送数据时把TDR内容转移到发送移位寄存器上,接收数据时则是把接收到的每一位顺序保存在接收移位寄存器内进而转移到RDR。
2.3 控制器
STM32的USART有专门用于控制发送、接收、唤醒单元和中断等的寄存器。例如:
(1)USART_CR1寄存器的UE位用于开启/关闭给串口的时钟源的,使用USART之前向该位写1用于使能USART。
(2)USART_CR1寄存器的M位用于控制发送/接收数据字长可选8位/9位。
(3)USART_CR1寄存器的TE位用于启停数据发送,向该位写1时发送移位寄存器上的数据会从TX引脚输出,低位在前,高位在后。如果设置USART为同步模式,SCLK引脚将会输出时钟信号。
(4)USART_CR1寄存器的RE位用于开启/关闭USART的接收,若为1,接收器在RX线开始接收数据帧的起始位,确定到起始位后就根据RX线电平状态把数据存放在接收移位寄存器内,接收完成后就要接收移位寄存器移到RDR内,并将USART_SR寄存器的RXNE位置1(若USART_CR2寄存器的RXNEIE置1的话此时可以产生中断)
一般在我们编程中较为重要的USART_CR1寄存器标志位有:
在发送数据时,
- 1
- 2
- 3
- 4
接收数据时,
- 1
- 2
- 3
2.4 波特率设置
USART的发送器和接收器使用相同的波特率,计算公式为:
- 1
USARTDIV是一个存放波特率寄存器(USART_BRR)的无符号浮点数
DIV_Mantissa[11:0]表示USARTDIV的整数部分
DIV_Fraction[3:0]表示USARTDIV的小数部分。
例如:DIV_Mantissa = 26(0x1a),DIV_Fraction = 12(0x0c),那么USART_CRR的值为0x26c。USARTDIV的小数位12 / 16 = 0.75,整数位26,最终USARTDIV的值为26.75。
假设知道USARTDIV的值为22.63,那么,DIV_Fraction = 16 * 0.63 = 10.08,最接近的整数位10,即DIV_Fraction = 0x0a,DIV_Mantissa = 22,即为0x16。
以USART1为例,它是挂接在APB2总线上的:
即USART1的时钟源频率为72MHz,那么如果要得到115200的波特率,即:
115200 = 72000000 / (16 * USARTDIV),USARTDIV = 39.0625,
同理计算可得,DIV_Fraction = 0.0625 * 16 = 1,DIV_Mantissa = 39,USART_BRR的值设置为0x271。
2.5 校验控制
STM32F103系列单片机的USART支持奇偶校验,USART_CR1寄存器的PCE位置1就可以启动奇偶校验,奇偶检验由硬件自动完成。使能奇偶校验控制后,每个字符帧的格式变为:
- 1
注意,当使用校验位时,USART_CR1寄存器的M位需要设置为1,即9位模式,因为串口传输的长度为8位数据帧加上1位校验位共9位。启动奇偶校验控制后,在发送数据帧时会自动添加校验位,接收数据帧时自动验证校验位。接收数据时若出现奇偶校验位验证失败,USART_SR寄存器的PE位会被置1并可以产生奇偶校验中断。
2.6 中断控制
USART有多个中断请求事件,常用中断请求有:
3. USART初始化数据结构
有了标准库,我们的编程变得十分简单,若上面讲到的寄存器操作及原理不清晰,也不是我们要动手编程的阻碍了,不过了解下总归是好的。
初始化结构体定义在标准外设库的stm32f10x_usart.h文件中:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
4. USART编程使用到的外设库函数
4.1 USART时钟使能
以USART1为例,它是挂接在APB2总线在的外设,使能函数为
- 1
4.2 USART复位
当外设出现异常时可通过复位设置实现对外设的复位,然后重新配置该外设使其重新工作。一般系统在刚开始配置外设时,都会先执行复位外设操作。USART的复位函数为
- 1
复位USART1时
- 1
4.3 串口初始化
- 1
参数一为待初始化的串口标号
参数二为USART_InitTypeDef类型的结构体指针,原型及其意义在前面已讲
4.4 USART发送数据
- 1
该函数向USART_DR写入一个数据,串口会自动发送。
4.5 接收数据
- 1
该函数是操作USART_DR读取串口接收到的数据
4.6 串口状态
串口的状态是保存在USART_SR寄存器中,读取串口状态寄存器的函数为】
- 1
参数二表示我们要查看串口的哪种状态,可取值为:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
4.7 串口使能
- 1
4.8 串口响应中断
- 1
参数二表示使能串口哪种中断。串口能产生中断的中断源有许多,取值为:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
4.9 获取相应中断状态
使能某中断后,当该中断发生了就会设置状态寄存器的某个标志位。在中断服务函数中我们经常要去判断是哪个中断源,
- 1
若使能了串口发送完成中断,判断是否产生该中断时用
- 1
返回值等于SET,说明发生串口发送完成中断。
5. 编程实践
硬件平台采用MiniSTM32开发板,要实现板载USART和计算机通讯,需要用到一个USB转USART的芯片,MiniSTM32开发板采用的转换芯片为CH340G。硬件接线图为:
需要注意的是,STM32的USART1的引脚和CH340的接线。USART1的发送、接收引脚分别是PA9和PA10:
通过跳线帽将PA9(U1_TXD)、PA10(U1_RXD)连接到CH340G的RXD、TXD。这个在配置GPIO功能的时候要注意是以STM32芯片原理图上的引脚功能为准。
程序实现功能:开发板上电后通过USART发送字符串到计算机(计算机用串口调试助手接收),进而开发板进入等待中断状态,若计算机通过串口调试助手向开发板发数据就会触发STM32的接收数据终中断,在中断服务函数中接收数据并将数据发回给计算机。
STM32的串口编程关键点在于:
(1)使能RX和TX引脚GPIO时钟和USART时钟
(2)初始化GPIO,并将GPIO复用到USART上。参照《STM32中文参考手册_V10.pdf》-P110 外设的GPIO配置-USART部分
(3)配置USART初始化参数
(4)配置终端控制器NVIC并使能USART接收中断
(5)使能USART
(6)在USART1中断服务函数中实现数据接收和发送
编程环境采用MDK5,工程结构如图:
BSP/BSP_USART.c中实现对USART的所有操作及NVIC初始化操作,相关声明在BSP/BSP_USART.h中:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
USART1的接收数据产生的中断的中断服务函数在stm32f10x_it.c中实现:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
在main函数中:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
发送完”HelloWorld\n”后进入等待中断中。
下载运行,注意若使用板载的串口下载方式下载程序,就会占用了USART1发送/接收数据用的串口,所以需要下载完程序后再用串口调试助手测试。另外,计算机串口调试助手的波特率、停止位、数据位等要跟在代码中的设置一致。运行如图:
-
顶
- 0
-
踩