CM3计算板RTC闹钟唤醒系统
1、前言
一個周期性控制系統的核心為CM3計算板,在電池供電情況下要求盡可能提高使用時長。由于系統空閑時長較多,因此在考慮低功耗的情況下將系統關機以進一步降低功耗。需要注意的是,系統關機后需要在指定時間喚醒,繼續執行相關任務,這涉及到如何喚醒系統。
系統關機很容易用代碼實現功能,一旦關機系統的服務都掛掉,如何保留開機任務?需要借助系統外圍設計。
可以進一步抽象該需求,如何定時開機。目前我的設計比較暴力,其一,開機方式通過重置CM3計算板的Reset (RUN)引腳加以實現;其二,定時方式通過外部RTC時鐘芯片進行設置,且RTC時鐘芯片可以設置鬧鐘,產生硬件中斷等電平觸發跳變。
2、硬件
根據前面的描述,硬件連接示意圖如下所示。詳細電路連接不在此處羅列,以下介紹設計的要求。
- CM3:提供一組I2C接口用于設置外部RTC
- RTC:電池供電的實時時鐘芯片,用I2C進行通信,具有鬧鐘功能,能產生鬧鐘中斷
- MCU:識別RTC鬧鐘中斷信號,輸出CM3系統復位信號。
具體地,選用的RTC為DS3231,該RTC的芯片資料可以在這里查看,邏輯框圖大概就是這么回事。
本例的MCU作用很單一,檢測RTC中斷,并復位CM3。所以可以用很簡單的單片機,比如51單片機都可以,我這里用的是SOP8封裝的STC15W104單片機,STC單片機,你懂得。單片機采用中斷還是電平檢測都可以,這是由于DS3231產生鬧鐘中斷后,INT管腳在沒有被清除鬧鐘之前一直保持低電平,這很重要。
當然,如果不想對MCU單片機編程,也可以用其他邊沿觸發電路來代替MCU,比如采用JK觸發器實現下降沿的捕獲,再配合其他的硬件電路產生一個CM3復位電平即可。CM3的復位管腳Run為電平復位,拉低然后保持一點時間,再松開即可完成復位重啟。如下圖。
其他需要說明的,在采用MCU方式輸出CM3復位信號的方案下,通常不要用MCU管腳直接連接CM3的復位系統,做一次信號隔離和驅動以保證兩個系統的耦合性,例如,可以采用以下三極管驅動的方式。SYS_RST為MCU輸出的信號,注意,此處需要MCU拉電流,因此配置MCU的相關管腳為強輸出,即推挽輸出以保證足夠的驅動能力。
3、軟件
3.1 DS3231驅動軟件
DS3231采用標準I2C接口,Linux環境下在Github找到了現成的驅動rtcctl[點擊鏈接]。使用起來非常方便,簡單介紹使用方法。
(1) 下載
github地址:?https://github.com/bablokb/pi-wake-on-rtc
(2)? 安裝
cd pi-wake-on-rtc //進入下載的文件夾內 sudo tools/install //執行安裝腳本(3)? 使用
命令為rtcctl,詳細的命令參數如下所示:
Available commands (date and time are synonyms):help - dump list of available commandsinit - initialize RTCshow [date|time|alarm1|alarm2|sys]- display given type or alldump [control|status|alarm1|alarm1]- display registers (hex/binary format)set date|time|alarm1|alarm2|sys - set date/time, alarm1, alarm2 timesFormat: dd.mm.YYYY [HH:MM[:SS]] ormm/dd.YYYY [HH:MM[:SS]](does not turn alarm on!)on alarm1|alarm2 - turn alarm1/alarm2 onoff alarm1|alarm2 - turn alarm1/alarm2 offclear alarm1|alarm2 - clear alarm1/alarm2-flag****注意1,該腳本使用的I2C默認掛接到I2C1,需要在系統中提前打開I2C接口,用i2cdetect 識別一下是否存在ID為68的設備。
****注意2,該腳本部分為window環境下編輯,如果執行命令報錯,且提示存在"\r\n"錯誤,需要將該格式全部換成linux下的文件,可以參考這篇博文。
rtcctl命令使用起來很簡單,如下:
/* rtcctl 初始化 */ rtcctl init /* rtcctl 查看系統時間 */ rtcctl show sys /* rtcctl 查看鬧鐘1信息 */ rtcctl show alarm1 /* rtcctl 啟用鬧鐘1 */ rtcctl on alarm1 /* rtcctl 清除鬧鐘1 */ rtcctl clear alarm1 /* rtcctl 設置鬧鐘1時間 2019/06/01 15:30:00 鬧鐘產生中斷*/ rtcctl set 06/01/2019 15:30:003.2 MCU軟件
MCU主要檢測RTC鬧鐘中斷,RTC鬧鐘產生中斷后如果不清除則一直保持低電平狀態。簡單寫的一個邊沿識別程序如下:
void main() {uint16_t Alarm1_tick = 0;uint8_t isSYSRstWorked = 0;uint8_t Alarm_reg0 = 0;uint8_t Alarm_reg1 = 0;/*! I/O configure */P3M1 = 0x00;P3M0 = 0x0C;SYS_RST_Out = 0;//init pin statewhile(1){delay_ms(1);//systick/*! handle RTC wake up alarm1 */if(isSYSRstWorked == 0){Alarm_reg1 = Alarm_reg0;Alarm_reg0 = RTC_Alarm1_In;/*! check RTC alarm1 fall-edge */if((!Alarm_reg0) && Alarm_reg1 == 1){isSYSRstWorked = 1;}}else{Alarm1_tick++;/* ___________|-----|_____________ */if(Alarm1_tick < 2000) SYS_RST_Out = 1;else{Alarm1_tick = 0;SYS_RST_Out = 0;isSYSRstWorked = 0;}}} }可見,只要MCU識別到一個下降沿,就會產生一個CM3復位脈沖,脈沖寬度為2s,經過測試,可以實現CM3復位重啟,達到定時開機的要求了。
3.3 CM3執行邏輯
RTC和MCU的外設配置完成后,需要在CM3編寫執行邏輯。首先CM3開機后執行清除RTC鬧鐘(# rtcctl clear alarm1),或者直接對RTC進行初始化(# rtcctl init),其次執行正常監控管理任務,最后在關機之前設置下一次需要喚醒的RTC鬧鐘時間,推薦采用絕對時間方式,即計算重啟時間到1970年1月1日(epoch·time)過了多少秒,再將重啟時間的秒數轉換為rtcctl命令的時間戳 mm/dd/yyyy HH:MM:SS,即可。
4、最后
總的來說,這個方案容易想到,實現起來也不復雜,簡單的外設即可搞定。多謝github作者的rtcctl源碼,學習了。
總結
以上是生活随笔為你收集整理的CM3计算板RTC闹钟唤醒系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 采样次数不同平均值不一样_网络推广采取的
- 下一篇: apache 配置文件内使用 8080