STM32 hal库使用笔记(二)中断—串口中断

本文介绍了如何利用串口通信控制正点原子精英板上的LED灯,包括串口简介、HAL库的时钟树配置和CubeMX设置,以及代码编写,涉及波特率计算、USART与UART的区别和中断处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、串口简介

1.串口介绍

2.波特率计算

二、HAL库的配置

1.时钟树的配置

2.CubeMX配置

三、代码编写


实验目的:利用串口控制LED灯的亮灭,并进行提示

实验平台:正点原子精英板

一、串口简介

1.串口介绍

    串口通信是一种设备间常用的串行通信方式,串口按位(bit)发送和接收字节。尽管比特
字节(byte)的串行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。
串口通信协议是指规定了数据包的内容,内容包含了起始位、主体数据、校验位及停止位,双
方需要约定一致的数据包格式才能正常收发数据的有关规范。在串口通信中,常用的协议包括
RS-232、RS-422 和 RS-485 等。

2.波特率计算

二、HAL库的配置

1.时钟树的配置

参考第一篇文章即可

2.CubeMX配置

配置为UART模式即可,省去时钟线,大部分时候异步方式即可

补充一些知识:

UART与USART区别

1)硬件设计

USART:通用同步和异步收发器
UART:通用异步收发器
当进行异步通信时,这两者是没有区别的。区别在于USART比UART多了同步通信功能。
这个同步通信功能可以把USART当做SPI来用,比如用USART来驱动SPI设备。

其中SPI IIC为同步通信  UART为异步通信, usart为同步&异步通信。

2)软件设计也存在同步发送和异步发送的区别:

同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。  
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。

同步是阻塞模式,异步是非阻塞模式。

3)单工\半双工\全双工

单工、半双工、全双工 单工数据传输只支持数据在一个方向上传输; 半双工数据传输允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信; 全双工数据通信允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。

I2C是半双工,SPI的全双工,uart是全双工。

 开启NVIC对应的中断接口

 配置波特率、停止位等参数,按下图配置即可,也可以按照自己需求配置。

 LED的配置参考:https://blog.youkuaiyun.com/hdh546/article/details/132192856

配置完成后生成代码即可。

三、代码编写

使用HAL库后用户需要完成的工作是,在串口初始化里使能接收/发送中断,重定义编写接收/发送回调函数。注意,接收中断需要在下次使用中断前软件重复开启,本次实验放在了回调函数里,也可以放在中断公共服务函数UARTx_IRQHandler()中。

在uart.c的用户编码区编写回调函数和输出复用函数,方便打印信息。

int fputc(int ch, FILE *f)
{
    while ((USART1->SR & 0X40) == 0);     /* 等待上一个字符发送完成 */

    USART1->DR = (uint8_t)ch;             /* 将要发送的字符 ch 写入到DR寄存器 */
    return ch;
}
 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//接收中断服务函数
{
    if(huart->Instance == USART1)//判断串口号
   {
			 if(receive_arrary[0]=='A')
			 {
			 printf("LED_ON\r\n");
             HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);
			 HAL_UART_Receive_IT(&huart1, (uint8_t *)receive_arrary, 1);   //再开启接收中断
			 }
			 else if(receive_arrary[0]=='B')
			 {
			  printf("LED_OFF\r\n");
              HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_SET);
			  HAL_UART_Receive_IT(&huart1, (uint8_t *)receive_arrary, 1);   //再开启接收中断
			 }
    }
}

一定要在初始化里开启中断接收,如下图

 实验现象:

 欢迎大家交流与指正!!!

