stm32 HAL库笔记(一)——串口的操作
昨天分析了普通io口的使用,和初始化代码流程,回顾一下,首先定义一个配置io口功能的结构体,然后开启时钟,再去配置这个结构体里面的各个成员变量,每个成员变量都有很多种选择,可以看各个成员变量 后面的注释,找到可选的配置即可,把这个结构体配置完了之后,把它扔到hal库提供的io口初始化函数中,另一个参数是ABC。。。中的一个,指定端口。
同理,操作串口的流程大致和上面叙述的过程差不多,但是串口多了收发数据,中断等等功能。在Cubemx里面配置串口,然后打开工程,跟踪代码,了解详细的过程。首先,串口的初始化代码部分:
UART_HandleTypeDef UART1_Handler; //UART句柄
UART1_Handler.Instance=USART1; // 指定串口
UART1_Handler.Init.BaudRate=bound; // 波特率
UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B; // 字长为8位数据格式
UART1_Handler.Init.StopBits=UART_STOPBITS_1; // 一个停止位
UART1_Handler.Init.Parity=UART_PARITY_NONE; // 无奇偶校验位
UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; // 无硬件流控
UART1_Handler.Init.Mode=UART_MODE_TX_RX; // 收发模式
HAL_UART_Init(&UART1_Handler); // 初始化这个串口
大概过程和配置io口类似,不再细说。但是要进到串口初始化函数中去看一下,发现会调用这个函数,但是这个函数的weak虚函数,虚函数的概念百度一下即可,大概就是用户需要自己重新写他的功能:
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
...
HAL_UART_MspInit(huart);
...
}
...
__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_MspInit could be implemented in the user file
*/
}
看一下注释,大意就是与回调有关系,cubemx给做了,看一下:
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct; /**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_NVIC_SetPriority(USART1_IRQn, , );
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
从代码可以功能:配置io口,刚才的初始化串口函数,只是配置了串口的波特率、数据位等等,但是还没有配置串口所在的引脚,在这里配置,注释很清楚,A9 A10是这个川口的T和R,然后配置速度、复用模式,复用为什么,这个复用说一下。举个例子,如果有的用户想用很多普通io口,不用串口啊、SPI接口啊。有的呢,就用串口和spi接口,那厂家要是想满足这些用户,就要给片上,多加io口,加串口,等等其他的引脚,那么就可能会使脚很多,芯片大或者制造成本高,于是厂家就用100根引脚(407某型号)然后让一些脚有多个功能,既可以干这个也可以做那个,至于到底做什么,用户决定,这样就是脚会少,同时满足大多数用户的需求。片上除了电源等口,剩下的,基本都可以当作普通的io口用,同时也可以做串口、SPI等等功能,这叫复用。刚才说到,我们只配置了串口功能,还没配置这个串口所在的io口为复用,复用为串口。在这个回调初始化中定义了。同时,也配置了,中断优先号,中断使能。
那么中断怎么用呢?这里我直接参考了正点原子的教程:
// 串口号 接受缓冲数组 接收量:自己宏定义或者直接写数就行
HAL_UART_Receive_IT(&huart1, (u8 *)aRxBuffer1, RXBUFFERSIZE1);
//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
这个函数放在串口初始化中,就使能了串口接收中断,串口接收到数据,这个函数就把数据放在我们定义的接受缓冲数组中,可能一次过来很多,但是我们只接收RXBUFFERSIZ1个,这个还要配合回中断调用函数,在利用JY901模块收再说,下面再说。如果想深入了解的话,还得进入这个函数去看看,发现他会调用函数:__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);,其实这是一个宏定义,如下:
#define UART_IT_MASK ((uint32_t)0x0000FFFFU)
#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == 1U)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
(((__INTERRUPT__) >> 28U) == 2U)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \
((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))
很复杂,如果带参数宏定义,把参数带入进来,然后对比寄存器,配置中断的,这个就不详细写了,其实如果不了解寄存器的话也可用起来的。(刚才分析了一下,感觉这块还是要一步一步的写出来,以后自己看还是很省事的,但是时间紧迫,以后在回过头来补充)。
那如果发生了中断呢,刚才配置的是USART1_IRQn,我们去查一下他,发现:
DCD USART1_IRQHandler ; USART1 void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
串口1的中断处理函数是USART1_IRQHandler,他又调用了HAL_UART_IRQHandler(&huart1):
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
...
UART_Receive_IT(huart); //读数据寄存器,并且调用回调函数
....
} static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
HAL_UART_RxCpltCallback(huart); // 回调函数,虚函数自己定义
} __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
}
那么我们接收到了传到串口的数据后我们利用hal库函数也得到了,然后我们想利用一下这些数据做点什么怎么办呢?这个接收中断回调函数就来了,接收到数据后,执行中断函数,中断函数的功能是读取数据寄存器,把数据放在我们指定的数组中,然后调用这个回调函数,我们在这各回调函数中就可以操作这些数据了(读取到了),(但是根据正点院子教程所说,这么做效率不高,入门的话,就这么做就行,毕竟官方的)。
if(huart->Instance == USART1)//如果是串口1
{
a = aRxBuffer1[];
HAL_UART_Receive_IT(&huart1, (u8 *)aRxBuffer1, RXBUFFERSIZE1);
}
这里要仔细说一下,我这么写是来一个中断,读取一个字节(之前宏的),但是我用的JY901模块是一次发送11个数据,每条11个字节,我就要中断11次,想来效率不高,该进:把RXBUFFERSIZE1定义为11,一条指令包过来11个字节全部存储在aRxBuffer1中,就行了,然后继续接收使能。
概过程就是这样,这里面并没有发送中断,目前我还没用,只接受就行了,抓紧调四轴。
stm32 HAL库笔记(一)——串口的操作的更多相关文章
- stm32 HAL库笔记(零)
最近在设计四旋翼飞行器,用stm32f407,有三种开发方式可以选择:一.寄存器开发.二:库函数开发.三:HAL库开发,考虑了一下,选择了HAL库,原因如下: 1. 寄存器开发相对较慢,寄存器很多,配 ...
- stm32 HAL库笔记(一)——普通IO口
今天介HAL库操作普通IO口,就是输入/输出. 如果用CubeMX配置io工程,打开以后可以看到如下代码: GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOB ...
- 【情人节选帽子】TCS34725颜色传感器和Python图形界面编程(STM32 HAL库)
截图 描述: l STM32 HAL库编程 l 使用模拟IIC通信,方便程序移植 l Python界面编写,蘑菇头的帽子是什么颜色 l STM32 HAL库串口通信 l Python界面使用 ...
- STM32 HAL库与标准库的区别_浅谈句柄、MSP函数、Callback函数
最近笔者开始学习STM32的HAL库,由于以前一直用标准库进行开发,于是发现了HAL库几点好玩的地方,在此分享. 1.句柄在STM32的标准库中,假设我们要初始化一个外设(这里以USART为例)我们首 ...
- 【有趣的全彩LED | 编程】用STM32 HAL库让WS2812B为你所动
一.效果展示 观看演示效果:https://www.bilibili.com/video/BV1dv411Y7x3 使用STM32 HAL库编程 PWM+DMA控制输出,CubeMX生成初始工程 实现 ...
- 【春节歌曲回味 | STM32小音乐盒 】PWM+定时器驱动无源蜂鸣器(STM32 HAL库)
l STM32通过PWM与定时器方式控制无源蜂鸣器鸣响 l STM32小音乐盒,歌曲进度条图形显示与百分比显示,歌曲切换 l 编程使用STM32 HAL库 l IIC OLED界面编程,动画实 ...
- STM32 HAL库详解 及 手动移植
源: STM32 HAL库详解 及 手动移植
- 【书籍连载】《STM32 HAL 库开发实战指南—基于F7》-第一章
从今天起,每天开始连载一章<STM32 HAL 库开发实战指南—基于F7>.欢迎各位阅读.点评.学习. 第1章 如何使用本书 1.1 本书的参考资料 本书参考资料为:<STM32 ...
- STM32 HAL库 UART 串口读写功能笔记
https://www.cnblogs.com/Mysterious/p/4804188.html STM32L0 HAL库 UART 串口读写功能 串口发送功能: uint8_t TxData[10 ...
随机推荐
- 解决MOFH免费空间cpanel面板大文件无法解压的情况
解决办法: 解压大文件,重新压缩为tar格式的压缩格式,这样可以更小,而且也可以在cpanel面板解压,记得使用filezilla软件上传文件,在cpanel的网页界面不要刷新,一刷新就不可以解压大文 ...
- vim编辑器学习记录
i:在光标所在字符前开始插入 a:在光标所在字符后开始插入 o:在光标所在行的下面另起一新行插入 s:删除光标所在的字符并开始插入 I:在光标所在行的行首开始插入 如果行首有空格则在空格之后插入 A: ...
- windows下Redis的安装和使用
1.要安装Redis,首先要获取安装包.Windows的Redis安装包需要到以下GitHub链接找到.链接:https://github.com/MSOpenTech/redis.打开网站后,找到R ...
- 1、Nexus安装
1.nexus 下载地址: https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.14.5-02-bundle.tar.g ...
- 简易Asset工作流
前言: 当前比较主流的制作流程都可以按顺序细分为三个部分:资产环节(asset section),镜头环节(shot section),合成环节(composite section). 考虑到单一资产 ...
- Vue 给对象添加属性
坑真多,没想到很多小细节都 改了,我添加个属性都 折腾了半天才看明白原因 Vue.set(row,"isEdit",false); //给row对象新增一个isEdit的属性.
- excel安装wps后不能正常启动
1. HKCU\Software\Microsoft\Office\15.0\Word\Options 设置NoReReg REG_DWORD =1 2.重命名C:\Program Files (x8 ...
- winform 打印时的默认单位
通过设置Graphics.PageUnit,是枚举类型GraphicsUnit,默认是display(指定显示设备的度量单位. 通常,视频显示使用的单位是像素:打印机使用的单位是 1/100 英寸.)
- python 打印到控制台变颜色
1 格式:\033[显示方式;前景色;背景色m 2 3 说明: 4 前景色 背景色 颜色 5 --------------------------------------- 6 30 40 黑色 7 ...
- 京东饭粒捡漏V1.0.8
20180617 更新 V1.0.81.捡漏策略更新:自动检测商品,有货后自动下单:2.加车自动使用最优满减券组合: 功能介绍1.京东商城专用,支持饭粒模式下单,自己获得京豆返利 2.捡漏模式:帮助用 ...