电子说
1
HAL库中UART相关结构体的内容
本小节参考《description-of-stm32f0-hal-and-lowlayer-drivers-stmicroelectronics》、《STM32F051x 参考手册中文》。
UART的结构体有两个,如图,UART_InitTypeDef是初始化结构体,包含UART开始运行时的配置;UART_HandleTypeDef是句柄结构体,包含UART所有运行时的信息。
UART_InitTypeDef初始化结构体中包含,波特率、帧的字长、停止位长度、奇偶校验方式、工作模式、硬件流模式和过(超)采样率设置。
其中过采样的目的类似于一种低通滤波,Stm32通过对一帧进行16次或者8次采样,并对采样结果进行“多数票决”来判断该帧为起始位或是数据位的0或1。详见《STM32F051x 参考手册中文》573页。
硬件流控制是通过硬件对UART传输进行更精细的控制的手段。UART传输中,Stm32通过nCTS端口读取对方的nRTS端口电平,获知对方是否准备好接受新的数据,这种操作可以避免数据寄存器中未被读出的旧数据被新数据刷新掉的情况发生。详见《STM32F051x 参考手册中文》604页。
UART_HandleTypeDef是UART句柄结构体,包含了UART运行过程中HAL层的所有信息。
2
UART初始化三步
在介绍Stm32的HAL初始化UART之前,我们先看一下Arduino怎么初始化UART的。
Arduino使用非常简便的一句话,*Serial.begin(波特率); *来初始化UART,这一句话包含了三个内容:
Stm32的HAL初始化过程也可以进行类比:
我们还可以用填表格来理解这三步操作:
2.1
Step1-申明结构体变量-生成表格
申明一个UART_HandleTypeDef的结构体变量,图中的结构体是在main函数中声明,推荐在main.c的头部申明结构体,使其成为全局变量。
2.2
Step2-配置UART参数-填写表格
配置UART参数参数包括两步:
第一步是要给UART_HandleTypeDef结构体变量赋值
第二步是要配置与所使用的UART连接的GPIO口,因为任何外设想与外界交换数据都需要正确的和使用的GPIO进行绑定。
在还未介绍的Step3中,我们需要调用HAL_UART_Init()初始化UART,HAL_UART_Init()又会调用HAL_UART_MspInit()对于单片机的Msp( MCU Specific Package 单片机的具体方案 )进行配置,这里Msp就指具体配置哪个IO与UART进行连接。
在HAL_UART_MspInit()中配置GPIO又需要进行如下两步操作:
1. 定义GPIO_InitTypeDef初始化结构体变量作为所要初始化GPIO的配置的“暂存”。
2. 然后判断此次调用HAL_UART_MspInit()函数的UART外设,根据不同的UART外设对于相应的GPIO和时钟进行如下操作:
2.3
Step3-使用函数初始化UART-提交表格
完成了UART的参数配置和IO配置之后,我们需要使用HAL_UART_Init()函数提交之前配置好的UART_HandleTypeDef结构体变量这个“表格”,使得Stm32按照我们的参数配置、IO配置启动。
3
使用轮询模式
3.1
UART通信的三种模式
UART通信有三种模式,分别为轮询模式、中断模式、DMA模式,本小节介绍轮询模式通信。
如果读者学过8位单片机的底层开发,应该能理解轮询模式和中断模式的区别以及中断模式比轮询模式在单片机任务较多时更为高效的原因。
《Mastering Stm32》一书的248页也对两者的区别进行了阐述:
简单来说,轮询模式是内核在规定的阻塞时间内使用while循环读取传输的标志位,直到标志位被置位才将数据写入或读出DR寄存器。
而中断模式是传输完成的相关中断发生时,内核才放下手中的工作,将数据写入或读出DR寄存器。少了阻塞时间内的循环读取因此更高效。
而DMA模式则更为高效,DMA作为内核的二弟,当传输完成中断发生时,帮助大哥将数据写入或读出DR寄存器,不需要打断大哥-内核的工作。
3.2
轮询模式
在轮询模式发送数据调用函数HAL_UART_Transmit() ,接收数据调用函数HAL_UART_Receive(),两者的传入参数列表,以及返回值意义相同,如下图,摘自《description-of-stm32f0-hal-and-lowlayer-drivers-stmicroelectronics》P572页。
下面演示两个函数的几种调用案例:
/* 发送字符数组 */
char buff[2] = {'a','b'};
HAL_UART_Transmit(&huart3,(uint8_t *)buff,
sizeof(buff),HAL_MAX_DELAY);
/* 发送字符串 */
HAL_UART_Transmit(&huart3, (uint8_t*)"Hello",
strlen("Hello"),HAL_MAX_DELAY);
/* 接受字符数组 */
char readBuf[1];
HAL_UART_Receive(&huart2, (uint8_t*)readBuf, 1, HAL_MAX_DELAY);
至此本文已经完成了对于Stm32使用HAL初始化UART,以及在轮询模式通信方法的阐述。
全部0条评论
快来发表一下你的评论吧 !