同时处理Alarm A和Alarm B中断

当同时启用Alarm A和Alarm B时,需要在中断处理程序中准确判断是哪个闹钟触发了中断。以下是完整的解决方案:

中断判断与处理流程

1. 在RTC中断服务程序中判断中断源

// stm32l0xx_it.c
void RTC_IRQHandler(void)
{/* USER CODE BEGIN RTC_IRQn 0 */// 检查Alarm A中断标志if (__HAL_RTC_ALARM_GET_FLAG(&hrtc, RTC_ISR_ALRAF) != RESET){// 清除Alarm A中断标志__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF);// 处理Alarm A中断AlarmA_Handler();printf("Alarm A Triggered\n");}// 检查Alarm B中断标志if (__HAL_RTC_ALARM_GET_FLAG(&hrtc, RTC_ISR_ALRBF) != RESET){// 清除Alarm B中断标志__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRBF);// 处理Alarm B中断AlarmB_Handler();printf("Alarm B Triggered\n");}// 检查Wakeup定时器中断标志if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_ISR_WUTF) != RESET){// 清除Wakeup中断标志__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);// 处理Wakeup中断WakeUp_Handler();printf("WakeUp Timer Triggered\n");}/* USER CODE END RTC_IRQn 0 */// 调用HAL库的中断处理函数HAL_RTC_AlarmIRQHandler(&hrtc);HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc);/* USER CODE BEGIN RTC_IRQn 1 *//* USER CODE END RTC_IRQn 1 */
}

2. 实现各中断的处理函数

// alarm_handlers.c
#include "alarm_handlers.h"// Alarm A处理函数
void AlarmA_Handler(void)
{// 执行Alarm A特定的任务HAL_GPIO_TogglePin(LED_A_GPIO_Port, LED_A_Pin);// 可以在此重新设置Alarm A// Reset_AlarmA();
}// Alarm B处理函数
void AlarmB_Handler(void)
{// 执行Alarm B特定的任务HAL_GPIO_TogglePin(LED_B_GPIO_Port, LED_B_Pin);// 可以在此重新设置Alarm B// Reset_AlarmB();
}// Wakeup处理函数
void WakeUp_Handler(void)
{// 执行唤醒后的任务printf("System Woke Up from Stop Mode\n");// 禁用Wakeup定时器(除非需要再次使用)HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
}

完整的中断处理流程

ALRAF置位
ALRBF置位
WUTF置位
RTC中断触发
检查中断标志
处理Alarm A
处理Alarm B
处理Wakeup
清除ALRAF标志
清除ALRBF标志
清除WUTF标志
执行Alarm A任务
执行Alarm B任务
执行Wakeup任务
退出中断

关键配置说明

1. 中断标志位

  • Alarm A: RTC_ISR_ALRAF (寄存器ISR的位0)
  • Alarm B: RTC_ISR_ALRBF (寄存器ISR的位1)
  • Wakeup定时器: RTC_ISR_WUTF (寄存器ISR的位2)

2. 清除中断标志

  • 使用__HAL_RTC_ALARM_CLEAR_FLAG()宏清除Alarm标志
  • 清除标志后,中断挂起位也会自动清除

3. 中断优先级处理

当多个中断同时发生时,处理顺序取决于检查顺序:

  1. 先检查Alarm A
  2. 然后检查Alarm B
  3. 最后检查Wakeup定时器

如果需要改变优先级,可以调整检查顺序。

设置双闹钟的示例代码

1. 配置Alarm A和Alarm B

// rtc.c
void MX_RTC_Init(void)
{// ... 其他初始化代码// 配置Alarm ARTC_AlarmTypeDef sAlarmA = {0};sAlarmA.AlarmTime.Hours = 0x0;sAlarmA.AlarmTime.Minutes = 0x0;sAlarmA.AlarmTime.Seconds = 0x20; // 32秒触发sAlarmA.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_HOURS | RTC_ALARMMASK_MINUTES;sAlarmA.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;sAlarmA.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;sAlarmA.AlarmDateWeekDay = 0x1;sAlarmA.Alarm = RTC_ALARM_A;if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarmA, RTC_FORMAT_BCD) != HAL_OK){Error_Handler();}// 配置Alarm BRTC_AlarmTypeDef sAlarmB = {0};sAlarmB.AlarmTime.Hours = 0x0;sAlarmB.AlarmTime.Minutes = 0x1;  // 1分钟触发sAlarmB.AlarmTime.Seconds = 0x0;sAlarmB.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_HOURS | RTC_ALARMMASK_SECONDS;sAlarmB.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;sAlarmB.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;sAlarmB.AlarmDateWeekDay = 0x1;sAlarmB.Alarm = RTC_ALARM_B;if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarmB, RTC_FORMAT_BCD) != HAL_OK){Error_Handler();}
}

