對于學習過51單片機的同學來說,一般使用RTC功能,一般都會使用51單片機+DS1302的方案,在STM32單片機中,因為STM32單片機自帶RTC模塊,所以我們只需要使用一個STM32即可,不需要外掛實時時鐘芯片了。
RTC實時時鐘簡介
"RTC"是Real Time Clock 的簡稱,意為實時時鐘。
STM32提供了一個秒中斷源和一個鬧鐘中斷源,修改計數(shù)器的值可以重新設置系統(tǒng)當前的時間和日期。
STM32的RTC外設,實質是一個掉電后還能繼續(xù)運行的定時器,通過配置,可以讓它準確地每秒鐘中斷一次。
所謂掉電,是指電源VDD斷開的情況下,為了RTC外設掉電可以繼續(xù)運行,必須給STM32芯片通過VBAT引腳接上外部3.3V供電。
當主電源VDD有效時,由VDD給RTC外設供電。
當VDD掉電后,由VBAT給RTC外設供電。
無論由什么電源供電,RTC中的數(shù)據(jù)始終都保存在屬于RTC的備份域中,如果主電源和VBAT都掉電,那么備份域中保存的所有數(shù)據(jù)都將丟失。(備份域除了RTC模塊的寄存器,還有42個16位的寄存器可以在VDD掉電的情況下保存用戶程序的數(shù)據(jù),系統(tǒng)復位或電源復位時,這些數(shù)據(jù)也不會被復位)。
- 上圖來自于《STM32中文參考手冊》
備份寄存器是42個16位的寄存器,可用來存儲84個字節(jié)的用戶應用程序數(shù)據(jù)。他們處在備份域里,當VDD電源被切斷,他們?nèi)匀挥蒝BAT維持供電,數(shù)據(jù)不會丟失,所以我們可以使用這些寄存器預存一些運行狀態(tài)信息。
比如我們可以在RTC初始化之后,對BKP_DR1寄存器寫入一個值,比如0x5050,然后在 RTC_Init(void)函數(shù)開始處,先讀取并判斷BKP_DR1寄存器的值是否為0x5050,進而可以知道系統(tǒng)的RTC是否有VBAT外部電源維持供電。
STM32時鐘系統(tǒng)
參考《STM32中文參考手冊》中對STM32的時鐘系統(tǒng)的詳細說明。
RTC的時鐘源可以來源于3個渠道:
- 來自于低速外部時鐘LSE,也就是外部的晶振,一般選用32.768KHz
- 來自于高速外部時鐘HSE的128分頻,即HSE/128
- 來自于低速內(nèi)部時鐘LSI
使用HSE分頻時鐘或者LSI的時候,在主電源VDD掉電的情況下,這兩個時鐘來源都會受到影響,因此沒法保證RTC正常工作(在有自動校準功能并對時鐘的精度要求不是很高的情況下,還是可以使用HSE分頻時鐘作為RTC時鐘的),所以RTC一般都選用低速外部時鐘LSE,晶振的頻率為實時時鐘模塊中常用的32.768KHz,因為32768 = 2^15,分頻容易實現(xiàn)1秒的時鐘頻率,所以被廣泛應用到RTC模塊。
在配置RTC模塊的時鐘時,把輸入的32768Hz的RTCCLK進行32768分頻得到實際驅動計數(shù)器的時鐘TR_CLK = RTCCLK/37768 = 1Hz,計時周期為1秒,計時器在TR_CLK的驅動下計數(shù),即每秒計數(shù)器RTC_CNT的值加1。
RTC時間設置
RTC時間設置就是對RTC計數(shù)器寄存器RTC_CNT進行設置。
該寄存器由兩個16位的寄存器RTC_CNTH和RTC_CNTL組成,總共32位,用來記錄秒鐘值。
理論上可以計算2^32 = 4,294,967,296? s,大約136年。
所以設置RTC時間或者獲取RTC時間,就是設置RTC_CNT寄存器或者獲取RTC_CNT寄存器的值。
所以封裝的設置時鐘的函數(shù)RTC_Set(),就是求得設定的時間與1970年1月1日 00:00:00之間的秒數(shù),然后通過RTC_SetCounter()函數(shù),寫入RTC_CNT寄存器即可。
注意:
每次操作RTC_CNT時應該要使能PWR 和 BKP 時鐘,允許訪問BKP域,否則會操作失敗。
/* Enable PWR and BKP clocks*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE); /* Wait until last write operation on RTC registers has finished*/RTC_WaitForLastTask();/* 修改當前RTC計數(shù)寄存器內(nèi)容 */RTC_SetCounter(Cnt);/* Wait until last write operation on RTC registers has finished*/RTC_WaitForLastTask();
RTC鬧鐘
在實際應用中,我們有時會用到定時鬧鐘功能,我們簡單的可以在main函數(shù)的while循環(huán)中,通過比對當前時間和設定時間值是否相等進行判斷是否定時時間到,比如:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
//主循環(huán) while(1) { times++; if(t!=calendar.sec) { t=calendar.sec; NowHour = calendar.hour; NowMinute = calendar.min; NowSecond = calendar.sec; if(NowHour==AlarmHour&&NowMinute==AlarmMinute&&NowSecond==AlarmSecond) { //執(zhí)行預定動作 } } }
除了上面的方法外,我們還可以使用RTC的鬧鐘中斷來實現(xiàn)。
-
使能RTC_IT_ALR中斷,并設置鬧鐘時間:
-
鬧鐘中斷響應
在主電源VDD有效的情況下(待機),RTC還可以配置鬧鐘事件使STM32退出待機模式。
結果展示
RTC_Init(void)函數(shù)中,設置初始化時間如下:
程序會在串口助手中,每秒鐘輸出一條時間信息,40S后執(zhí)行一次鬧鐘中斷。
STM32串口發(fā)送數(shù)據(jù)和接收數(shù)據(jù)方式總結!
STM32配置SPI通訊功能
還在敲代碼? 來看看如何自動生成"狀態(tài)機"代碼
SPI怎么玩?搞懂時序,運用自如
什么是DMA? STM32如何配置DMA?
STM32基礎分析——PWM配置
STM32單片機:獨立看門狗、窗口看門狗的配置
免責聲明:本文內(nèi)容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!