[应用相关] ERTC闹钟功能的使用方法

[复制链接]
2075|9
 楼主| yiyigirl2014 发表于 2023-6-12 16:50 | 显示全部楼层 |阅读模式
main文件
  1. int main(void)
  2. {
  3. exint_init_type exint_init_struct;
  4. ertc_time_type time;
  5. uint32_t temp = 0;

  6. /*初始化系统时钟 */
  7. system_clock_config();

  8. /*配置 NVIC 优先级组 */
  9. nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);

  10. /* 初始化 ATSTART 板子资源 */
  11. at32_board_init();
  12. /*初始化串口*/
  13. uart_init(115200);
  14. /* 开启 PWC 时钟 */
  15. crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);
  16. /* 使能电池供电域写保护 */
  17. pwc_battery_powered_domain_access(TRUE);

  18. if (ertc_bpr_data_read(ERTC_DT1) != 0x1234)
  19. {
  20. /* 打印信息 */
  21. printf("ertc has not been initialized\r\n\r\n");

  22. /* ERTC 初始化 */
  23. ertc_config();
  24. }
  25. else
  26. {
  27. /* 打印信息 */
  28. printf("ertc has been initialized\r\n\r\n");

  29. /* 等待 ERTC 寄存器同步,最多需要 2 个 ERTC_CLK */
  30. ertc_wait_update();
  31. /* 清除闹钟标志 */
  32. ertc_flag_clear(ERTC_ALAF_FLAG);
  33. /* 清除 exint 挂起标志 */
  34. exint_flag_clear(EXINT_LINE_17);
  35. }
  36. /* 显示当前的 ertc 时间和闹钟时间 */
  37. ertc_time_show();
  38. ertc_alarm_show();
  39. printf("\r\n");

  40. /* 闹钟初始化 */
  41. exint_default_para_init(&exint_init_struct);
  42. exint_init_struct.line_enable = TRUE;
  43. exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
  44. exint_init_struct.line_select = EXINT_LINE_17;
  45. exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
  46. exint_init(&exint_init_struct);

  47. /* 使能闹钟中断 */
  48. nvic_irq_enable(ERTCAlarm_IRQn, 0, 1);
  49. while(1)
  50. {
  51. /* 获取当前日历 */
  52. ertc_calendar_get(&time);

  53. if(temp != time.sec)
  54. {
  55. temp = time.sec;

  56. /* 打印日期:年-月-日 */
  57. printf("%02d-%02d-%02d ",time.year, time.month, time.day);

  58. /* 打印时间:时:分:秒 */
  59. printf("%02d:%02d:%02d\r\n",time.hour, time.min, time.sec);
  60. }
  61. }
  62. }