2. 中断处理优化建议

  1. 避免在中断中执行耗时操作

    void AlarmA_Handler(void)
    {// 仅设置标志,在主循环中处理alarmA_triggered = true;
    }
    
  2. 处理同时触发的情况

    if (__HAL_RTC_ALARM_GET_FLAG(&hrtc, RTC_ISR_ALRAF) && __HAL_RTC_ALARM_GET_FLAG(&hrtc, RTC_ISR_ALRBF))
    {// 处理双闹钟同时触发的情况Handle_Dual_Alarm();
    }
    
  3. 添加错误处理

    if (__HAL_RTC_ALARM_GET_FLAG(&hrtc, RTC_ISR_ALRAWF))
    {// Alarm A写入正在进行中printf("Alarm A register is being written\n");
    }
    

调试技巧

  1. 使用GPIO调试

    void AlarmA_Handler(void)
    {HAL_GPIO_WritePin(DEBUG_A_GPIO_Port, DEBUG_A_Pin, GPIO_PIN_SET);// ... 处理代码HAL_GPIO_WritePin(DEBUG_A_GPIO_Port, DEBUG_A_Pin, GPIO_PIN_RESET);
    }
    
  2. 记录中断时间

    void AlarmA_Handler(void)
    {HAL_RTC_GetTime(&hrtc, &lastAlarmATime, RTC_FORMAT_BIN);// ... 其他处理
    }
    
  3. 检查中断频率

    static uint32_t alarmA_count = 0;
    void AlarmA_Handler(void)
    {alarmA_count++;if (alarmA_count % 10 == 0) {printf("Alarm A triggered %lu times\n", alarmA_count);}
    }
    

通过以上方案,您可以准确区分和处理Alarm A、Alarm B以及Wakeup定时器的中断,实现复杂的定时任务调度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/93316.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/93316.shtml
英文地址,请注明出处:http://en.pswp.cn/web/93316.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV---morphologyEx形态学操作

在计算机视觉与图像处理领域,形态学操作是一种基于图像形状的非线性处理方法,广泛应用于噪声去除、边缘检测、目标分割等任务。OpenCV提供的morphologyEx函数是形态学操作的“瑞士军刀”,它整合了多种高级形态学运算,能够实现开运…

RuoYi-Cloud 接入 Sentinel 的 3 种限流方式

