|
STM32 RTC時(shí)鐘帶中文注釋
#include "stm32f10x.h" // Device header
#include <time.h>
uint16_t MyRTC_Time[] = {2024, 2, 26, 15, 18, 00}; //定義全局的時(shí)間數(shù)組,數(shù)組內(nèi)容分別為年、月、日、時(shí)、分、秒
void MyRTC_SetTime(void); //函數(shù)聲明
/**
* 函 數(shù):RTC初始化
* 參 數(shù):無(wú)
* 返 回 值:無(wú)
*/
void MyRTC_Init(void)
{
/*開(kāi)啟時(shí)鐘*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //開(kāi)啟PWR的時(shí)鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE); //開(kāi)啟BKP的時(shí)鐘
/*備份寄存器訪(fǎng)問(wèn)使能*/
PWR_BackupAccessCmd(ENABLE); //使用PWR開(kāi)啟對(duì)備份寄存器的訪(fǎng)問(wèn)
if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) //通過(guò)寫(xiě)入備份寄存器的標(biāo)志位,判斷RTC是否是第一次配置
//if成立則執(zhí)行第一次的RTC配置
{
RCC_LSEConfig(RCC_LSE_ON); //開(kāi)啟LSE時(shí)鐘
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET); //等待LSE準(zhǔn)備就緒
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //選擇RTCCLK來(lái)源為L(zhǎng)SE
RCC_RTCCLKCmd(ENABLE); //RTCCLK使能
RTC_WaitForSynchro(); //等待同步
RTC_WaitForLastTask(); //等待上一次操作完成
RTC_SetPrescaler(32768 - 1); //設(shè)置RTC預(yù)分頻器,預(yù)分頻后的計(jì)數(shù)頻率為1Hz
RTC_WaitForLastTask(); //等待上一次操作完成
MyRTC_SetTime(); //設(shè)置時(shí)間,調(diào)用此函數(shù),全局?jǐn)?shù)組里時(shí)間值刷新到RTC硬件電路
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); //在備份寄存器寫(xiě)入自己規(guī)定的標(biāo)志位,用于判斷RTC是不是第一次執(zhí)行配置
}
else //RTC不是第一次配置
{
RTC_WaitForSynchro(); //等待同步
RTC_WaitForLastTask(); //等待上一次操作完成
}
}
//如果LSE無(wú)法起振導(dǎo)致程序卡死在初始化函數(shù)中
//可將初始化函數(shù)替換為下述代碼,使用LSI當(dāng)作RTCCLK
//LSI無(wú)法由備用電源供電,故主電源掉電時(shí),RTC走時(shí)會(huì)暫停
/*
void MyRTC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
{
RCC_LSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) != SET);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_SetPrescaler(40000 - 1);
RTC_WaitForLastTask();
MyRTC_SetTime();
BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
}
else
{
RCC_LSICmd(ENABLE); //即使不是第一次配置,也需要再次開(kāi)啟LSI時(shí)鐘
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) != SET);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
}
}*/
/**
* 函 數(shù):RTC設(shè)置時(shí)間
* 參 數(shù):無(wú)
* 返 回 值:無(wú)
* 說(shuō) 明:調(diào)用此函數(shù)后,全局?jǐn)?shù)組里時(shí)間值將刷新到RTC硬件電路
*/
void MyRTC_SetTime(void)
{
time_t time_cnt; //定義秒計(jì)數(shù)器數(shù)據(jù)類(lèi)型
struct tm time_date; //定義日期時(shí)間數(shù)據(jù)類(lèi)型
time_date.tm_year = MyRTC_Time[0] - 1900; //將數(shù)組的時(shí)間賦值給日期時(shí)間結(jié)構(gòu)體
time_date.tm_mon = MyRTC_Time[1] - 1;
time_date.tm_mday = MyRTC_Time[2];
time_date.tm_hour = MyRTC_Time[3];
time_date.tm_min = MyRTC_Time[4];
time_date.tm_sec = MyRTC_Time[5];
time_cnt = mktime(&time_date) - 8 * 60 * 60; //調(diào)用mktime函數(shù),將日期時(shí)間轉(zhuǎn)換為秒計(jì)數(shù)器格式
//- 8 * 60 * 60為東八區(qū)的時(shí)區(qū)調(diào)整
RTC_SetCounter(time_cnt); //將秒計(jì)數(shù)器寫(xiě)入到RTC的CNT中
RTC_WaitForLastTask(); //等待上一次操作完成
}
/**
* 函 數(shù):RTC讀取時(shí)間
* 參 數(shù):無(wú)
* 返 回 值:無(wú)
* 說(shuō) 明:調(diào)用此函數(shù)后,RTC硬件電路里時(shí)間值將刷新到全局?jǐn)?shù)組
*/
void MyRTC_ReadTime(void)
{
time_t time_cnt; //定義秒計(jì)數(shù)器數(shù)據(jù)類(lèi)型
struct tm time_date; //定義日期時(shí)間數(shù)據(jù)類(lèi)型
time_cnt = RTC_GetCounter() + 8 * 60 * 60; //讀取RTC的CNT,獲取當(dāng)前的秒計(jì)數(shù)器
//+ 8 * 60 * 60為東八區(qū)的時(shí)區(qū)調(diào)整
time_date = *localtime(&time_cnt); //使用localtime函數(shù),將秒計(jì)數(shù)器轉(zhuǎn)換為日期時(shí)間格式
MyRTC_Time[0] = time_date.tm_year + 1900; //將日期時(shí)間結(jié)構(gòu)體賦值給數(shù)組的時(shí)間
MyRTC_Time[1] = time_date.tm_mon + 1;
MyRTC_Time[2] = time_date.tm_mday;
MyRTC_Time[3] = time_date.tm_hour;
MyRTC_Time[4] = time_date.tm_min;
MyRTC_Time[5] = time_date.tm_sec;
}
#include "MyRTC.h"
int main(void)
{
/*模塊初始化*/
OLED_Init(); //OLED初始化
MyRTC_Init(); //RTC初始化
// MyRTC_SetTime();//設(shè)置時(shí)間
/*顯示靜態(tài)字符串*/
OLED_ShowString(1, 1, "Date:XXXX-XX-XX");
OLED_ShowString(2, 1, "Time:XX:XX:XX");
OLED_ShowString(3, 1, "CNT :");
OLED_ShowString(4, 1, "DIV :");
while (1)
{
MyRTC_ReadTime(); //RTC讀取時(shí)間,最新的時(shí)間存儲(chǔ)到MyRTC_Time數(shù)組中
OLED_ShowNum(1, 6, MyRTC_Time[0], 4); //顯示MyRTC_Time數(shù)組中的時(shí)間值,年
OLED_ShowNum(1, 11, MyRTC_Time[1], 2); //月
OLED_ShowNum(1, 14, MyRTC_Time[2], 2); //日
OLED_ShowNum(2, 6, MyRTC_Time[3], 2); //時(shí)
OLED_ShowNum(2, 9, MyRTC_Time[4], 2); //分
OLED_ShowNum(2, 12, MyRTC_Time[5], 2); //秒
OLED_ShowNum(3, 6, RTC_GetCounter(), 10); //顯示32位的秒計(jì)數(shù)器
OLED_ShowNum(4, 6, RTC_GetDivider(), 10); //顯示余數(shù)寄存器
}
}
原理圖: 無(wú)
仿真: 無(wú)
代碼:
12-2 實(shí)時(shí)時(shí)鐘.7z
(179.82 KB, 下載次數(shù): 23)
2024-2-29 02:51 上傳
點(diǎn)擊文件名下載附件
RTC時(shí)鐘 下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|