<think>嗯,用户想了解如何在STM32 HAL中实现USART串口中断处理,包括示例代码和参考文档。首先,我需要回忆一下STM32 HAL的相关知识,特别是USART中断处理的部分。 首先,用户提到的HAL中USART的中断处理,通常涉及到配置串口参数、启用中断,以及编写中断回调函数。根据引用[2]和[4],使用DMA和空闲中断是常见的方法。比如,引用[4]提到串口1-4使用DMA+空闲中断,而串口5用接收中断+空闲中断。这可能意味着不同的配置方式,用户可能需要选择适合自己需求的方法。 接下来,用户需要示例代码。根据引用[2],用户在使用STM32CubeMX生成代码时可能遇到无法接收数据的问题,所以需要手动添加中断处理。HAL中,接收数据通常使用HAL_UART_Receive_IT函数启动中断接收,然后在中断发生时调用回调函数。比如,引用[3]提到开启空闲中断和错误中断,这可能涉及到修改CubeMX配置或直接操作寄存器。 参考文档方面,引用[1]提到了STM32F4系列的中文参考手册,虽然用户的问题是关于F1系列的,但参考手册的结构可能类似。同时,引用[2]和[4]提供了具体的HAL版本和配置步骤,需要确保用户使用HAL版本与示例匹配,避免兼容性问题。 可能需要注意的点:HAL中断处理流程,比如HAL_UART_IRQHandler会自动处理中断标志,并调用相应的回调函数。用户需要正确实现HAL_UART_RxCpltCallback等函数。此外,空闲中断的配置可能需要手动开启,如引用[3]所述,空闲中断未开启可能导致错误中断也无法触发。 用户可能遇到的问题:中断不触发,数据接收不完整。这可能需要检查中断优先级、DMA配置是否正确,或者是否在初始化后启动了接收中断。此外,需要确保在回调函数中重新启动接收,以持续接收数据。 总结步骤:1. 使用STM32CubeMX配置USART参数和中断;2. 生成代码并添加用户回调函数;3. 处理中断服务函数;4. 测试和调试。示例代码部分应展示初始化和回调函数的实现,可能包括DMA配置或中断接收的启动。 最后,生成相关问题需要考虑用户可能的后续问题,比如DMA与中断的区别、错误处理、性能优化等,如引用[4]提到的不同串口配置方式,可以引导用户进一步探索。</think>### STM32 HALUSART串口中断实现方法 #### 一、实现步骤 1. **配置USART参数与中断** 使用STM32CubeMX配置串口参数(波特率、数据位、停止位等),并开启接收中断和空闲中断[^2][^4]。 ```c // CubeMX生成的初始化片段(USART1为例) huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; HAL_UART_Init(&huart1); ``` 2. **启动接收中断** 在主程序中调用`HAL_UART_Receive_IT`函数启动接收中断: ```c uint8_t rx_buffer[64]; HAL_UART_Receive_IT(&huart1, rx_buffer, sizeof(rx_buffer)); ``` 3. **重写中断回调函数** 在用户代码中实现`HAL_UART_RxCpltCallback`处理接收完成事件,并重新启动接收: ```c void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 处理接收到的数据 // 重新启动接收中断 HAL_UART_Receive_IT(&huart1, rx_buffer, sizeof(rx_buffer)); } } ``` 4. **处理空闲中断(可选)** 若需要检测数据帧结束,需手动开启空闲中断: ```c __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); ``` 并在`stm32f1xx_it.c`中实现空闲中断处理: ```c void USART1_IRQHandler(void) { if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG(&huart1); // 处理空闲中断(数据接收完成) } HAL_UART_IRQHandler(&huart1); } ``` --- #### 、示例代码 ```c // main.c uint8_t rx_data[64]; int main(void) { HAL_Init(); SystemClock_Config(); MX_USART1_UART_Init(); HAL_UART_Receive_IT(&huart1, rx_data, sizeof(rx_data)); while (1) { // 主循环逻辑 } } // 接收完成回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 处理数据(例如通过DMA传输) // 重新启动接收 HAL_UART_Receive_IT(&huart1, rx_data, sizeof(rx_data)); } } ``` --- #### 三、参考文档 1. **STM32F1参考手册** 寄存器定义与中断标志说明参考《STM32F40xxx参考手册》(中文版)第25章-USART部分[^1]。 2. **HAL文档** STM32Cube_FW_F1_V1.8.5中的`stm32f1xx_hal_uart.h/c`文件包含函数原型与中断处理逻辑[^3]。 3. **应用笔记** DMA+空闲中断的配置方法可参考STM32官方应用笔记AN4031[^4]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乱码小伙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值