ERTC 初始化 ertc_config 函数代码描述
  1. void ertc_config(void)
  2. {
  3. /* 开启 PWC 时钟 */
  4. crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);

  5. /* 使能电池供电域写保护 */
  6. pwc_battery_powered_domain_access(TRUE);
  7. /* 复位电池供电域寄存器 */
  8. crm_battery_powered_domain_reset(TRUE);
  9. crm_battery_powered_domain_reset(FALSE);

  10. #if defined (ERTC_CLOCK_SOURCE_LICK)
  11. /* 使能 LICK 时钟 */
  12. crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);
  13. /* 等待 LICK 时钟稳定 */
  14. while(crm_flag_get(CRM_LICK_STABLE_FLAG) == RESET)
  15. {
  16. }
  17. /* 选择 ERTC 时钟源 */
  18. crm_ertc_clock_select(CRM_ERTC_CLOCK_LICK);

  19. /* ertc second(1hz) = ertc_clk(lick) / (ertc_clk_div_a + 1) * (ertc_clk_div_b + 1) */
  20. ertc_clk_div_b = 255;
  21. ertc_clk_div_a = 127;
  22. #elif defined (ERTC_CLOCK_SOURCE_LEXT)
  23. /* 使能 LEXT 时钟 */
  24. crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE);
  25. /* 等待 LEXT 时钟稳定 */
  26. while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET)
  27. {
  28. }
  29. /* 选择 ERTC 时钟源 */
  30. crm_ertc_clock_select(CRM_ERTC_CLOCK_LEXT);
  31. /* ertc second(1hz) = ertc_clk / (ertc_clk_div_a + 1) * (ertc_clk_div_b + 1) */
  32. ertc_clk_div_b = 255;
  33. ertc_clk_div_a = 127;
  34. #endif
  35. /* 使能 ERTC 时钟 */
  36. crm_ertc_clock_enable(TRUE);
  37. /* 复位所有 ERTC 寄存器 */
  38. ertc_reset();
  39. /* 等待 ERTC 寄存器同步,最多需要 2 个 ERTC_CLK */
  40. ertc_wait_update();

  41. /* 配置 ERTC 分频器 */
  42. ertc_divider_set(ertc_clk_div_a, ertc_clk_div_b);

  43. /* 配置 ERTC 小时格式为 24 小时格式 */
  44. ertc_hour_mode_set(ERTC_HOUR_MODE_24);

  45. /* 设置日期: 2021-05-01 */
  46. ertc_date_set(21, 5, 1, 5);

  47. /* 设置时间: 12:00:00 */
  48. ertc_time_set(12, 0, 0, ERTC_AM);

  49. /* 设置闹钟 12:00:10 */
  50. ertc_alarm_mask_set(ERTC_ALA, ERTC_ALARM_MASK_DATE_WEEK);
  51. ertc_alarm_week_date_select(ERTC_ALA, ERTC_SLECT_DATE);
  52. ertc_alarm_set(ERTC_ALA, 1, 12, 0, 10, ERTC_AM);

  53. /* 使能闹钟中断 */
  54. ertc_interrupt_enable(ERTC_ALA_INT, TRUE);
  55. /* 开启闹钟 */
  56. ertc_alarm_enable(ERTC_ALA, TRUE);

  57. ertc_flag_clear(ERTC_ALAF_FLAG);

  58. /* 指示 ERTC 初始化 */
  59. ertc_bpr_data_write(ERTC_DT1, 0x1234);
  60. }
闹钟中断函数代码描述
  1. void ERTCAlarm_IRQHandler(void)
  2. {
  3. if(ertc_flag_get(ERTC_ALAF_FLAG) != RESET)
  4. {
  5. /* 显示闹钟 */
  6. ertc_alarm_show();

  7. at32_led_on(LED2);

  8. /* 清除闹钟标志 */
  9. ertc_flag_clear(ERTC_ALAF_FLAG);

  10. /* 清除 EXINT 标志 */
  11. exint_flag_clear(EXINT_LINE_17);
  12. }
  13. }
最后中断处理程序的清理标志位很重要,如果不清理没法正常进入下一个周期的循环。
 楼主| yiyigirl2014 发表于 2023-6-12 16:51 | 显示全部楼层
贴代码要像我这样贴啊,不然看起来费劲。用专门的代码框贴。
onlycook 发表于 2023-6-13 15:52 | 显示全部楼层
这代码框看起来挺不习惯的
tpgf 发表于 2023-7-3 11:00 | 显示全部楼层
实时时钟 (ERTC) 是一个独立的 BCD 定时器/计数器
nawu 发表于 2023-7-3 11:16 | 显示全部楼层
ERTC 提供一个日历时钟、一个可编程闹钟中断
aoyi 发表于 2023-7-3 11:32 | 显示全部楼层
ERTC两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒、分钟、小时(12 或 24 小时制)、星期几、日期、
月份和年份。此外,还可提供二进制格式的亚秒值
zljiu 发表于 2023-7-3 11:59 | 显示全部楼层
上电复位后,所有 ERTC 寄存器都会受到保护,以防止可能的非正常写访问
gwsan 发表于 2023-7-3 12:11 | 显示全部楼层
无论器件状态如何(运行模式、低功耗模式或处于复位状态),只要电源电压保持在工作范围内, ERTC
便不会停止工作
tfqi 发表于 2023-7-3 13:07 | 显示全部楼层
可以使用数字校准功能对晶振精度的偏差进行补偿
uiint 发表于 2023-7-5 16:55 | 显示全部楼层
ERTC模块可以提供精确的时间和日期信息,以及闹钟功能。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

230

主题

3676

帖子

10

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