Ⅰ、概述
接著上一篇文章來講述關于RTC的計數功能,我們以實例RTC日歷(讀寫年、月、日、星期、時、分、秒)來講述該章節。
STM32F1系列芯片的RTC功能和其他系列(F0、F2、F4等)相比來說,功能要弱一點,原因在于F1系列的RTC日歷功能需要我們通過軟件進行處理(換算RTC計數值)才能真正實現RTC日歷的功能,而其他系列芯片不用這么麻煩,可直接讀取日歷值。
該文和上一篇文章的區別:1、RTC時鐘源選擇LSE(外部低速時鐘); 2、分頻值是32768; 3、讀寫了RTC_CNT(計數值),用于RTC日歷。
本文章提供的實例工程“STM32F10x_RTC日歷(LSE)”,其實驗效果是:
主函數間隔0.5秒LED變化一次;
間隔1秒中斷:讀取日歷并打印出來
電腦串口調試助手接收到數據:年月日星期時分秒
關于本文的更多詳情請往下看。
Ⅱ、實例工程下載
筆者針對于初學者提供的例程都是去掉了許多不必要的功能,精簡了官方的代碼,對初學者一看就明白,以簡單明了的工程供大家學習。
筆者提供的實例工程都是在板子上經過多次測試并沒有問題才上傳至360云盤,歡迎下載測試、參照學習。
提供下載的軟件工程是基于Keil(MDK-ARM) v5版本、STM32F103ZE芯片,但F1其他型號也適用(適用F1其他型號:關注微信,回復“修改型號”)。
STM32F10x_RTC日歷(LSE)實例源代碼工程:
https://yunpan.cn/cBDwPJcChZRFE 訪問密碼 f7c0
STM32F10x_RTC日歷(LSI)實例源代碼工程:
https://yunpan.cn/cBDwSikRhZ2Nk 訪問密碼 d65d
STM32F1資料:
https://yunpan.cn/crBUdUGdYKam2 訪問密碼 ca90
Ⅲ、原理描述
以筆者個人學習經歷來說,想要掌握其真正原理,最好還是查看參考手冊(現在有很多都翻譯為中文了),里面模塊的框圖,從框圖中大概就可以看到該模塊有些什么功能及其工作的原理。
RTC框圖:
從上面系統框圖來分析“RTC秒中斷”和“RTC_CNT計數”的原理:
1.RTC時鐘源,總共有三類:
RCC_RTCCLKSource_LSE
RCC_RTCCLKSource_LSI
RCC_RTCCLKSource_HSE_Div128
本文實例代碼是:RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
重點:
細心的朋友可能會發現:筆者還提供了一個實例“STM32F10x_RTC日歷(LSI)”。對,這個實例是以LSI內部低速時鐘作為RTC時鐘源。
先問兩個問題:1、為什么不建議使用LSI作為時鐘源來設計日歷? 2、兩個實例工程之間的差別? 將實例中使用“LSE”時鐘改為“LSI”時鐘,其他地方不該可以嗎?【在下面解答】
2.RTC分頻:
本文實例代碼是:RTC_SetPrescaler(32768-1);
外部低速時鐘頻率為32.768K,我們要達到1秒計數(RTC_CNT)一次,則需要分頻32768.
3.RTC中斷:
RTC中斷有三種:
RTC_IT_SEC秒中斷
RTC_IT_ALR鬧鐘中斷
RTC_IT_OW(計數)溢出中斷
本文實例是:RTC_ITConfig(RTC_IT_SEC, ENABLE);
使能RTC_IT_SEC秒中斷,間隔1秒中斷一次,打印日歷。
再次強調:
這里的“秒中斷”是概念上的秒中斷,它的中斷間隔時間是根據你選擇的時鐘源和分頻值決定的,并非真正的1秒鐘中斷一次。本文提供的實例是1秒鐘中斷一次。
4.RTC日歷的來由:
在文章開頭已經說了,F1系列中RTC只要RTC_CNT寄存器,不像F0、F4等有現成的日歷(年月日時分秒)寄存器,因此,我們是通過軟件換算而得來的日歷。
Ⅳ、源代碼分析
筆者以F1標準外設庫(同時也建議初學者使用官方的標準外設庫)為基礎建立的工程,主要以庫的方式來講述(若您的F1芯片與提供工程不一樣,可微信回復“修改型號”)。
下面將講述關于“RTC秒中斷”重要的、容易弄錯的幾點:
1.RCC時鐘源
該函數位于bsp.c文件下面;
RCC是很多初學者,甚至已經工作的朋友容易遺漏的地方,有很多朋友覺得它使用的外設不正常,很大部分是沒有配置RCC導致的。
重點注意:
A.外設RCC時鐘的配置要在其外設初始化的前面;
B.匹配對應時鐘。
比如:RCC_APB2外設不要配置在RCC_APB1時鐘里面
【如:RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);這樣能編譯通過,但這是錯誤的代碼】
2. RTC配置
該函數位于rtc.c文件下面;
該函數請結合參考手冊(框圖和寄存器)理解。
注意4點:
A.使能后備區域:PWR_BackupAccessCmd(ENABLE);
從系統框圖可以看見RTC有陰影部分,其實這部分就是后備區域。因此,需要使能,這也是為什么上面需要配置RCC時鐘的原因。
B.選擇RTC時鐘源:RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
在原理描述中說了,RTC時鐘源有三種:
RCC_RTCCLKSource_LSE
RCC_RTCCLKSource_LSI
RCC_RTCCLKSource_HSE_Div128
可以在源代碼中查看其參數,也是有3中可以選擇。
C.使能RTC鬧鐘中斷:RTC_ITConfig(RTC_IT_SEC,ENABLE);
RTC有三類中斷:
RTC_IT_SEC秒中斷
RTC_IT_ALR鬧鐘中斷
RTC_IT_OW(計數)溢出中斷
上一篇文章提供的拓展功能“RTC鬧鐘”就是使用鬧鐘中斷,可以下載實例工程查看源代碼。
D.RTC分頻:RTC_SetPrescaler(32767);
我們是為了得到真正的1秒鐘中斷一次。
3. RTC初始化
該函數位于rtc.c文件下面;
A.我們使用BKP保存“標志位”數據(第一次才初始化,后面就不用初始化了)。我們初始化時間為:2016年7月18日 1800(假如為當前值)。 如果有電池,則會按照這個時間一直持續下去,系統掉電之后也不會影響時鐘的計數。
B.第二次及以后上電需要等待RTC與RTC_APB時鐘同步。
C.使能RTC秒中斷,我們用于測試并打印RTC日歷數據。如果你的應用是直接讀取RTC日歷,不是想我們實例那樣中斷打印數據,則可以不開啟該中斷。
4. RTC讀寫描述
該結構體位于rtc.h文件下面;
這要就是用于讀寫用(這樣直接傳遞一個參數就行了,不用傳遞“一串”整形變量)
該函數位于rtc.c文件下面;
RTC日歷寫(設置)函數,這個函數是筆者整理并經過項目驗證的,可直接調用。
注意:
參數不能越界(超出范圍),超出范圍會返回錯誤。
該函數位于rtc.c文件下面;
RTC日歷讀(獲取)函數,這個函數是筆者整理并經過項目驗證的,可直接調用。
注意:
需要配置RTC并初始化RTC值才會讀出正確的日歷值。
Ⅴ、解答問題
上面筆者留下的問題或許對于初學者不是很關心,但對于在工作中,需要實際項目的開發的人應該比較有幫助。
1、為什么不建議使用LSI作為時鐘源來設計日歷?
原因在于LSI不是屬于后備區域,而RTC日歷部分是屬于后備局域(見上圖),也就是說系統一旦掉電,RTC時鐘就不能工作了。
2、兩個實例工程之間的差別? 將實例中使用“LSE”時鐘改為“LSI”時鐘,其他地方不該可以嗎?
這個地方和第一個問題有關聯,修改后的工程程序會死在等待時鐘同步的地方。
-
LSI
+關注
關注
0文章
274瀏覽量
28077 -
STM32F10x
+關注
關注
1文章
81瀏覽量
20730 -
RTC
+關注
關注
2文章
544瀏覽量
67039
發布評論請先 登錄
相關推薦
評論