HAL库学习——串口中断

一、介绍

         串口的传输方式包括:轮询、中断DMA,在此要介绍的是关于HAL库底层串口接收中断流程的讲解,包括串口错误的处理,中断回调函数以及错误中断回调函数的执行。

 

二、配置流程

         首先使用STM32CubeMX配置串口参数和工作方式。如下图:

       配置好基础参数波特率和数据长度,校验位,停止位后, 选择NVIC Settings点击Enabled使能全局中断。

       这样整个串口配置就完成了。

 

三、开启接收中断

       在代码初始化调用HAL_UART_Receive_IT(&huart2, &gUart2.Temp, RECLEN)函数即可开启接收中断,这边gUart2结构体是自己定义用来存放串口接收的内容,RECLEN则指一次性接收几个字节后触发中断回调函数。这边先介绍一下串口底层数据的存放。串口收到一个字节数据时最先存放到移位寄存器内,然后移到RDR寄存器中。当RDR寄存器有值时则RXNE标志置1(指示接收非空),这时将RXNEIE标志置1则会触发中断。执行HAL_UART_Receive_IT函数的作用就是指定接收数据长度,存放的地址以及开启接收非空中断,还有接收函数的映射

 

四、中断流程

       当接收到一个字节的数据时进入了中断处理函数,由于这边使用的是USART2,所以进入的是USART2_IRQHandler:

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}

       紧接着进入HAL_UART_IRQHandler里面执行,点进去可以发现里面在做的是一些状态位读取以及判断,还有中断回调函数接收函数的入口。如下读取ISR状态寄存器以及CR1控制寄存器还有CR3控制寄存器的内容分别存放到isrflags、cr1its、cr3its。然后让状态寄存器去与上以下四种错误PE奇偶校验错误、FE帧错误、ORE溢出错误、NE噪声错误。查看状态位是否有以下四种错误。

  uint32_t isrflags   = READ_REG(huart->Instance->ISR);
  uint32_t cr1its     = READ_REG(huart->Instance->CR1);
  uint32_t cr3its     = READ_REG(huart->Instance->CR3);

  uint32_t errorflags;
  uint32_t errorco
### 使用STM32 HAL实现RTC万年历功能 #### 配置CubeMX 在使用STM32 HAL实现RTC的万年历功能之前,需要先通过STM32CubeMX完成基本配置。具体操作如下: 1. **设置时钟源** 在STM32CubeMX中,进入“Clock Configuration”,选择外部低速晶振(LSE)作为RTC的时钟源[^1]。 2. **启用RTC外设** 进入“Pinout & Configuration”界面,在“Peripherals”选项卡下找到RTC模块并将其启用。 3. **生成初始化代码** 完成以上配置后,点击“Generate Code”按钮生成初始代码框架。 --- #### 修改初始化代码 在生成的代码基础上,需对`MX_RTC_Init()`函数进行调整以支持万年历功能。以下是具体的改动说明: 1. **定义全局变量** 将原本局部声明的时间和日期结构体改为全局变量以便后续调用: ```c RTC_TimeTypeDef sTime; RTC_DateTypeDef DateToUpdate; ``` 2. **读取备份寄存器中的数据** 如果检测到RTC尚未被初始化,则从备份寄存器中恢复时间和日期信息,并重新加载至RTC硬件寄存器中: ```c else { DateToUpdate.Year = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3); DateToUpdate.Month = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4); DateToUpdate.Date = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR5); DateToUpdate.WeekDay = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR6); HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN); Read_AlarmInfo_FromBKP(); RTC_TimeShow(ShowTime1); // 显示当前时间 } ``` 上述逻辑确保即使设备断电重启,也能保持正确的时间和日期记录。 --- #### 中断处理程序设计 为了实现秒级精度以及闹钟提醒等功能,还需要编写相应的中断服务程序。以下是一个典型的RTC中断处理流程: ```c void RTC_IRQHandler(void) { if (__HAL_RTC_SECOND_GET_FLAG(&hrtc, RTC_FLAG_SEC)) { // 秒中断标志位判断 __HAL_RTC_SECOND_CLEAR_FLAG(&hrtc, RTC_FLAG_SEC); // 清除秒中断标志位 RTC_Get(); // 更新时间 } if (__HAL_RTC_ALARM_GET_FLAG(&hrtc, RTC_FLAG_ALRAF)) { // 闹钟A中断标志位判断 __HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF); // 清除闹钟A中断标志位 RTC_Get(); // 更新时间 } __HAL_RTC_CLEAR_FLAG(&hrtc, RTC_FLAG_SEC | RTC_FLAG_OWF); // 清理所有可能触发的异常状态 } ``` 此部分实现了两种类型的中断响应:一种用于每秒钟刷新显示;另一种则负责执行预设好的报警动作[^2]。 --- #### 调试工具集成 为了让调试更加直观方便,可以重写标准输入/输出流函数来配合串口通信打印日志消息。例如下面这段代码展示了如何让`printf`命令可以通过USART端口发送字符序列给PC终端查看运行状况: ```c int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF); return ch; } int fgetc(FILE *f) { uint8_t ch = 0; HAL_UART_Receive(&huart2, &ch, 1, 0xFFFF); return ch; } ``` 这样做的好处是可以随时监控系统的实时动态变化情况而无需额外增加复杂度[^3]。 --- ### 总结 综上所述,利用STM32 HAL开发具备完整万年历特性的实时时钟应用涉及多个方面的工作内容,包括但不限于基础环境搭建、核心算法定制化改造还有最后阶段测试验证环节等等诸多细节之处都需要格外留意才能达成预期目标效果最佳实践方案推荐按照上述步骤逐一实施直至完全满足项目需求为止!
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值