APM32E030支持RTC外设,可作为时钟使用;
驱动代码如下:
- /* RTC初始化标记 */
- #define RTC_BKP_DATA (RTC_BAKP_DATA0)
- #define BKP_DATA (0x12345678)
- /*
- * @brief RTC初始化
- *
- * @param None
- *
- * @retval None
- *
- */
- void bsp_rtc_init(void)
- {
- RTC_Config_T RtcStruct;
- RTC_TIME_T timeStruct;
- RTC_DATE_T dateStruct;
-
- /* 使能RTC区域写, 否则无法开启LSE */
- RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
- PMU_EnableBackupAccess();
-
- /* 备份值一致则无需重复初始化 */
- if (RTC_ReadBackup(RTC_BKP_DATA) != BKP_DATA) {
- /* 复位RTC域 */
- RCM_EnableBackupReset();
- __NOP();__NOP();__NOP();__NOP();
- RCM_DisableBackupReset();
-
- /* 开启LSE */
- RCM_ConfigLSE(RCM_LSE_OPEN);
- while (RCM_ReadStatusFlag(RCM_FLAG_LSERDY) != SET);
- RCM_ConfigDriveLSE(RCM_LSE_DRIVE_High);
- /* RTC 时钟为LSE */
- RCM_ConfigRTCCLK(RCM_RTCCLK_LSE);
- RCM_EnableRTCCLK();
-
- /* 配置RTC */
- RTC_Reset();
- RTC_ConfigStructInit(&RtcStruct);
- RtcStruct.format = RTC_HourFormat_24;
- /* 时钟先异步分配,再同步分频到RTC使用
- * 1HZ = 32768 / 256 / 128
- */
- RtcStruct.SynchPrediv = 256 - 1;
- RtcStruct.AsynchPrediv = 128 - 1;
- RTC_Config(&RtcStruct);
- /* 配置默认时间 */
- RTC_ConfigTimeStructInit(&timeStruct);
- timeStruct.hours = 12;
- timeStruct.minutes = 10;
- timeStruct.seconds = 10;
- timeStruct.H12 = RTC_H12_AM;
- if (RTC_ConfigTime(RTC_FORMAT_BIN, &timeStruct) == SUCCESS) {
- /* 配置默认日期 */
- RTC_ConfigDateStructInit(&dateStruct);
- dateStruct.weekday = RTC_WEEKDAY_TUESDAY;
- dateStruct.date = 23;
- dateStruct.month = RTC_MONTH_SEPTEMBER;
- dateStruct.year = 25;
- RTC_ConfigDate(RTC_FORMAT_BIN, &dateStruct);
- }
- RTC_WriteBackup(RTC_BKP_DATA, BKP_DATA);
- }
-
- /* 禁止RTC寄存器可写 */
- PMU_DisableBackupAccess();
- }
- /*
- * @brief 获取RTC时间
- *
- * @param dt: 日期时间
- *
- * @retval None
- *
- */
- void bsp_rtc_datetime_get(struct datetime_t *dt)
- {
- RTC_TIME_T timeStruct;
- RTC_TIME_T timeStruct2;
- RTC_DATE_T dateStruct;
- RTC_DATE_T dateStruct2;
-
- if (dt != NULL) {
- do {
- RTC_ReadTime(RTC_FORMAT_BIN, &timeStruct);
- RTC_ReadTime(RTC_FORMAT_BIN, &timeStruct2);
- RTC_ReadDate(RTC_FORMAT_BIN, &dateStruct);
- RTC_ReadDate(RTC_FORMAT_BIN, &dateStruct2);
- /* 确保两次读取的数据完全一致,避免卡跨时间点位置导致时间错乱 */
- if ((memcmp(&timeStruct, &timeStruct2, sizeof(RTC_TIME_T)) == 0) && \
- (memcmp(&dateStruct, &dateStruct2, sizeof(RTC_DATE_T)) == 0)) {
- dt->second = timeStruct.seconds;
- dt->minute = timeStruct.minutes;
- dt->hour = timeStruct.hours;
- dt->day = dateStruct.date;
- dt->month = dateStruct.month;
- dt->year = 2000 + dateStruct.year;
- dt->week = dateStruct.weekday;
- break;
- }
- } while (1);
- }
- }
- /*
- * @brief 设置RTC时间
- *
- * @param dt: 日期时间
- *
- * @retval None
- *
- */
- void bsp_rtc_datetime_set(struct datetime_t *dt)
- {
- RTC_TIME_T timeStruct;
- RTC_TIME_T timeStruct2;
- RTC_DATE_T dateStruct;
- RTC_DATE_T dateStruct2;
- uint8_t state;
- uint8_t state2;
-
- /* 填充数据 */
- timeStruct.seconds = dt->second;
- timeStruct.minutes = dt->minute;
- timeStruct.hours = dt->hour;
- dateStruct.date = dt->day;
- dateStruct.month = dt->month;
- dateStruct.year = dt->year % 100;
- dateStruct.weekday = dt->week;
-
- if (dt != NULL) {
- do {
- /* 允许RTC寄存器可写 */
- PMU_EnableBackupAccess();
- /* 配置时间日期 */
- state = RTC_ConfigTime(RTC_FORMAT_BIN, &timeStruct);
- state2 = RTC_ConfigDate(RTC_FORMAT_BIN, &dateStruct);
- if ((state != SUCCESS) || (state2 != SUCCESS)) {
- continue;
- }
- RTC_ReadTime(RTC_FORMAT_BIN, &timeStruct2);
- RTC_ReadDate(RTC_FORMAT_BIN, &dateStruct2);
- /* 确保读取的数据与写入的完全一致 */
- if ((memcmp(&timeStruct, &timeStruct2, sizeof(RTC_TIME_T)) == 0) && \
- (memcmp(&dateStruct, &dateStruct2, sizeof(RTC_DATE_T)) == 0)) {
- break;
- }
- } while (1);
- /* 禁止RTC寄存器可写 */
- PMU_DisableBackupAccess();
- }
- }
测试代码如下:
- struct datetime_t datetime_get;
- struct datetime_t datetime_set;
- uint8_t flag_datetime_set;
- // 应用初始化
- void app_init(void)
- {
- bsp_rtc_init();
- }
- // 应用任务
- void app_task(void)
- {
- bsp_rtc_datetime_get(&datetime_get);
- if (flag_datetime_set != 0) {
- flag_datetime_set = 0;
- bsp_rtc_datetime_set(&datetime_set);
- }
- }
详细代码,请查看附件!
Clock.zip
(2.05 MB, 下载次数: 0)
|