1MM32L0130 RTC簡介
RTC 模塊是用于提供時間(時、分、秒、亞秒)和日期(年、月、日)功能的定時計數器,日歷以 BCD碼的格式顯示。內部包含周期性的喚醒單元,用于喚醒低功耗模式。支持夏令時補償,支持數字校準補償晶振精度的偏差。靈動微電子推出的MM32L0130系列MCU片上RTC外設具有以下特征:
可編程的日歷功能,包括時、分、秒、小時(12/24 小時制)、日期、星期、月份、年份
軟件可編程的夏令時補償
可編程鬧鐘,任意日歷字段的組合觸發鬧鐘
周期性自動喚醒單元,喚醒時間可配置
數字校準,精度為 0.95ppm
通過移位功能調整亞秒時間
支持可配置的時間戳功能,用于記錄事件的入侵時間
支持可配置的入侵檢測
5 個 32 位寬的備份數據寄存器,當發生入侵事件時會復位備份數據寄存器
可屏蔽中斷源
?鬧鐘
?喚醒單元
?時間戳事件
?入侵事件
2RTC功能描述
2.1 RTC模塊系統框圖
RTC中斷請求:
注:
當使用了 PC13 的時間戳或入侵的功能時,如果需要使用 PC13 用做復用功能或者輸出時,需要關閉時間戳或入侵對應的寄存器的使能位釋放 PC13。
RTC_ALARM 為鬧鐘或喚醒標志輸出, RTC_CALB 代表校準時鐘輸出,最終會輸出到 PAD,具體的復用關系參考芯片數據手冊與 RTC_OR 輸出控制寄存器。
TAMP_IN 代表外部入侵管腳, TIM_TS 代表時間戳管腳,具體的對應關系參考芯片數據手冊部分。
2.2 時鐘和預分頻
RTC 時鐘包含3個獨立可配置的時鐘源:分別是 LSE、 LSI、 HSE 時鐘的 128 分頻。RTC 內部包含2個預分頻器用于提供日歷或其它功能的時鐘,分別是一個 7 位的異步預分頻器與15位的同步預分頻器,為了降低功耗,建議將異步預分頻的值設置到可能的最大值。
異步分頻器輸出時鐘為fck_apre;同步預分頻器輸出時鐘為fck_spre。
計算公式如下:
fck_apre時鐘用于為二進制格式的 RTC_SSR 亞秒遞減計數器提供時鐘。當該遞減計數器計數到 0 時,會使用 PREDIV_S 的內容重載 RTC_SSR, fck_spre用于為日歷計數單元提供時鐘。
注:
針對 32.768KHZ 的 LSE 時鐘,異步分頻部分默認設置為 128,同步分頻部分設置為 256,產生1HZ(fck_spre)的時鐘用于日歷計數。
2.3 實時時鐘和日歷
RTC 時間和日期寄存器對應如下:
RTC_SSR 對應于亞秒
RTC_TR 對應于時間
RTC_DR 對應于日期
通過 APB 總線訪問日歷時間與日期寄存器時,由 RTC_CR 寄存器中的 BYPSHAD 位決定訪問實時的日歷寄存器還是影子寄存器,默認情況下訪問的是影子寄存器。
每隔 2 個 RTC 時鐘周期,會將實時的日歷寄存器復制到影子寄存器,并將 RTC_ISR 寄存器的 RSF位置 1,在停機和待機模式下不會執行復制操作。退出這兩種模式時,影子寄存器會在最長 2 個 RTC 時鐘周期后進行更新。影子寄存器可以通過系統復位復位。
2.4 可編程鬧鐘
RTC 鬧鐘單元被劃分為多個位 ,并且每個位支持獨立的使能或屏蔽。具體可以通過配置RTC_ALRMAR 寄存器 MSKx 位以及 RTC_ALRMASSR 寄存器的 MASKSSx 位。
配置 RTC_CR 寄存器中的 ALRAE 位使能可編程鬧鐘功能。當該位為 1,并且配置的 RTC_ALRMAR寄存器的值同當前日歷一致時, RTC_ISR 寄存器中的 ALRAF 位會置 1。同時配置 RTC_CR 寄存器中的ALRAIE 位等于 1 時,會產生鬧鐘中斷輸出。
配置 RTC_CR 寄存器中的位 OSEL[1:0]等于 1, ALRAF 連接到 RTC_ALARM 輸出,配置 RTC_CR寄存器的 POL 位選擇 RTC_ALARM 輸出極性。
MM32L0130的RTC外設還有周期喚醒單元、日歷讀取、復位RTC、RTC數字校準、RTC移位、時間戳、入侵檢測、RTC低功耗喚醒等功能, 在用戶手冊RTC章節有進行詳細描述,大家可以參考查閱,此處不再進行贅述,實驗涉及到再進行說明。
3實驗
3.1 實驗原理
RTC 鬧鐘單元被劃分為多個位,包括日期、星期、小時、分鐘、秒,并且每個位支持獨立的使能或屏蔽。當配置的鬧鐘A寄存器的值與當前日歷(時間/日期)寄存器的值一致時,鬧鐘發生,相應標志置位。如果使能了鬧鐘中斷,則會產生鬧鐘中斷輸出。
配置時間寄存器、日期寄存器的值來初始化日歷,配置鬧鐘A寄存器的值,并使能鬧鐘中斷,每次鬧鐘A寄存器的值與當前時間/日期寄存器的值一致時,鬧鐘發生,產生鬧鐘中斷。讀取日歷,如果查詢到鬧鐘發生,串口打印鬧鐘發生次數與當前日歷數據。
在日歷的基礎上實現鬧鐘功能,為便于觀察和驗證,實驗中配置鬧鐘發生的時間盡可能短,匹配到秒而將其余位屏蔽以使鬧鐘發生。
3.2 程序設計
3.21 RTCCAL_Initialize() 函數
函數實現日歷初始化配置,按如下步驟初始化日歷時間與日期寄存器:
1配置 RTC_ISR 寄存器中的 INIT 位為 1 以進入初始化模式
2等待 RTC_ISR 寄存器中的 INITF 位被硬件置 1
3編程 RTC_PRER 寄存器,配置同步與異步預分頻系數
4配置影子寄存器(RTC_TR 和 RTC_DR),加載日歷初值,配置 RTC_CR 寄存器中的 FMT 位選擇 12 或 24 小時制
5清除 RTC_ISR 寄存器中的 INIT 位退出初始化模式
注:
約 4 個 RTC 時鐘周期后,影子寄存器配置值加載到內部實時計數器。初始化影子寄存器后,等待 RTC_ISR 寄存器的 RSF 位置 1,才能讀取日歷。
voidRTCCAL_Initialize(void) { //Checkiftheclockisconfiguredforthefirsttime RTCCAL_InitTypeDefinit_struct; RTCCAL_TimeTypeDefsetTimeStruct; RTCCAL_DateTypeDefsetDateStruct; u16temp=0; RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWR,ENABLE);//(1) RCC_APB1PeriphClockCmd(RCC_APB1ENR_BKP,ENABLE);//(2) PWR_BackupAccessCmd(ENABLE);//(3) RCC_LSEConfig(RCC_LSE_ON); delay_x_cycle(2000); //CheckwhetherthespecifiedRCCmarkerissetornot,andwaitforthe //low-speedcrystaloscillatortobeready while(1){ if(RCC_GetFlagStatus(RCC_FLAG_LSERDY)!=RESET){//(4) break; } temp++; if(temp>=LSE_READY_TIMEOUT){ while(1){ __NOP(); } } delay_x_cycle(10); } RCC_APB1PeriphClockCmd(RCC_APB1ENR_RTC,ENABLE); //SettingRTCClock RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); RCC_RTCCLKCmd(ENABLE); RTCCAL_EnterInitMode();//(5) RTCCAL_WaitForSynchro(); RTCCAL_StructInit(&init_struct); init_struct.RTCCAL_AsynchPrediv=0x7F;//(6) init_struct.RTCCAL_SynchPrediv=0xFF; init_struct.RTCCAL_HourFormat=RTCCAL_HourFormat_24; RTCCAL_Init(&init_struct); RTCCAL_TimeStructInit(&setTimeStruct); setTimeStruct.RTCCAL_H12=RTCCAL_H12_AM;//(7) setTimeStruct.RTCCAL_Hours=15; setTimeStruct.RTCCAL_Minutes=34; setTimeStruct.RTCCAL_Seconds=0; RTCCAL_SetTime(RTCCAL_Format_BCD,&setTimeStruct); RTCCAL_DateStructInit(&setDateStruct); setDateStruct.RTCCAL_Year=0x16;//(8) setDateStruct.RTCCAL_Month=0x0A; setDateStruct.RTCCAL_Date=0x1A; setDateStruct.RTCCAL_WeekDay=0x01; RTCCAL_SetDate(RTCCAL_Format_BCD,&setDateStruct); RTCCAL_WaitForSynchro(); RTCCAL_ExitInitMode();//(9) }
(1)、(2)配置 RTC 需要使能 PWR 和 BKP 的時鐘
(3)RTC 寄存器寫保護,取消備份域的寫保護
(4)等待 LSE 時鐘穩定,選擇 LSE 作為 RTC 時鐘源
(5)確認 RTC 進入初始化模式
(6)配置 RTC 預分頻寄存器,時鐘頻率為 1HZ
(7)配置 PTC_TR時間寄存器,更新時間
(8)配置 PTC_DR日期寄存器,更新日期
(9)RTC 退出初始化模式
3.22 RTCCAL_AlarmConfig() 函數
函數實現鬧鐘初始化配置,按如下步驟編程鬧鐘:
1配置 RTC_CR 中的 ALRAE 位等于 0 禁止鬧鐘 A
2等待 RTC_ISR 寄存器中的 ALRAWF 位等于 1
3設置鬧鐘寄存器(RTC_ALRMASSR/RTC_ALRMAR)
4配置 RTC_CR 寄存器中的 ALRAE 位等于 1 使能鬧鐘 A
注:
對 RTC_CR 寄存器執行的寫操作。約 2 個 RTC 時鐘周期同步后生效。
voidRTCCAL_AlarmConfig(void) { RTCCAL_AlarmTypeDefRTCCAL_AlarmStructure; RTCCAL_NVIC_Config();//(1) //SetthealarmAMasks RTCCAL_AlarmStructure.RTCCAL_AlarmMask=(RTCCAL_ALRMAR_MSK4|RTCCAL_ALRMAR_MSK3|RTCCAL_ALRMAR_MSK2);//(2) RTCCAL_AlarmStructure.RTCCAL_AlarmDateWeekDaySel=RTCCAL_AlarmDateWeekDaySel_Date; RTCCAL_AlarmStructure.RTCCAL_AlarmDateWeekDay=RTCCAL_Weekday_Monday; RTCCAL_AlarmStructure.RTCCAL_AlarmTime.RTCCAL_Hours=0; RTCCAL_AlarmStructure.RTCCAL_AlarmTime.RTCCAL_Minutes=0; RTCCAL_AlarmStructure.RTCCAL_AlarmTime.RTCCAL_Seconds=9; if(ERROR==RTCCAL_AlarmCmd(RTCCAL_Alarm_A,DISABLE)){ while(1){}; } RTCCAL_SetAlarm(RTCCAL_Format_BCD,RTCCAL_Alarm_A,&RTCCAL_AlarmStructure); RTCCAL_AlarmSubSecondConfig(RTCCAL_Alarm_A,0xFF,RTCCAL_AlarmSubSecondMask_SS14_5);//(3) //EnablealarmAinterrupt RTCCAL_ITConfig(RTCCAL_IT_ALRA,ENABLE);//(4) if(ERROR==RTCCAL_AlarmCmd(RTCCAL_Alarm_A,ENABLE)){ while(1){}; } }
(1)配置RTC鬧鐘中斷,RTC&BKP全局中斷連接到 EXTI17
(2)配置鬧鐘A寄存器,屏蔽日期/星期、時、分,僅匹配秒
(3)配置鬧鐘A亞秒寄存器
(4)使能鬧鐘A中斷
3.23 RTC_BKP_IRQHandler() 函數
RTC鬧鐘中斷服務子程序,記錄鬧鐘中斷次數,置位標志位。
voidRTC_BKP_IRQHandler(void) { if(RTCCAL_GetITStatus(RTCCAL_IT_ALRA)!=RESET){ RTCCAL_ClearITPendingBit(RTCCAL_IT_ALRA); Flag_ALARM=1; if(AlarmCount>500){ RCC_RTCCLKCmd(DISABLE); AlarmCount=0; } else{ AlarmCount++; } EXTI_ClearITPendingBit(EXTI_Line17); } }
3.24 main() 函數
函數實現各模塊初始化,在循環中獲取當前日期、時間,查詢到鬧鐘發生,打印當前日期、時間。
s32main(void) { RTCCAL_DateTypeDefRTCCAL_tempDate; RTCCAL_TimeTypeDefRTCCAL_tempTime; DELAY_Init(); CONSOLE_Init(115200); RTCCAL_LSE_DemoInit(); while(1){ if(Flag_ALARM==1){ Flag_ALARM=0; printf("Alarmclockwastriggered%dtimes! ",AlarmCount); printf("20"); printf("%02d-",RTCCAL_tempDate.RTCCAL_Year); printf("%02d-",RTCCAL_tempDate.RTCCAL_Month); printf("%02d ",RTCCAL_tempDate.RTCCAL_Date); printf("%02d:",RTCCAL_tempTime.RTCCAL_Hours); printf("%02d:",RTCCAL_tempTime.RTCCAL_Minutes); printf("%02d ",RTCCAL_tempTime.RTCCAL_Seconds); printf(" "); } } }
3.3 實驗演示
下載程序運行,觀察串口調試助手:
串口調試助手間隔打印數據,比較前后兩次數據的日期和時間,相差1分鐘,在每分鐘的第9秒鬧鐘發生,和鬧鐘寄存器配置一致,運行情況和預期設計相符。
審核編輯:湯梓紅
-
mcu
+關注
關注
146文章
17148瀏覽量
351197 -
寄存器
+關注
關注
31文章
5343瀏覽量
120365 -
RTC
+關注
關注
2文章
538瀏覽量
66529 -
靈動微電子
+關注
關注
7文章
121瀏覽量
19640 -
MM32
+關注
關注
1文章
106瀏覽量
763
原文標題:靈動微課堂 (第233講) | MM32L0130 RTC 日歷和鬧鐘
文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動MM32MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論