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 ...
随机推荐
- TEAMWORK1
代码信息 队友:马司雨 队友项目:Prim算法生成最小生成树 codeing地址:这里 博客地址:那里 代码功能审查表 功能模块名称 Prim算法生成最小生成树 审查人 张洋 审查日期 2019.4. ...
- javascript 4.2
element.value="......"也可以为属性设置新的值 setAttribute()方法是“第一级DOM”的组成部分之一,DOM是适用于多种环境和多种程序设计语言的通用 ...
- 将 windows 目录结构 复制到 linux 上
思路:生成目录结构文件,复制到linux上,然后建立每个文件即可 借助unix_utils( https://sourceforge.net/projects/unxutils/) 1. window ...
- CentOS7之Rsync+Inotify架构实现实时同步文件和文件夹
简介:rsync是用来同步文件和文件夹的,inotify是用来实现监听变动而自动同步的 OS:Centos7.3 服务器端:172.16.13.157 客 户 端 :172.16.13.156 目 ...
- idea调试代码跟踪到tomcat代码里面
在POM.xml文件里面加上如下代码即可: <dependency> <groupId>org.apache.tomcat</groupId> <artifa ...
- mvc项目远程发布到windows server服务器
1.安装IIS的时候需要将这两个选项勾选起来 2.确保 管理服务委派 这个选项存在 3.添加委派规则 4.配置IIS管理用户,后续需要用这个用户进行发布连接 5.配置站点的IIS权限 选择刚才在前面设 ...
- python中使用 C 类型的数组以及ctypes 的用法
Python 在 ctypes 中为我们提供了类似C语言的数据类型, 它的用途(我理解的)可能是: (1) 与 其他语言(如 C.Delphi 等)写的动态连接库DLL 进行交换数据,因为 pytho ...
- [ZZ] Valse 2017 | 生成对抗网络(GAN)研究年度进展评述
Valse 2017 | 生成对抗网络(GAN)研究年度进展评述 https://www.leiphone.com/news/201704/fcG0rTSZWqgI31eY.html?viewType ...
- H5外包 微信小程序外包 小程序外包 就找北京动点开发团队
长年承接微信小程序.微信公众号开发 全职的H5开发团队,开发过几十款微信小程序公众号案例 欢迎来电咨询 QQ:372900288 微信:liuxiang0884 TEL:13911652504
- php5.5.7添加pgsql,pdo_pgsql,swoole
一:下载php源码sudo wget cn2.php.net/distributions/php-X.X.X.tar.gz 二:解压 tar xzf /php-X.X.X.tar.gz 三:进入源码e ...