[APM32E0] APM32E030的RTC驱动(时钟)

[复制链接]
76|0
口天土立口 发表于 2025-10-15 18:59 | 显示全部楼层 |阅读模式
9564568ef7ec120d56.png

APM32E030支持RTC外设,可作为时钟使用;

驱动代码如下:
  1. /* RTC初始化标记 */
  2. #define RTC_BKP_DATA    (RTC_BAKP_DATA0)
  3. #define BKP_DATA        (0x12345678)
  1. /*
  2. * @brief       RTC初始化
  3. *
  4. * @param       None
  5. *
  6. * @retval      None
  7. *
  8. */
  9. void bsp_rtc_init(void)
  10. {
  11.     RTC_Config_T RtcStruct;
  12.     RTC_TIME_T timeStruct;
  13.     RTC_DATE_T dateStruct;
  14.    
  15.     /* 使能RTC区域写, 否则无法开启LSE */
  16.     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
  17.     PMU_EnableBackupAccess();
  18.    
  19.     /* 备份值一致则无需重复初始化 */
  20.     if (RTC_ReadBackup(RTC_BKP_DATA) != BKP_DATA) {   
  21.         /* 复位RTC域 */
  22.         RCM_EnableBackupReset();
  23.         __NOP();__NOP();__NOP();__NOP();
  24.         RCM_DisableBackupReset();
  25.         
  26.         /* 开启LSE */
  27.         RCM_ConfigLSE(RCM_LSE_OPEN);
  28.         while (RCM_ReadStatusFlag(RCM_FLAG_LSERDY) != SET);
  29.         RCM_ConfigDriveLSE(RCM_LSE_DRIVE_High);
  30.         /* RTC 时钟为LSE */
  31.         RCM_ConfigRTCCLK(RCM_RTCCLK_LSE);
  32.         RCM_EnableRTCCLK();
  33.         
  34.         /* 配置RTC */
  35.         RTC_Reset();
  36.         RTC_ConfigStructInit(&RtcStruct);
  37.         RtcStruct.format = RTC_HourFormat_24;
  38.         /* 时钟先异步分配,再同步分频到RTC使用
  39.          * 1HZ = 32768 / 256 / 128
  40.          */
  41.         RtcStruct.SynchPrediv = 256 - 1;
  42.         RtcStruct.AsynchPrediv = 128 - 1;
  43.         RTC_Config(&RtcStruct);
  44.         /* 配置默认时间 */
  45.         RTC_ConfigTimeStructInit(&timeStruct);
  46.         timeStruct.hours = 12;
  47.         timeStruct.minutes = 10;
  48.         timeStruct.seconds = 10;
  49.         timeStruct.H12 = RTC_H12_AM;
  50.         if (RTC_ConfigTime(RTC_FORMAT_BIN, &timeStruct) == SUCCESS) {
  51.             /* 配置默认日期 */
  52.             RTC_ConfigDateStructInit(&dateStruct);
  53.             dateStruct.weekday = RTC_WEEKDAY_TUESDAY;
  54.             dateStruct.date = 23;
  55.             dateStruct.month = RTC_MONTH_SEPTEMBER;
  56.             dateStruct.year = 25;
  57.             RTC_ConfigDate(RTC_FORMAT_BIN, &dateStruct);
  58.         }
  59.         RTC_WriteBackup(RTC_BKP_DATA, BKP_DATA);
  60.     }
  61.    
  62.     /* 禁止RTC寄存器可写 */
  63.     PMU_DisableBackupAccess();
  64. }
  1. /*
  2. * @brief       获取RTC时间
  3. *
  4. * @param       dt: 日期时间
  5. *
  6. * @retval      None
  7. *
  8. */
  9. void bsp_rtc_datetime_get(struct datetime_t *dt)
  10. {
  11.     RTC_TIME_T timeStruct;
  12.     RTC_TIME_T timeStruct2;
  13.     RTC_DATE_T dateStruct;
  14.     RTC_DATE_T dateStruct2;
  15.    
  16.     if (dt != NULL) {   
  17.         do {
  18.             RTC_ReadTime(RTC_FORMAT_BIN, &timeStruct);
  19.             RTC_ReadTime(RTC_FORMAT_BIN, &timeStruct2);
  20.             RTC_ReadDate(RTC_FORMAT_BIN, &dateStruct);
  21.             RTC_ReadDate(RTC_FORMAT_BIN, &dateStruct2);
  22.             /* 确保两次读取的数据完全一致,避免卡跨时间点位置导致时间错乱 */
  23.             if ((memcmp(&timeStruct, &timeStruct2, sizeof(RTC_TIME_T)) == 0) && \
  24.                 (memcmp(&dateStruct, &dateStruct2, sizeof(RTC_DATE_T)) == 0)) {
  25.                 dt->second = timeStruct.seconds;
  26.                 dt->minute = timeStruct.minutes;
  27.                 dt->hour = timeStruct.hours;
  28.                 dt->day = dateStruct.date;
  29.                 dt->month = dateStruct.month;
  30.                 dt->year = 2000 + dateStruct.year;
  31.                 dt->week = dateStruct.weekday;
  32.                 break;
  33.             }
  34.         } while (1);
  35.     }
  36. }
  1. /*
  2. * @brief       设置RTC时间
  3. *
  4. * @param       dt: 日期时间
  5. *
  6. * @retval      None
  7. *
  8. */
  9. void bsp_rtc_datetime_set(struct datetime_t *dt)
  10. {
  11.     RTC_TIME_T timeStruct;
  12.     RTC_TIME_T timeStruct2;
  13.     RTC_DATE_T dateStruct;
  14.     RTC_DATE_T dateStruct2;
  15.     uint8_t state;
  16.     uint8_t state2;
  17.    
  18.     /* 填充数据 */
  19.     timeStruct.seconds = dt->second;
  20.     timeStruct.minutes = dt->minute;   
  21.     timeStruct.hours = dt->hour;
  22.     dateStruct.date = dt->day;
  23.     dateStruct.month = dt->month;
  24.     dateStruct.year = dt->year % 100;
  25.     dateStruct.weekday = dt->week;
  26.    
  27.     if (dt != NULL) {   
  28.         do {
  29.             /* 允许RTC寄存器可写 */
  30.             PMU_EnableBackupAccess();
  31.             /* 配置时间日期 */
  32.             state = RTC_ConfigTime(RTC_FORMAT_BIN, &timeStruct);
  33.             state2 = RTC_ConfigDate(RTC_FORMAT_BIN, &dateStruct);
  34.             if ((state != SUCCESS) || (state2 != SUCCESS)) {
  35.                 continue;
  36.             }
  37.             RTC_ReadTime(RTC_FORMAT_BIN, &timeStruct2);
  38.             RTC_ReadDate(RTC_FORMAT_BIN, &dateStruct2);
  39.             /* 确保读取的数据与写入的完全一致 */
  40.             if ((memcmp(&timeStruct, &timeStruct2, sizeof(RTC_TIME_T)) == 0) && \
  41.                 (memcmp(&dateStruct, &dateStruct2, sizeof(RTC_DATE_T)) == 0)) {
  42.                 break;
  43.             }
  44.         } while (1);
  45.         /* 禁止RTC寄存器可写 */
  46.         PMU_DisableBackupAccess();
  47.     }
  48. }


测试代码如下:
  1. struct datetime_t datetime_get;
  2. struct datetime_t datetime_set;
  3. uint8_t flag_datetime_set;

  4. // 应用初始化
  5. void app_init(void)
  6. {
  7.     bsp_rtc_init();
  8. }

  9. // 应用任务
  10. void app_task(void)
  11. {
  12.     bsp_rtc_datetime_get(&datetime_get);
  13.     if (flag_datetime_set != 0) {
  14.         flag_datetime_set = 0;
  15.         bsp_rtc_datetime_set(&datetime_set);
  16.     }
  17. }


详细代码,请查看附件!
Clock.zip (2.05 MB, 下载次数: 0)



您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

54

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部