esp32 rtc 时钟设置不对_「STM32」实时时钟(RTC)实验
實時時鐘的特征和原理
RTCCLK:時鐘來源
RTC的時鐘有哪些來源呢?
如圖,有3個渠道
- 來自于外部的LSE也就是外部的晶振
- 來自于HSE的128分頻
- 來自于LSI
一般情況下我們都是采用外部晶振來提供時鐘的,因為它還是很精確的。
BKP備份寄存器
RTC相關(guān)寄存器
具體設(shè)置可查看datasheet。
配置RTC寄存器
讀RTC寄存器
RTC相關(guān)庫函數(shù)
RTC一般配置步驟
源碼
建議使用pc端瀏覽源碼
rtc.h
#ifndef __RTC_H
#define __RTC_H
//時間結(jié)構(gòu)體
typedef struct
{
vu8 hour;
vu8 min;
vu8 sec;
//公歷日月年周
vu16 w_year;
vu8 w_month;
vu8 w_date;
vu8 week;
}_calendar_obj;
extern _calendar_obj calendar;//日歷結(jié)構(gòu)體
extern u8 const mon_table[12];//月份日期數(shù)據(jù)表
void Disp_Time(u8 x,u8 y,u8 size);//在制定位置開始顯示時間
void Disp_Week(u8 x,u8 y,u8 size,u8 lang);//在指定位置顯示星期
u8 RTC_Init(void); //初始化RTC,返回0,失敗;1,成功;
u8 Is_Leap_Year(u16 year);//平年,閏年判斷
u8 RTC_Alarm_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);
u8 RTC_Get(void); //更新時間
u8 RTC_Get_Week(u16 year,u8 month,u8 day);
u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);//設(shè)置時間
#endif
rtc.c
#include "delay.h"
#include "usart.h"
#include "rtc.h"
_calendar_obj calendar;//時鐘結(jié)構(gòu)體
static void RTC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;//RTC全局中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//先占優(yōu)先級1位,從優(yōu)先級3位
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//先占優(yōu)先級0位,從優(yōu)先級4位
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能該通道中斷
NVIC_Init(&NVIC_InitStructure);//根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器
}
//實時時鐘配置
//初始化RTC時鐘,同時檢測時鐘是否工作正常
//BKP->DR1用于保存是否第一次配置的設(shè)置
//返回0:正常
//其他:錯誤代碼
u8 RTC_Init(void)
{
//檢查是不是第一次配置時鐘
u8 temp=0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//使能PWR和BKP外設(shè)時鐘
PWR_BackupAccessCmd(ENABLE);//使能后備寄存器訪問
if (BKP_ReadBackupRegister(BKP_DR1) != 0x5050)//從指定的后備寄存器中讀出數(shù)據(jù):讀出了與寫入的指定數(shù)據(jù)不相乎
{
BKP_DeInit();//復(fù)位備份區(qū)域
RCC_LSEConfig(RCC_LSE_ON);//設(shè)置外部低速晶振(LSE),使用外設(shè)低速晶振
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET&&temp<250)//檢查指定的RCC標(biāo)志位設(shè)置與否,等待低速晶振就緒
{
temp++;
delay_ms(10);
}
if(temp>=250)return 1;//初始化時鐘失敗,晶振有問題
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//設(shè)置RTC時鐘(RTCCLK),選擇LSE作為RTC時鐘
RCC_RTCCLKCmd(ENABLE);//使能RTC時鐘
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
RTC_WaitForSynchro();//等待RTC寄存器同步
RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能RTC秒中斷
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
RTC_EnterConfigMode();/// 允許配置
RTC_SetPrescaler(32767); //設(shè)置RTC預(yù)分頻的值
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
RTC_Set(2015,1,14,17,42,55); //設(shè)置時間
RTC_ExitConfigMode(); //退出配置模式
BKP_WriteBackupRegister(BKP_DR1, 0X5050);//向指定的后備寄存器中寫入用戶程序數(shù)據(jù)
}
else//系統(tǒng)繼續(xù)計時
{
RTC_WaitForSynchro();//等待最近一次對RTC寄存器的寫操作完成
RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能RTC秒中斷
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
}
RTC_NVIC_Config();//RCT中斷分組設(shè)置
RTC_Get();//更新時間
return 0; //ok
}
//RTC時鐘中斷
//每秒觸發(fā)一次
//extern u16 tcnt;
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒鐘中斷
{
RTC_Get();//更新時間
}
if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)//鬧鐘中斷
{
RTC_ClearITPendingBit(RTC_IT_ALR);//清鬧鐘中斷
RTC_Get();//更新時間
printf("Alarm Time:%d-%d-%d %d:%d:%d
總結(jié)
以上是生活随笔為你收集整理的esp32 rtc 时钟设置不对_「STM32」实时时钟(RTC)实验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么判断日出时间早晚_早晚都要擦精华液?
- 下一篇: 语言课程设计超市售货_自闭症儿童家庭干预