一. rtc.c,rtc.h,秒中断及闹钟中断均采用金沙滩工作室的源文件;
二. 在主函数中对rtc进行初始化:RtcInit();? 并且,在初始化后延时3秒再使用:delay_ms(3000);
三. 需要使用RTC时间时,先调用下面代码:
?? ??? ? if (RTC_AlarmFlag == 1) ?? ??? ? { ?? ??? ??? ??? ?RTC_AlarmFlag = 0;? ?// RTC闹钟中断变量; ?? ??? ? }?? ?
? ? ? ? 然后按照客户协议帧格式,或者接收设备帧格式进行接收/转换RTC时钟数据;
? ? ? ?例如:我需要在一上电给LCD发送其要求的RTC帧格式的数据;那么我还需要增加:
? ? ? ? ? ? ? get_rtc_hex();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //获取符合LCD要求的RTC时间帧格式;
? ? ? ? ? ? ? LCD_SendMessage(rtc_hex,13);? ? ? ? // 给LCD发送RTC时间;
其中:get_rtc_hex(); 函数和rtc_hex数据定义如下:
void get_rtc_hex(void) { ?? ? ? ? week = GetWeek2(RTC_Time.yyyy, RTC_Time.MM, RTC_Time.dd); ?? ? ?? ??? ??? ? //rtc_hex[2] = RTC_Time.ss; ?? ??? ??? ? rtc_hex[2] = (RTC_Time.ss /10 *16) + (RTC_Time.ss %10);? ?? ??? ??? ? rtc_hex[3] = (RTC_Time.mm /10 *16) + (RTC_Time.mm %10);? ?? ??? ??? ? rtc_hex[4] = (RTC_Time.hh /10 *16) + (RTC_Time.hh %10);? ?? ??? ??? ? rtc_hex[5] = (RTC_Time.dd /10 *16) + (RTC_Time.dd %10);? ?? ??? ??? ? rtc_hex[6] = week; ?? ??? ??? ? rtc_hex[7] = (RTC_Time.MM /10 *16) + (RTC_Time.MM %10);? ?? ??? ??? ? rtc_hex[8] = (RTC_Time.yyyy %100/10 *16) + (RTC_Time.yyyy %100 %10);? }
unsigned char rtc_hex[13] = {0XEE,0x81,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFC,0xFF,0xFF};
四. 如果只需要修改RTC一次, 那么需要修改void RtcConfig(void)函数中的变量的值:
? ? RTC_SetTime.yyyy = 2021; ? ? ? ? ? ? ? ? ? ? ? ? ? ? //éè?? ?ê ? ? RTC_SetTime.MM = 9; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//éè?? ?? ? ? RTC_SetTime.dd = 4; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//éè?? è? ? ? RTC_SetTime.hh = 8; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //éè?? ê± ? ? RTC_SetTime.mm = 30; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //éè?? ·? ? ? RTC_SetTime.ss = 0; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //éè?? ??
? ? 并且将void RtcInit(void)函数中的0xAA修改为新值:0xAB
void RtcInit(void) { ? ? RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // ? ? PWR_BackupAccessCmd(ENABLE); ? ? ? ? ? ? ? ?// ? ? if(BKP_ReadBackupRegister(BKP_DR1) != 0xAB) // ? ? { ? ? ? ? RtcConfig(); ? ? ? ? ? ? ? ? ? ? ? ? ? ?// ? ? ? ? BKP_WriteBackupRegister(BKP_DR1, 0xAB); // ? ? } ? ? else ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// ? ? { ? ? ? ? RTC_WaitForSynchro(); ? ? ? ? ? ? ? ? ? // ? ? ? ? RTC_ITConfig(RTC_IT_SEC, ENABLE); ? ? ? // ? ? ? ? RTC_WaitForLastTask(); ? ? ? ? ? ? ? ? ?// ? ? } ? ? NVIC_RtcInit(); }
五. 如果需要二次配置RTC,比如设备正常工作时通过人机界面修改时间;
那么就需要将void RtcInit(void)函数进行4步修改:
a. 新建一个void RtcModify_lcdcontrol(void)函数;函数主体为:void RtcInit(void)函数和? RtcConfig();函数的合并;(原函数保留)
b. 将新函数中的?if(BKP_ReadBackupRegister(BKP_DR1) != 0xAB)语句中的“!=”修改为“==”;
c. 定义一个新的结构体变量rtc_modify;语句为:DateTime rtc_modify; 并将年月日时分秒更换为黑体部分;
d. 增加一行语句PWR_BackupAccessCmd(DISABLE); ? ?
void RtcModify_lcdcontrol(void) { ?? ??? ?DateTime RTC_SetTime; ?? ??? ?RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); // ?? ??? ?PWR_BackupAccessCmd(ENABLE); ? ? ? ? ? ? ? ?// ? ? if(BKP_ReadBackupRegister(BKP_DR1) == 0xAB) // ? ? {
?? ??? ??? ??? ?//DateTime RTC_SetTime2;
?? ??? ??? ??? ?BKP_DeInit(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// ?? ??? ??? ??? ?RCC_LSEConfig(RCC_LSE_ON); ? ? ? ? ? ? ? ? ? ? ? ? ? // ?? ??? ??? ??? ?while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); // ?? ??? ??? ??? ?RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); ? ? ? ? ? ? ?// ?? ??? ??? ??? ?RCC_RTCCLKCmd(ENABLE); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ?? ??? ??? ??? ?RTC_WaitForSynchro(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// ?? ??? ??? ??? ?RTC_WaitForLastTask(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ?? ??? ??? ??? ?RTC_EnterConfigMode(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ?? ??? ??? ??? ?RTC_SetPrescaler(32767); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ?? ??? ??? ??? ?RTC_WaitForLastTask(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ?? ??? ??? ??? ?RTC_ITConfig(RTC_IT_SEC, ENABLE); ? ? ? ? ? ? ? ? ? ?// ?? ??? ??? ??? ?RTC_WaitForLastTask(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ?? ??? ??? ??? ?RTC_SetTime.yyyy = rtc_modify.yyyy; //? ? ? ? ? ? ? ? ? ? ? ? ? ? / ?? ??? ??? ??? ?RTC_SetTime.MM = rtc_modify.MM; //? ?? ??? ??? ??? ?RTC_SetTime.dd = rtc_modify.dd; //? ? ? ? ? ? ? ? ? ? ? ?? ?? ??? ??? ??? ?RTC_SetTime.hh = rtc_modify.hh; // ?? ??? ??? ??? ?RTC_SetTime.mm = rtc_modify.mm; // ?? ??? ??? ??? ?RTC_SetTime.ss = rtc_modify.ss; // ?? ??? ??? ??? ?SetRtcTime(&RTC_SetTime); ? ? ? ? ? ? ? ? ? ? ? ? ? ?// ?? ??? ??? ??? ?RTC_WaitForLastTask(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ?? ??? ??? ??? ?RTC_ExitConfigMode(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// ?? ??? ??? ??? ?RTC_WaitForLastTask(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //
? ? ?? ? ? ? ? BKP_WriteBackupRegister(BKP_DR1, 0xAB); // ?? ??? ??? ??? ?PWR_BackupAccessCmd(DISABLE); ? ? ? ? ? ? ? ?// ? ? } ? ? else ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// ? ? { ? ? ? ? RTC_WaitForSynchro(); ? ? ? ? ? ? ? ? ? // ? ? ? ? RTC_ITConfig(RTC_IT_SEC, ENABLE); ? ? ? // ? ? ? ? RTC_WaitForLastTask(); ? ? ? ? ? ? ? ? ?// ? ? } ?? ?NVIC_RtcInit(); }
e. 并且,再修改完时钟配置后,需要延时1s, 再进行读取;例如:
? ? ? ? ? ? ?RtcModify_lcdcontrol(); // ? ? ? ? ? ? ?delay_ms(1000); // 获取RTC函数在秒中断中调用,至少进入一次秒中断,获取的时间才是新的设置时间。(个人目前只能这样理解) ?? ??? ??? ???if (RTC_AlarmFlag == 1) ?? ??? ??? ???{? ?? ??? ??? ??? ??? ????RTC_AlarmFlag = 0; ?? ??? ??? ????} ? ?? ??? ??? ???get_rtc_hex(); LCD_SendMessage(rtc_hex,13); //
|