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,这一句话包含了三个内容:
uart对象——其代表我们要使用的uart外设;uart启动——其代表根据uart参数启动串口;uart参数——其代表uart以何种配置运行;
stm32的hal初始化过程也可以进行类比:
我们还可以用填表格来理解这三步操作:
2.1
step1-申明结构体变量-生成表格
申明一个uart_handletypedef的结构体变量,图中的结构体是在main函数中声明,推荐在main.c的头部申明结构体,使其成为全局变量。
2.2
step2-配置uart参数-填写表格
配置uart参数参数包括两步:
第一步是要给uart_handletypedef结构体变量赋值
将我们要使用的外设赋值给其instance字段。将波特率、帧长度等配合赋值给其uart_inittypedef初始化结构体变量的相应字段。
第二步是要配置与所使用的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和时钟进行如下操作:
启动所用uart外设的时钟。启用所用gpio的时钟。配置gpio_inittypedef初始化结构体变量(变量值如上图)。使用初始化函数初始化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,以及在轮询模式通信方法的阐述。
康佳冰箱匠心设计引领行业风潮 获线上消费者追捧
亮风台助力云天化三环中化 打造数字“智慧工厂”
利用 SoM 实现嵌入式微处理器/FPGA 组合设计和项目的快速运行
MATLAB学习笔记之PID算法3
目前能使用5G的12个品牌手机
Stm32 HAL库开发-UART串口通信轮询方式
苹果在未来依然是会是智能手机产业的强者实力不容小觑
上新 | QY-J10101A安卓行业平板,新品上市限时优惠抢先购
On Semi 255W ATX电源参考设计电路
人工智能的发展对未来的职业定位有什么影响
华米AmazfitGTR手表评测 华米开辟出了另一条高阶之路
AI智能音箱防水透音膜如何实现音响防水的?
人工智能与深度摄像头可以做出什么来
安防领域典型AI芯片有三种,为何偏偏是FPGA称雄?
晶科能源为中天绿能打造4.2MW N型BIPV项目正式并网
国内首台超快扫描隧道显微镜,实现飞秒级时间分辨和原子级空间分辨
HRF系列隔离宽电压输入高电压稳压输出 3000VDC
802.11的射频指标和Wi-Fi国家属性的问题解析
分享高速PCB设计中的屏蔽方法分析
区块链能否成为企业管理工具的重要组成部分