一、RTC振荡器
PY32F003F18实时时钟的振荡器是内部RC振荡器,频率为32.768KHz。它也可以使用HSE时钟,不建议使用。HAL库提到LSE振荡器,但PY32F003F18实际上没有这个振荡器。
缺点:CPU掉电后,需要重新配置RTC,这个确实不太友好,有点像是鸡肋,在要求不严格的场合,凑合使用吧。
RTC时钟框图如下:

二、RTC的HAL库有一个不是很严重的bug
PY32F003F18的HAL库润年函数中有一个BUG,不是很严重,因为2400年是一个闰年,它把年定义为字节型变量,是没有办法分辨出是不是闰年。
闰年的计算方法:年数能被4整除,但不能被100年整除,为闰年;若年数能400年整除,也为闰年。
HAL库确实不大好,它喜欢用全局变量来实现其功能,让人受不了。我改了,让它适合自己需要的。HAL处的好处,就是我们可以从中抠出自己需要的部分,修修改改,就可以了,比HAL库的灵活多了。时刻不忘黑它一把,因为人云亦云的人太多了。
三、非完全HAL库测试程序
如果你觉得HAL库,就用HAL中的程序,也是可以的。
- #include "RTC.h"
- #include "LED.h"
- #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
-
- uint8_t Century;//世纪,21世纪用20表示
- RTC_DateTypeDef RTC_DateStructureure;//用来保存读到的"年月日"
- RTC_TimeTypeDef RTC_TimeStructureure;//用来保存读到的"时分秒"
- RTC_AlarmTypeDef RTC_AlarmStructureure;
-
- void RTC_Init(void);
- void RTC_Display(void);
-
- //函数功能:读"RTC计数寄存器"
- uint32_t Read_RTC_Time_Counter(void)
- {
- uint16_t high1 = 0U, high2 = 0U, low = 0U;
- uint32_t timecounter = 0U;
-
- high1 = READ_REG(RTC->CNTH & RTC_CNTH_RTC_CNT);//读"RTC计数寄存器高位RTC_CNTH"
- low = READ_REG(RTC->CNTL & RTC_CNTL_RTC_CNT);//读"RTC计数寄存器低位RTC_CNTL"
- high2 = READ_REG(RTC->CNTH & RTC_CNTH_RTC_CNT);//读"RTC计数寄存器高位RTC_CNTH"
-
- if (high1 != high2)
- {//读"RTC计数寄存器低位RTC_CNTL"时,发现"RTC计数寄存器高位RTC_CNTH"中的数据发生改变了
- //In this case the counter roll over during reading of CNTL and CNTH registers,
- //read again CNTL register then return the counter value
- timecounter = (((uint32_t) high2 << 16U) | READ_REG(RTC->CNTL & RTC_CNTL_RTC_CNT));
- }
- else
- {
- //No counter roll over during reading of CNTL and CNTH registers,
- //counter value is equal to first value of CNTL and CNTH
- timecounter = (((uint32_t) high1 << 16U) | low);
- }
-
- return timecounter;
- }
-
- //函数功能:
- //等待RTC写操作结束
- //返回0,表示退出RTC配置模式,开始更新RTC寄存器
- HAL_StatusTypeDef Enter_RTC_Init_Mode(void)
- {
- uint32_t tickstart = 0U;
-
- tickstart = HAL_GetTick();
- /* Wait till RTC is in INIT state and if Time out is reached exit */
- while ( (RTC->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET )
- {//读"RTC控制寄存器RTC_CRL"中的RTOFF,若RTOFF=0,则上一次对RTC寄存器的写操作仍在进行
- if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
- {//RTC_TIMEOUT_VALUE=2000,最大等待时间为2000ms
- return HAL_TIMEOUT;
- }
- }
-
- _HAL_RTC_WRITEPROTECTION_DISABLE(RTC);
- //将"RTC控制寄存器RTC_CRL"中的CNF=0,退出配置模式,开始更新RTC寄存器
- //Disable the write protection for RTC registers
-
- return HAL_OK;
- }
-
- //函数功能:
- //等待RTC写操作结束
- //返回0,表示RTC写操作结束
- HAL_StatusTypeDef Exit_RTC_Init_Mode(void)
- {
- uint32_t tickstart = 0U;
-
- _HAL_RTC_WRITEPROTECTION_ENABLE(RTC);
- //将"RTC控制寄存器RTC_CRL"中的CNF=1,进入RTC配置模式
-
- tickstart = HAL_GetTick();
- while ((RTC->CRL & RTC_CRL_RTOFF) == RTC_CRL_RTOFF)
- {//读"RTC控制寄存器RTC_CRL"中的RTOFF,若RTOFF=1,则上一次对RTC寄存器的写操作已经完成
- if ((HAL_GetTick() - tickstart) > RTC_RTOFF_RESET_TIMEOUT_VALUE)
- {//RTC_RTOFF_RESET_TIMEOUT_VALUE=4,最大等待时间为4ms
- break;
- }
- }
-
- tickstart = HAL_GetTick();
- while ((RTC->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
- {//读"RTC控制寄存器RTC_CRL"中的RTOFF,若RTOFF=0,则上一次对RTC寄存器的写操作仍在进行
- if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
- {//RTC_TIMEOUT_VALUE=2000,最大等待时间为2000ms
- return HAL_TIMEOUT;
- }
- }
-
- return HAL_OK;
- }
-
- //函数功能:将TimeCounter写入"RTC计数寄存器"
- HAL_StatusTypeDef Write_RTC_Time_Counter( uint32_t TimeCounter )
- {
- HAL_StatusTypeDef status = HAL_OK;
-
- if (Enter_RTC_Init_Mode() != HAL_OK)
- {//等待RTC写操作结束
- //返回0,表示退出RTC配置模式,开始更新RTC寄存器
- status = HAL_ERROR;
- }
- else
- {
- WRITE_REG(RTC->CNTH, (TimeCounter >> 16U));
- //写"RTC计数寄存器高位RTC_CNTH"
- //Set RTC COUNTER MSB word
- WRITE_REG(RTC->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
- //写"RTC计数寄存器低位RTC_CNTL"
- //Set RTC COUNTER LSB word
- if (Exit_RTC_Init_Mode() != HAL_OK)
- {//等待RTC写操作结束
- status = HAL_ERROR;
- }
- }
-
- return status;
- }
-
- //函数功能:读"RTC闹钟寄存器"
- uint32_t Read_RTC_Alarm_Counter(void)
- {
- uint16_t high1 = 0U, low = 0U;
-
- high1 = READ_REG(RTC->ALRH & RTC_CNTH_RTC_CNT);
- //读"RTC闹钟寄存器高位RTC_ALRH"
- low = READ_REG(RTC->ALRL & RTC_CNTL_RTC_CNT);
- //读"RTC闹钟寄存器低位RTC_ALRL"
-
- return (((uint32_t) high1 << 16U) | low);
- }
-
- //函数功能:将AlarmCounter写入"RTC闹钟寄存器"
- HAL_StatusTypeDef Write_RTC_Alarm_Counter( uint32_t AlarmCounter)
- {
- HAL_StatusTypeDef status = HAL_OK;
-
- /* Set Initialization mode */
- if (Enter_RTC_Init_Mode() != HAL_OK)
- {//等待RTC写操作结束
- //返回0,表示退出RTC配置模式,开始更新RTC寄存器
- status = HAL_ERROR;
- }
- else
- {
- WRITE_REG(RTC->ALRH, (AlarmCounter >> 16U));
- //写"RTC闹钟寄存器高位RTC_ALRH",Set RTC COUNTER MSB word
- WRITE_REG(RTC->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR));
- //写"RTC闹钟寄存器低位RTC_ALRL",Set RTC COUNTER LSB word
-
- /* Wait for synchro */
- if (Exit_RTC_Init_Mode() != HAL_OK)
- {//等待RTC写操作结束
- status = HAL_ERROR;
- }
- }
-
- return status;
- }
-
- //函数功能:返回0表示闰年
- uint8_t Is_LeapYear(uint16_t nYear)
- {
- uint16_t y;
-
- y=Century;//2023年9月26日
- y=y*100;//2023年9月26日
- nYear=y+nYear;//2023年9月26日
-
- if ((nYear % 4U) != 0U)
- {
- return 0U;
- }
-
- if ((nYear % 100U) != 0U)
- {
- return 1U;
- }
-
- if ((nYear % 400U) == 0U)
- {
- return 1U;
- }
- else
- {
- return 0U;
- }
- }
-
- //函数功能;读取星期几的值
- uint8_t Read_RTC_WeekDay(uint32_t nYear, uint8_t nMonth, uint8_t nDay)
- {
- uint32_t year = 0U, weekday = 0U;
-
- year = 2000U + nYear;
-
- if (nMonth < 3U)
- {
- /*D = { [(23 x month)/9] + day + 4 + year + [(year-1)/4] - [(year-1)/100] + [(year-1)/400] } mod 7*/
- weekday = (((23U * nMonth) / 9U) + nDay + 4U + year + ((year - 1U) / 4U) - ((year - 1U) / 100U) + ((year - 1U) / 400U)) % 7U;
- }
- else
- {
- /*D = { [(23 x month)/9] + day + 4 + year + [year/4] - [year/100] + [year/400] - 2 } mod 7*/
- weekday = (((23U * nMonth) / 9U) + nDay + 4U + year + (year / 4U) - (year / 100U) + (year / 400U) - 2U) % 7U;
- }
-
- return (uint8_t)weekday;
- }
-
- void Update_RTC_Date(RTC_DateTypeDef *update_RTCDate, uint32_t DayElapsed)
- {
- uint32_t year = 0U, month = 0U, day = 0U;
- uint32_t loop = 0U;
-
- /* Get the current year*/
- year = update_RTCDate->Year;
-
- /* Get the current month and day */
- month = update_RTCDate->Month;
- day = update_RTCDate->Date;
-
- for (loop = 0U; loop < DayElapsed; loop++)
- {
- if ((month == 1U) || (month == 3U) || (month == 5U) || (month == 7U) || \
- (month == 8U) || (month == 10U) || (month == 12U))
- {
- if (day < 31U)
- {
- day++;
- }
- /* Date structure member: day = 31 */
- else
- {
- if (month != 12U)
- {
- month++;
- day = 1U;
- }
- /* Date structure member: day = 31 & month =12 */
- else
- {
- month = 1U;
- day = 1U;
- year++;
- }
- }
- }
- else if ((month == 4U) || (month == 6U) || (month == 9U) || (month == 11U))
- {
- if (day < 30U)
- {
- day++;
- }
- /* Date structure member: day = 30 */
- else
- {
- month++;
- day = 1U;
- }
- }
- else if (month == 2U)
- {
- if (day < 28U)
- {
- day++;
- }
- else if (day == 28U)
- {
- if (Is_LeapYear(year))//不闰年
- {//返回0表示闰年
- day++;
- }
- else //闰年
- {
- month++;
- day = 1U;
- }
- }
- else if (day == 29U)
- {
- month++;
- day = 1U;
- }
- }
- }
-
- if(year>=100)//2023年9月26日
- {
- Century++;
- year=year-100;
- }
-
- /* Update year */
- update_RTCDate->Year = year;
-
- /* Update day and month */
- update_RTCDate->Month = month;
- update_RTCDate->Date = day;
-
- /* Update day of the week */
- update_RTCDate->WeekDay = Read_RTC_WeekDay(year, month, day);
- //读取星期几的值
- }
-
- HAL_StatusTypeDef Read_RTC_Time(RTC_DateTypeDef *update_RTCDate, RTC_TimeTypeDef *sTime)
- {
- uint32_t counter_time = 0U, counter_alarm = 0U, days_elapsed = 0U, hours = 0U;
-
- counter_time = Read_RTC_Time_Counter();//读"RTC计数寄存器",总秒数
- hours = counter_time / 3600U;//计算有多少小时
- sTime->Minutes = (uint8_t)((counter_time % 3600U) / 60U);//计算分钟数值
- sTime->Seconds = (uint8_t)((counter_time % 3600U) % 60U);//计算秒数值
-
- if (hours >= 24U)
- {
- days_elapsed = (hours / 24U);//计算"天"
- sTime->Hours = (hours % 24U);//计算今天的"小时时间"
-
- counter_alarm = Read_RTC_Alarm_Counter();
- //读"RTC闹钟寄存器"
- //Read Alarm counter in RTC registers
-
- /* Calculate remaining time to reach alarm (only if set and not yet expired)*/
- if ((counter_alarm != 0xFFFFFFFF) && (counter_alarm > counter_time))
- {//RTC_ALARM_RESETVALUE=0xFFFFFFFFU
- counter_alarm -= counter_time;//计算"距离报警时间的差值"
- }
- else
- {
- /* In case of counter_alarm < counter_time */
- /* Alarm expiration already occurred but alarm not deactivated */
- counter_alarm = 0xFFFFFFFF;
- //RTC_ALARM_RESETVALUE=0xFFFFFFFFU
- }
-
- /* Set updated time in decreasing counter by number of days elapsed */
- counter_time -= (days_elapsed * 24U * 3600U);//计算"今天的总秒数"
-
- /* Write time counter in RTC registers */
- if (Write_RTC_Time_Counter(counter_time) != HAL_OK)
- {//将"今天的总秒数"counter_time写入"RTC计数寄存器"
- return HAL_ERROR;
- }
-
- /* Set updated alarm to be set */
- if (counter_alarm != 0xFFFFFFFF)
- {//RTC_ALARM_RESETVALUE=0xFFFFFFFFU
- counter_alarm += counter_time;
- //报警时间 = "距离报警时间的差值" + "今天的总秒数"
- if (Write_RTC_Alarm_Counter(counter_alarm) != HAL_OK)
- {//将AlarmCounter写入"RTC闹钟寄存器"
- return HAL_ERROR;
- }
- }
- else
- {
- /* Alarm already occurred. Set it to reset values to avoid unexpected expiration */
- if (Write_RTC_Alarm_Counter(counter_alarm) != HAL_OK)
- {//将AlarmCounter写入"RTC闹钟寄存器"
- return HAL_ERROR;
- }
- }
-
- /* Update date */
- Update_RTC_Date(update_RTCDate, days_elapsed);
- }
- else
- {
- sTime->Hours = hours;
- }
-
- return HAL_OK;
- }
-
- HAL_StatusTypeDef Read_RTC_Date(RTC_DateTypeDef *update_RTCDate,RTC_DateTypeDef *sDate)
- {
- RTC_TimeTypeDef stime = {0U};
-
- /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
- if (Read_RTC_Time(update_RTCDate, &stime) != HAL_OK)
- {
- return HAL_ERROR;
- }
-
- /* Fill the structure fields with the read parameters */
- sDate->WeekDay = update_RTCDate->WeekDay;
- sDate->Year = update_RTCDate->Year;
- sDate->Month = update_RTCDate->Month;
- sDate->Date = update_RTCDate->Date;
-
- return HAL_OK;
- }
-
- void RTC_Init(void)
- {
- RTC_HandleTypeDef RTC_HandleStructureure;
- RCC_OscInitTypeDef RCC_OscInit_Structureure;
- RCC_PeriphCLKInitTypeDef PeriphClkInit_Structureure;
-
- Century=20;//世纪,21世纪用20表示
-
- RTC_HandleStructureure.Instance = RTC; //选择RTC
- RTC_HandleStructureure.Init.AsynchPrediv = RTC_AUTO_1_SECOND; //RTC一秒时基自动计算
-
- //HAL_RTC_MspInit函数开始//
- RCC_OscInit_Structureure.OscillatorType = RCC_OSCILLATORTYPE_LSI;
-
- RCC_OscInit_Structureure.LSIState = RCC_LSI_ON;
- HAL_RCC_OscConfig(&RCC_OscInit_Structureure);
-
- PeriphClkInit_Structureure.PeriphClockSelection = RCC_PERIPHCLK_RTC;
- PeriphClkInit_Structureure.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
- HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit_Structureure);
-
- __HAL_RCC_RTCAPB_CLK_ENABLE();
- //使能RTC APB外部设备时钟,Enable RTC peripheral Clocks
- __HAL_RCC_RTC_ENABLE();//使能RTC时钟,Enable RTC Clock
-
- HAL_NVIC_SetPriority(RTC_IRQn, 0x01, 0);
- //设置RTC中断优先级为0x01,0无意义
- NVIC_EnableIRQ(RTC_IRQn);//使能RTC中断
-
- __HAL_RTC_OVERFLOW_ENABLE_IT(&RTC_HandleStructureure, RTC_IT_OW);//使能溢出中断,Overflow interrupt
- __HAL_RTC_ALARM_ENABLE_IT(&RTC_HandleStructureure, RTC_IT_ALRA);//使能报警中断,Alarm interrupt
- __HAL_RTC_SECOND_ENABLE_IT(&RTC_HandleStructureure, RTC_IT_SEC);//使能秒中断,Second interrupt
- //HAL_RTC_MspInit函数结束//
-
- HAL_RTC_Init(&RTC_HandleStructureure);//RTC初始化
-
- /设置日期: 2023/9/27 星期三/
- RTC_DateStructureure.Year = 23;
- RTC_DateStructureure.Month =9;
- RTC_DateStructureure.Date = 27;
- RTC_DateStructureure.WeekDay = RTC_WEEKDAY_WEDNESDAY;
- HAL_RTC_SetDate(&RTC_HandleStructureure, &RTC_DateStructureure, RTC_FORMAT_BIN);
- //设置RTC日期
-
- /设置时间: 09:00:00/
- RTC_TimeStructureure.Hours = 9;
- RTC_TimeStructureure.Minutes =00;
- RTC_TimeStructureure.Seconds = 00;
- HAL_RTC_SetTime(&RTC_HandleStructureure, &RTC_TimeStructureure, RTC_FORMAT_BIN);
- //设置RTC时间
-
- /设置RTC闹钟,时间到09:01:00产生中断/
- RTC_AlarmStructureure.AlarmTime.Hours = 9;
- RTC_AlarmStructureure.AlarmTime.Minutes = 1;
- RTC_AlarmStructureure.AlarmTime.Seconds = 00;
- HAL_RTC_SetAlarm_IT(&RTC_HandleStructureure, &RTC_AlarmStructureure, RTC_FORMAT_BIN);
- }
-
- void RTC_Display(void)
- {
- Read_RTC_Time(&RTC_DateStructureure,&RTC_TimeStructureure);
- // Read_RTC_Date(&RTC_DateStructureure,&RTC_DateStructureure);
-
- // RTC_HandleTypeDef RTC_HandleStructureure;
-
- // RTC_HandleStructureure.Instance = RTC;//选择RTC
- // printf("RTC_IT_SEC\r\n");
- // HAL_RTC_GetTime(&RTC_HandleStructureure, &RTC_TimeStructureure, RTC_FORMAT_BIN);//读取"RTC时间"
- // HAL_RTC_GetDate(&RTC_HandleStructureure, &RTC_DateStructureure, RTC_FORMAT_BIN);//读取"RTC日期"
- printf("%02d%02d-%02d-%02d %02d:%02d:%02d\r\n", Century,RTC_DateStructureure.Year,RTC_DateStructureure.Month,RTC_DateStructureure.Date,RTC_TimeStructureure.Hours, RTC_TimeStructureure.Minutes, RTC_TimeStructureure.Seconds);
- //显示时间格式为 : YY-MM-DD hh:mm:ss
- if(RTC_DateStructureure.WeekDay==RTC_WEEKDAY_SUNDAY) printf("Sunday\r\n");
- if(RTC_DateStructureure.WeekDay==RTC_WEEKDAY_MONDAY) printf("Monday\r\n");
- if(RTC_DateStructureure.WeekDay==RTC_WEEKDAY_TUESDAY) printf("Tuesday\r\n");
- if(RTC_DateStructureure.WeekDay==RTC_WEEKDAY_WEDNESDAY) printf("Wednesday\r\n");
- if(RTC_DateStructureure.WeekDay==RTC_WEEKDAY_THURSDAY) printf("Thursday\r\n");
- if(RTC_DateStructureure.WeekDay==RTC_WEEKDAY_FRIDAY) printf("Friday\r\n");
- if(RTC_DateStructureure.WeekDay==RTC_WEEKDAY_SATURDAY) printf("Saturday\r\n");
- }
-
- //函数功能;RTC中断服务函数
- void RTC_IRQHandler(void)
- {
- if (_HAL_RTC_SECOND_GET_FLAG(RTC,RTC_FLAG_SEC))
- {
- if (_HAL_RTC_SECOND_GET_FLAG(RTC, RTC_FLAG_OW))
- {//RTC计数器溢出中断
- /HAL_RTCEx_RTCEventCallback函数开始/
- printf("%s","\r\nRTC Overflow!!!\r\n");
- /HAL_RTCEx_RTCEventCallback函数结束/
-
- _HAL_RTC_OVERFLOW_CLEAR_FLAG(RTC, RTC_FLAG_OW);
- //清除溢出中断
- }
- else
- {//RTC产生秒中断
- /HAL_RTCEx_RTCEventCallback函数开始/
- MCU_LED_Toggle();
- /HAL_RTCEx_RTCEventCallback函数结束/
- }
- _HAL_RTC_SECOND_CLEAR_FLAG(RTC, RTC_FLAG_SEC);
- }
-
- if (_HAL_RTC_ALARM_GET_FLAG(RTC, RTC_FLAG_ALRAF) != (uint32_t)RESET)
- {//RTC产生报警中断
- /HAL_RTC_AlarmAEventCallback函数开始/
- printf("%s","\r\nRTC Alarm!!!\r\n");
- /HAL_RTC_AlarmAEventCallback函数结束/
- _HAL_RTC_ALARM_CLEAR_FLAG(RTC, RTC_FLAG_ALRAF);
- //Clear the Alarm interrupt pending bit
- }
- }
- #ifndef __RTC_H
- #define __RTC_H
-
- #include "py32f0xx_hal.h"
-
- #define _HAL_RTC_SECOND_GET_FLAG(__INSTANCE__, __FLAG__) (((((__INSTANCE__)->CRL) & (__FLAG__)) != RESET)? SET : RESET)
- #define _HAL_RTC_OVERFLOW_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->CRL) = ~(__FLAG__)
- #define _HAL_RTC_SECOND_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->CRL) = ~(__FLAG__)
- #define _HAL_RTC_ALARM_GET_FLAG(__INSTANCE__, __FLAG__) (((((__INSTANCE__)->CRL) & (__FLAG__)) != RESET)? SET : RESET)
- #define _HAL_RTC_ALARM_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->CRL) = ~(__FLAG__)
- //#define _HAL_RTC_ALARM_ENABLE_IT(__INSTANCE__, __INTERRUPT__) SET_BIT((__INSTANCE__)->CRH, (__INTERRUPT__))
-
- #define _HAL_RTC_WRITEPROTECTION_ENABLE(__INSTANCE__) CLEAR_BIT((__INSTANCE__)->CRL, RTC_CRL_CNF)
- //将"RTC控制寄存器RTC_CRL"中的CNF=1,进入RTC配置模式
-
- #define _HAL_RTC_WRITEPROTECTION_DISABLE(__INSTANCE__) SET_BIT((__INSTANCE__)->CRL, RTC_CRL_CNF)
- //将"RTC控制寄存器RTC_CRL"中的CNF=0,退出配置模式,开始更新RTC寄存器
- extern void RTC_Init(void);
- extern void RTC_Display(void);
-
- #endif /* __RTC_H */
- #include "py32f0xx_hal.h"
- #include "SystemClock.h"
- #include "delay.h"
- #include "LED.h"
- #include "SystemClock.h"
- #include "USART2.h"
- #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
- #include "string.h" //使能strcpy(),strlen(),memset()
- #include "RTC.h"
-
- const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
- int main(void)
- {
- HSE_Config();
- // HAL_Init();//systick初始化
- delay_init();
- HAL_Delay(1000);
-
- USART2_Init(115200);
- //PA0是为USART2_TX,PA1是USART2_RX
- //中断优先级为0x01
- //波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
- printf("%s",CPU_Reset_REG);
-
- MCU_LED_Init();
- RTC_Init();
-
- while (1)
- {
- delay_ms(1000);
- RTC_Display();
- }
- }
四、误差分析

误差: 每10分钟误差6秒。1%的误差,还行。