STM32L051同時處理Alarm A和Alarm B中斷

同時處理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等,針對局域網環境下,用自研軟件控制打印機打印的應用場景,針對自研軟…