每乙個複雜的專案,都包括了許多基礎內容。每乙個複雜的任務,都是通過一系列簡單的分解動作組裝而成。
rtc就是諸多分解動作中重要的一環。在物聯網的各類裝置中,許多都需要利用rtc,才能為資料提供準確的定時。
rtc初始化根據bkp_readbackupregister讀數值進行判斷,如果讀數值不等於bkp_valid,說明沒有完成rtc初始化(rtc初始化完成後,會把backupregister設定為bkp_valid)。
rtc初始化時,將會有乙個延時等待時間,等待rtc晶振穩定。如果等待超時,則將返回1,表示初始化失敗。
設定時,會呼叫rtc_set設定當前的具體時間。這個時間在系統上電時,一次設定成功後,後續通過rtc電池供電,時間永不丟失。
如果bkp_readbackupregister(bkp_r_valid)==bkp_valid,表示rtc已經完成了初始化,則使能中斷,並通過rtc_get獲取當前rtc時間。
u8 rtc_init(void)
if (temp>=250) return 1;//初始化時鐘失敗,晶振有問題
rcc_rtcclkconfig(rcc_rtcclksource_lse); //設定rtc時鐘(rtcclk),選擇lse作為rtc時鐘
rcc_rtcclkcmd(enable); //使能rtc時鐘
rtc_waitforlasttask(); //等待最近一次對rtc暫存器的寫操作完成
rtc_waitforsynchro(); //等待rtc暫存器同步
rtc_itconfig(rtc_it_sec, enable); //使能rtc秒中斷
rtc_waitforlasttask(); //等待最近一次對rtc暫存器的寫操作完成
rtc_enterconfigmode(); //允許配置
rtc_setprescaler(32767); //設定rtc預分頻的值
rtc_waitforlasttask(); //等待最近一次對rtc暫存器的寫操作完成
rtc_set(2018,11,8,16,02,55); //設定時間
rtc_exitconfigmode(); //退出配置模式
// 向指定的後備暫存器中寫入使用者程式資料
bkp_writebackupregister(bkp_r_valid, bkp_valid); // 備份暫存器生效標誌
bkp_writebackupregister(bkp_r_adxl_set, adxl_initial_value); // adxl設定預設值
bkp_writebackupregister(bkp_r_acc_num, 0); // 3軸資料檔案序號
bkp_writebackupregister(bkp_r_acc_del_num, 0); // 3軸資料檔案待刪除序號
} else//已經完成了初始化,系統繼續計時
rtc_nvic_config();//rct中斷分組設定
rtc_get();//更新時間
return 0; //ok
}
rtc_set完成rtc時間的寫入和修改。設定時,呼叫rtc_setcounter(seccount); 其中引數seccount為時間戳。時間戳是指格林威治時間2023年01月01日00時00分00秒(北京時間2023年01月01日08時00分00秒)起至現在的總秒數。
u8 rtc_set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
}else temp-=365; //平年
temp1++;
} g_cainfo.year=temp1;//得到年份
temp1=0;
while (temp>=28)//超過了乙個月
else
temp1++;
} g_cainfo.month=temp1+1; //得到月份
g_cainfo.date=temp+1; //得到日期
} temp=timecount%86400; //得到秒鐘數
g_cainfo.time.hour=temp/3600; //小時
g_cainfo.time.min=(temp%3600)/60; //分鐘
g_cainfo.time.sec=(temp%3600)%60; //秒鐘
//g_cainfo.week=rtc_get_week(g_cainfo.year,g_cainfo.month,g_cainfo.date);//獲取星期
//printf("\r\nget rtc success");
return 0;
}
rtc_alarm_set用來設定定時。具體方法和前面相似,首先計算總秒數:seccount。然後使能外設時鐘,最後使能後備暫存器訪問。
具體設定alarm通過stm32的庫函式rtc_setalarm(seccount)完成設定。
u8 rtc_alarm_set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
計算閏年,當年c語言課程中的試題。
u8 is_leap_year(u16 year)
else return 1;
}else return 0;
}
設定rtc中斷優先順序配置,在rtc_init()中呼叫。
static void rtc_nvic_config(void)
rtc中斷處理中, 當rtc_getitstatus(rtc_it_sec) != reset時,rtc觸發了秒中斷,這時呼叫rtc_get獲取資訊,並設定g_bsecflag,作為標誌。
如果檢查到(rtc_getitstatus(rtc_it_alr)!= reset, 則可以進行鬧鐘中斷處理,例如,設定鬧鐘標誌位。當然,在這裡並未進行處理。
void rtc_irqhandler(void)
if(rtc_getitstatus(rtc_it_alr)!= reset)//鬧鐘中斷
rtc_clearitpendingbit(rtc_it_sec|rtc_it_ow); //清鬧鐘中斷
rtc_waitforlasttask();
}
其實任何乙個複雜的專案,都是由乙個又乙個簡單工程拼接而成的。當我們在砌磚時,不要忘記內心中規劃的那個美好的建築。
通過rtc_alarm_set可以設定定時時間。同時,需要在中斷處理函式中,設定相關標誌位
if(rtc_getitstatus(rtc_it_alr)!= reset)//鬧鐘中斷
在主迴圈中,檢查到標誌位後,進行相應處理,這裡僅僅進行簡單列印。
也可以通過rtc進行定時休眠和定時喚醒功能。具體方法是:
1. 主迴圈中,當sec達到15s時,設定15s後鬧鐘,然後進入待機模式sys_enter_standby;
主迴圈中,設定鬧鐘,進入待機模式
if (g_bsecflag) //每秒計時器
}
2. rtc中斷定時中,清中斷。rtc定時中斷中,不需要做其他操作。定時到達後,rtc定時會自動喚醒mcu;
if(rtc_getitstatus(rtc_it_alr)!= reset)//鬧鐘中斷
注意:standby喚醒後,程式會重頭開始執行, standby之後語句執行不到。
通過rtc設定系統進入待機模式,並定時喚醒,是乙個非常省電而且非常可靠的方法。
rtc操作原始碼:
rtc休眠並定時喚醒原始碼
**通過uart2輸出,波特率115200,執行結果如下:
當時間到達15s時,自動休眠,休眠30s後,再通過rtc中斷喚醒,中斷喚醒後,從頭開始執行,當然,休眠時間和喚醒時間可以自行調整設定。
STM32應用 第7節 低功耗設計
隨著電池供電的應用場景越來越對,非常有必要深入理解和應用stm32的低功耗設計。程式執行過程中,呼叫 wfi 命令,即可進入睡眠模式。wfi可以通過任意中斷喚醒,這裡採用按鍵中斷喚醒。pa15 void exti15 10 irqhandler void exti clearitpendingbit...
STM32應用 第8節 AM2320單線驅動
和常用的dht11相比較,am2320溫濕度感測器的溫濕度等級高許多,是乙個不錯的感測器選擇。該驅動經過開發和長期測試,穩定好用,採用單獨的.c和.h檔案編寫,方便移植到不同程式中。static void am2320 gpio config void brief am2320 初始化函式 para...
基於STM32的FREERTOS應用的幾個常見問題
1 怎樣將 freertos 移植到不同的cortex m 核心?答 若需將 freertos 移植到正確的cortex m 產品,您必須從正確的目錄匯入 port.c 檔案。例如,若微控制器是帶有iar 工具的 cortex m0 核心,則您必須從 freertos source portable...