新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 結(jié)合RTC實(shí)現(xiàn)的“智能定時(shí)任務(wù)系統(tǒng)”:設(shè)計(jì)與實(shí)戰(zhàn)

        結(jié)合RTC實(shí)現(xiàn)的“智能定時(shí)任務(wù)系統(tǒng)”:設(shè)計(jì)與實(shí)戰(zhàn)

        作者:嵌入式芯視野 時(shí)間:2025-07-17 來(lái)源:今日頭條 收藏

        在低功耗嵌入式系統(tǒng)中,定時(shí)喚醒執(zhí)行任務(wù)是一個(gè)常見(jiàn)需求,比如定時(shí)上傳數(shù)據(jù)、定時(shí)采集傳感器信息、定時(shí)進(jìn)入/退出低功耗模式等。系列MCU內(nèi)置RTC模塊,不僅可提供實(shí)時(shí)時(shí)鐘,還支持低功耗喚醒和帶日期的定時(shí)調(diào)度。

        本文將基于平臺(tái),介紹如何構(gòu)建一個(gè)支持用戶可配置任務(wù) + + 靈活喚醒處理的“智能定時(shí)任務(wù)系統(tǒng)”。并通過(guò)完整的實(shí)例代碼進(jìn)行剖析,具有較強(qiáng)實(shí)用性。


        一、核心需求分析

        • 用戶配置任務(wù):支持配置多個(gè)“何時(shí)執(zhí)行什么操作”的定時(shí)任務(wù),任務(wù)存儲(chǔ)在Flash中。

        • :系統(tǒng)低功耗運(yùn)行,RTC定時(shí)器喚醒MCU按計(jì)劃執(zhí)行任務(wù)。

        • 喚醒后任務(wù)執(zhí)行:自動(dòng)加載任務(wù)表,匹配當(dāng)前時(shí)間,執(zhí)行對(duì)應(yīng)動(dòng)作。

        • 任務(wù)自動(dòng)循環(huán):支持按天/小時(shí)/分鐘循環(huán)任務(wù)。


        二、系統(tǒng)結(jié)構(gòu)設(shè)計(jì)

        [ 配置接口 ]
            ↑[任務(wù)存儲(chǔ)區(qū)] ←→ [RTC管理模塊] ←→ [任務(wù)調(diào)度器] ←→ [用戶任務(wù)處理]
                                   ↑                   [低功耗控制模塊]

        三、RTC喚醒基礎(chǔ)配置

        使用的RTC + Alarm A功能,作為喚醒觸發(fā)源。

        void RTC_AlarmAConfig(uint8_t hour, uint8_t min, uint8_t sec){
           RTC_AlarmTypeDef sAlarm = {0};

           sAlarm.AlarmTime.Hours   = hour;
           sAlarm.AlarmTime.Minutes = min;
           sAlarm.AlarmTime.Seconds = sec;
           sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY; // 只匹配時(shí)分秒
           sAlarm.Alarm = RTC_ALARM_A;

           HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
        }

        喚醒中斷回調(diào):

        void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc){
           rtc_wakeup_flag = 1;
        }

        四、定時(shí)任務(wù)結(jié)構(gòu)設(shè)計(jì)

        定義任務(wù)數(shù)據(jù)結(jié)構(gòu),支持 Flash 存儲(chǔ)和用戶配置:

        #define MAX_TASK_NUM 10typedef struct {
           uint8_t enable;    uint8_t hour;    uint8_t minute;    uint8_t repeat_day;   // 0x7F:每天,bit0=周日, bit1=周一...
           uint8_t task_id;      // 執(zhí)行的任務(wù)編號(hào)} rtc_task_t;rtc_task_t g_task_list[MAX_TASK_NUM];

        五、用戶任務(wù)執(zhí)行處理

        根據(jù)任務(wù) ID 執(zhí)行實(shí)際操作:

        void execute_user_task(uint8_t task_id){    switch (task_id) {        case 0: toggle_led(); break;        case 1: collect_sensor(); break;        case 2: send_data(); break;        default: break;
           }
        }

        六、RTC時(shí)間匹配調(diào)度器

        每次系統(tǒng)被喚醒時(shí),匹配當(dāng)前 RTC 時(shí)間是否對(duì)應(yīng)一個(gè)任務(wù):

        void check_and_run_rtc_tasks(void){
           RTC_TimeTypeDef time;
           RTC_DateTypeDef date;
           HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
           HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);

           uint8_t weekday_mask = 1 << date.WeekDay;

           for (int i = 0; i < MAX_TASK_NUM; i++) {
               if (!g_task_list[i].enable) continue;
               if (g_task_list[i].hour == time.Hours &&
                   g_task_list[i].minute == time.Minutes) {
                   if (g_task_list[i].repeat_day & weekday_mask) {
                       execute_user_task(g_task_list[i].task_id);
                   }
               }
           }}

        七、低功耗進(jìn)入與喚醒流程

        1. 設(shè)置最近的下次任務(wù)時(shí)間

        每次執(zhí)行完任務(wù)后,根據(jù)任務(wù)表,找出最近的下一個(gè)任務(wù)時(shí)間點(diǎn),并設(shè)置為 Alarm A:

        void update_next_rtc_alarm(void){    // 簡(jiǎn)單示例:找出第一個(gè)啟用任務(wù)作為下次 Alarm
           for (int i = 0; i < MAX_TASK_NUM; i++) {        if (g_task_list[i].enable) {
                   RTC_AlarmAConfig(g_task_list[i].hour, g_task_list[i].minute, 0);            break;
               }
           }
        }

        可進(jìn)一步排序任務(wù)時(shí)間并計(jì)算最接近當(dāng)前時(shí)間的任務(wù),提高效率。

        2. 進(jìn)入低功耗模式

        void enter_stop_mode(void)
        {    HAL_SuspendTick();    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);    HAL_ResumeTick();
        }

        喚醒后恢復(fù)系統(tǒng)時(shí)鐘和功能:

        void system_resume_from_stop(void){
           SystemClock_Config(); // 重新配置系統(tǒng)時(shí)鐘}

        八、任務(wù)配置接口(可選)

        通過(guò)串口或屏幕提供簡(jiǎn)單配置接口:

        // 示例:串口接收命令配置任務(wù)// 命令格式:TASK 1 08 30 7F 0// 含義:任務(wù)1,8:30,每天執(zhí)行,執(zhí)行任務(wù)編號(hào)0void parse_task_command(const char* cmd){    uint8_t idx, h, m, days, id;    if (sscanf(cmd, "TASK %hhu %hhu %hhu %hhx %hhu", &idx, &h, &m, &days, &id) == 5) {
               g_task_list[idx].enable = 1;
               g_task_list[idx].hour = h;
               g_task_list[idx].minute = m;
               g_task_list[idx].repeat_day = days;
               g_task_list[idx].task_id = id;        // 保存到Flash
               save_task_to_flash(g_task_list, sizeof(g_task_list));
           }
        }

        九、整體工作流程圖

        上電 → 加載任務(wù) → 設(shè)置最近Alarm A → 進(jìn)入STOP模式
               ↑                             ↓
           Flash配置 ← 用戶設(shè)置 ← 串口/屏幕   ← RTC喚醒 → 執(zhí)行匹配任務(wù) → 更新Alarm → 進(jìn)入STOP

        十、工程建議與總結(jié)

        1. 任務(wù)存儲(chǔ):使用內(nèi)部 Flash 或外部 EEPROM 保存任務(wù)表;

        2. 時(shí)間邊界判斷:可引入“分鐘偏移判斷”,避免誤判;

        3. 喚醒延遲容忍:可通過(guò)軟件 Timer 判斷是否錯(cuò)過(guò)喚醒時(shí)間;

        4. 任務(wù)重復(fù)機(jī)制:可擴(kuò)展支持一次性/周期任務(wù)等多類(lèi)型。


        結(jié)語(yǔ)

        結(jié)合STM32的RTC功能,我們可以構(gòu)建一個(gè)低功耗、高靈活性、可配置的定時(shí)任務(wù)系統(tǒng),非常適用于IoT節(jié)點(diǎn)、遠(yuǎn)程采集設(shè)備、智能家電等場(chǎng)景。通過(guò)本文的接口定義、調(diào)度策略與實(shí)例演示,你可以輕松實(shí)現(xiàn)自己的RTC任務(wù)系統(tǒng),并為后期擴(kuò)展(如OTA配置、LCD顯示)打下基礎(chǔ)。


        關(guān)鍵詞: STM32 RTC定時(shí)喚醒

        評(píng)論


        相關(guān)推薦

        技術(shù)專(zhuān)區(qū)

        關(guān)閉
        主站蜘蛛池模板: 双城市| 东乌| 祁门县| 云安县| 延津县| 江源县| 思南县| 河东区| 兴安盟| 九龙坡区| 藁城市| 巢湖市| 马山县| 玛多县| 高淳县| 栖霞市| 吉林市| 云梦县| 利辛县| 邮箱| 普定县| 石棉县| 新昌县| 塘沽区| 天门市| 迁西县| 洪湖市| 安图县| 西乡县| 莱州市| 平凉市| 临海市| 广河县| 辉南县| 禹城市| 剑河县| 中卫市| 开远市| 易门县| 沙坪坝区| 定结县|