场景: 服务:ruoyi-robot(对外接口统一在 /external/gs/**) 网关:ruoyi-gateway(转发到 ruoyi-robot) 注册/配置:Nacos 流控:Sentinel 1.8.x 控制台 Dashboard&#x…

快速搭建python HTTP Server测试环境

这里用python http.server搭建一个api测试环境,自定义请求处理程序,以模拟不同api相应。 1 服务代码 /api/data,端口8000,GET 返回json数据为"{"message": "This is a sample API response"}" 代…

Docker容器定时任务时区Bug导致业务异常的环境变量配置解决方案

Docker容器定时任务时区Bug导致业务异常的环境变量配置解决方案 🌟 Hello,我是摘星! 🌈 在彩虹般绚烂的技术栈中,我是那个永不停歇的色彩收集者。 🦋 每一个优化都是我培育的花朵,每一个特性都是…

解锁Dify与MySQL的深度融合:MCP魔法开启数据新旅程

文章目录解锁Dify与MySQL的深度融合:MCP魔法开启数据新旅程引言:技术融合的奇妙开篇认识主角:Dify、MCP 与 MySQL(一)Dify:大语言模型应用开发利器(二)MCP:连接的桥梁&am…

杂记 02

1 WSL安装 WSL的安装遇到了问题,睡醒起来发现电脑蓝屏了,linux系统没装好,但是好像大部分开发环境都是linux下需要的,先这样用一下吧,到时候再说。可以问下前辈开发细节,主要是网络代理问题,保…

剧本杀小程序系统开发:重构推理娱乐生态

在娱乐产业蓬勃发展的今天,推理娱乐作为一种充满智慧和挑战的娱乐形式,受到了越来越多人的喜爱。剧本杀,作为推理娱乐的代表之一,正以其独特的魅力吸引着大量玩家。而剧本杀小程序系统开发,则为推理娱乐生态的重构带来…

力扣习题:基本计算器

本片内容我们将针对于一个力扣中的一道很经典的习题:基本计算器。 这道题目十分经典,在很多大厂的面试题中都有出现过 因此我们将进一步来学习 该题目代码已经上传作者的个人gitee:CPP 学习代码库: C代码库新库,旧有C仓库满员了喜…

Element用法---Loading 加载

仅供参考 文章目录一、加载动画二、Loading 组件1、指令调用 Loading2、服务调用 Loading一、加载动画 当我们打开某个页面时,如果需要加载的数据很多或者网络很差,页面加载就会非常缓慢,中间可能会很长时间显示空白,那么就需要加…

飞算AI 3.2.0实战评测:10分钟搭建企业级RBAC权限系统

飞算AI 3.2.0实战评测:10分钟搭建企业级RBAC权限系统 🌟 Hello,我是摘星! 🌈 在彩虹般绚烂的技术栈中,我是那个永不停歇的色彩收集者。 🦋 每一个优化都是我培育的花朵,每一个特性都…

事务的四大特性

事务(Transaction)是数据库管理系统(DBMS)中用于保证数据操作正确性和一致性的核心机制。事务的特性通常用 ACID 四个字母概括,分别代表 原子性(Atomicity)、一致性(Consistency&…

WIN11系统下Open3D 0.19.0支持GPU的python版本

前往Open 3D官网下载https://github.com/isl-org/Open3D下载对应版本的源码。 根据官方手册利用cmake进行编译&安装,其中需要修改一些代码适应于win 11系统,编译时间较长需要耐心等待。最后,安装结果如下图,搞了四天&#xff…

ICCV 2025 | 4相机干掉480机位?CMU MonoFusion高斯泼溅重构4D人体!

​​​​ 近日,卡内基梅隆大学(Carnegie Mellon University)的研究团队在动态场景重建领域取得重要进展。其发表于ICCV 2025的论文《MonoFusion: Sparse-View 4D Reconstruction via Monocular Fusion》提出创新方法MonoFusion 。该方法突破常…

ADB 无线调试连接(Windows + WSL 环境)

gradle wrapper --gradle-version 8.4 Windows WSL 成功连接 Android 设备(用于 ./gradlew installDebug)的完整过程总结:✅ ADB 无线调试连接过程(Windows WSL 环境) 📌 目标:从 WSL 中通过 …

【.net core】【wetercloud】处理前端项目免登陆,且从前端项目跳转至系统内时的问题

1.前端项目访问后台内容时免登陆(一般用于后台接口需要校验登陆时)处理思路:将后台用户的登陆校验令牌信息在用户登录后添加至前端项目访问地址的参数列表中,如:https://yourdomain/Home/Index#/https://yourdomain/vi…

设备 AI 知识库,管理效率新飞跃

在设备管理领域,高效解决设备故障、合理规划维护工作对企业生产运营至关重要。易点易动设备管理系统新推出的设备 AI 知识库,为提升管理效率带来了新契机。设备 AI 知识库集成先进的人工智能技术,是设备管理领域的创新应用。易点易动设备管理…

C#绘制斐波那契螺旋

Fabonacci 数列,也就是”兔子数列“, 如果第一项为0的话,就是, 0,1,1,2,3,5,8,13,21,34,55,89……

JavaScript 任务 - clearTimeout 函数与 clearInterval 函数

clearTimeout 函数 1、基本介绍 clearTimeout 函数用于取消先前通过 setTimeout 函数设置的定时器 clearTimeout(【timeoutID】)参数说明timeoutID要取消的定时器的标识符,这个 ID 是由 setTimeout 函数返回的2、演示 let timeoutId1 setTimeout(() > {console.…

在 CentOS 7 中使用 systemd 创建自定义服务

systemd 创建自定义服务简述创建自定义服务步骤文件覆盖优先级创建服务流程在 /etc/systemd/system/ 目录下创建 .service 文件(需 root 权限):编写服务配置模板Systemd 服务文件三大区块详解[Unit] 区块 - 服务元数据与依赖[Service] 区块 -…

【QT】printsupport库远程实现打印机打印

【QT】printsupport库远程实现打印机打印 前言 思路 实现 当前所有可用打印机浏览 打印预览 打印输出 手动选择打印 自动打印 防呆补充 库打包 前言 在打印机的通讯控制方式中,有USB、网口、串口、WIFI等,针对局域网环境下,用自研软件控制打印机打印的应用场景,针对自研软…