關(guān)于RTC
1、RTC介紹
RTC(Real Time Clock):實(shí)時(shí)時(shí)鐘,是指可以像時(shí)鐘一樣輸出實(shí)際時(shí)間的電子設(shè)備,一般會(huì)是集成電路,因此也稱為時(shí)鐘芯片。總之,RTC只是個(gè)能靠電池維持運(yùn)行的32位定時(shí)器,并不像實(shí)時(shí)時(shí)鐘芯片,讀出來(lái)就是年月日。
RTC就只一個(gè)定時(shí)器而已,掉電之后所有信息都會(huì)丟失,因此我們需要找一個(gè)地方來(lái)存儲(chǔ)這些信息,于是就找到了備份寄存器(BKP)。因?yàn)樗綦姾笕匀豢梢酝ㄟ^(guò)紐扣電池供電,繼續(xù)工作,所以能時(shí)刻保存這些數(shù)據(jù)。
stm32F103使用外部晶體的32.768kHz的振蕩器,產(chǎn)生一個(gè)1秒長(zhǎng)的時(shí)間基準(zhǔn)。
RTC 模塊和時(shí)鐘配置系統(tǒng)(RCC_BDCR 寄存器)是在后備區(qū)域,即在系統(tǒng)復(fù)位或從待機(jī)模式喚醒后 RTC 的設(shè)置和時(shí)間維持不變。但是在系統(tǒng)復(fù)位后,會(huì)自動(dòng)禁止訪問(wèn)后備寄存器和 RTC,以防止對(duì)后備區(qū)域(BKP)的意外寫操作。所以在要設(shè)置時(shí)間之前, 先要取消備份區(qū)域(BKP)寫保護(hù)。
2、工作過(guò)程
RTC只是一個(gè)時(shí)鐘,但與RTC相連的有兩個(gè)系統(tǒng)時(shí)鐘:一個(gè)是APB1接口的PCLK1,另一個(gè)是RTC時(shí)鐘。這樣,RTC功能也就分為兩個(gè)部分:第一部分,APB1接口部分,與APB1總線相連,MCU也就是通過(guò)這條總線對(duì)其進(jìn)行讀寫操作。另一部分,RTC核心,其整個(gè)核心部分位于后備區(qū)域,所以只要有VBAT引腳供電,就能一直工作,由一系列可編程計(jì)數(shù)器組成,這部分又再細(xì)分為兩個(gè)組件:20位的預(yù)分頻模塊與32位可編程計(jì)數(shù)器。預(yù)分頻模塊用來(lái)產(chǎn)生最長(zhǎng)為1秒的RTC時(shí)間基準(zhǔn),而32位的可編程的計(jì)數(shù)器可被初始化為當(dāng)前的系統(tǒng)時(shí)間。
RTC_PRL:預(yù)分頻裝載寄存器
RTC_DIV:預(yù)分頻器余數(shù)寄存器
RTC_CNT:計(jì)數(shù)器寄存器
RTC_ALR:鬧鐘寄存器
首先,在初始化時(shí)候,DIV和PRL都會(huì)裝載同樣的數(shù)。RTCCLK頻率為32.768kHz,來(lái)驅(qū)動(dòng)DIV工作,DIV為自減寄存器。當(dāng)DIV減少到0時(shí),會(huì)產(chǎn)生一個(gè)TR_CLK信號(hào),該信號(hào)會(huì)觸發(fā)三件事情:①將PRL的數(shù)重裝在到DIV中;②觸發(fā)CNT計(jì)數(shù)器+1;③觸發(fā)SECF,進(jìn)而產(chǎn)生秒中斷。我們會(huì)設(shè)置一個(gè)合理的預(yù)分頻數(shù),使得TR_CLK觸發(fā)時(shí)間剛好是1s。ALR中存儲(chǔ)的是我們?cè)O(shè)置的鬧鐘秒數(shù),當(dāng)CNT和ALR中的數(shù)據(jù)相同時(shí),就會(huì)觸發(fā)鬧鐘中斷或者鬧鐘喚醒。(關(guān)于CNT和ALR中存放的數(shù)據(jù),為時(shí)間戳。)
1s的時(shí)間如何計(jì)算?
我們的RTC_CLK為32.768kHz,所以只要PRL中寫入32767即可,即為2的15次方。
我們只需要在PRL的低16位寄存器中寫入0x7FFF即可。
DIV寄存器存在的意義?
從上述能知道TR_CLK輸出必須為1s。那么我們想要的到0.15s,應(yīng)該怎么實(shí)現(xiàn)呢?
道理很簡(jiǎn)單,因?yàn)镈IV是自減的,并且從32768一直減少到0,所需要的時(shí)間為1s。所以減少一個(gè)數(shù),所用的時(shí)間為1/32768s,那么減少多少個(gè)數(shù),就計(jì)時(shí)了0.15s呢?
1/32768s * n = 0.15
n = 0.15 * 32768
又因?yàn)镈IV寄存器是可讀的,所以我們就能實(shí)現(xiàn)0.15s的計(jì)時(shí)。
從框圖中,還可以看到,只有秒中斷和鬧鐘中斷能觸發(fā)中斷,溢出是沒(méi)有中斷的。
STM32CubeMAX界面
讀取STM32F103C8T6 內(nèi)部的時(shí)鐘(年月日時(shí)分秒),日歷(星期x),1秒周期,通過(guò)串口輸出到PC上位機(jī)
設(shè)置RCC
設(shè)置RTC
設(shè)置RTC參數(shù)
設(shè)置時(shí)鐘樹(shù)
創(chuàng)建工程
keil界面
在main.c文件中重寫fputc函數(shù),完成printf函數(shù)的重定向
//添加頭文件#include "stdio.h"
int fputc(int ch,FILE *f){
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,2);
return ch;
}
在main.c中定義時(shí)間和日期的結(jié)構(gòu)體用來(lái)獲取時(shí)間和日期
RTC_DateTypeDef GetData; //獲取日期結(jié)構(gòu)體
RTC_TimeTypeDef GetTime; //獲取時(shí)間結(jié)構(gòu)體
在main函數(shù)的while循環(huán)中添加以下代碼文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-827942.html
/* Get the RTC current Time */
HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
/* Get the RTC current Date */
HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
/* Display date Format : yy/mm/dd */
printf("%02d/%02d/%02d\r\n",2000 + GetData.Year, GetData.Month, GetData.Date);
/* Display time Format : hh:mm:ss */
printf("%02d:%02d:%02d\r\n",GetTime.Hours, GetTime.Minutes, GetTime.Seconds);
printf("\r\n");
HAL_Delay(1000);
編譯運(yùn)行結(jié)果如下:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-827942.html
到了這里,關(guān)于STM32日歷讀取,設(shè)置和輸出的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!