[活动专区] 【AT-START-L021测评】6、ERTC做个时钟

[复制链接]
 楼主| sujingliang 发表于 2024-11-25 21:50 | 显示全部楼层 |阅读模式
AT32L021之ERTC:增强型RTC,具有闹钟、亚秒级精度、及硬件日历,带校准功能

实时时钟用于配置日历时钟,修改 ERTC 中日历寄存器值可以修改系统的当前时间和日期。
ERTC 计数逻辑位于电池供电域,只要电池供电域有电,ERTC 便会一直运行,不受系统复位影响。
ERTC主要特性
● 功能强大的实时日历,自动处理月份天数28(平年2月)、29(闰年2月)、30(小月)、31(大
月),其中当年份寄存器是4的倍数时为闰年,支持一组闹钟
● 周期性唤醒
● 参考时钟检测
● 一组可配置入侵检测,支持时间戳功能
● 支持精密校准
● 5个电池供电寄存器
● 4组中断:闹钟A、周期性唤醒、入侵检测、时间戳
● 复用功能输出,校准时钟输出、闹钟事件或唤醒事件
● 复用功能输入,参考时钟输入、一路入侵检测、时间戳

本文使用ERTC实现一个时钟
1、ertc_config
  1. void ertc_config(void)
  2. {
  3.   /* enable the pwc clock interface */
  4.   crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);

  5.   /* allow access to ertc */
  6.   pwc_battery_powered_domain_access(TRUE);

  7.   /* reset ertc domain */
  8.   crm_battery_powered_domain_reset(TRUE);
  9.   crm_battery_powered_domain_reset(FALSE);

  10. #if defined (ERTC_CLOCK_SOURCE_LICK)
  11.   /* enable the lick osc */
  12.   crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE);

  13.   /* wait till lick is ready */
  14.   while(crm_flag_get(CRM_LICK_STABLE_FLAG) == RESET)
  15.   {
  16.   }

  17.   /* select the ertc clock source */
  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.   /* enable the lext osc */
  24.   crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE);

  25.   /* wait till lext is ready */
  26.   while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET)
  27.   {
  28.   }

  29.   /* select the ertc clock source */
  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.   /* enable the ertc clock */
  36.   crm_ertc_clock_enable(TRUE);

  37.   /* deinitializes the ertc registers */
  38.   ertc_reset();

  39.   /* wait for ertc registers update */
  40.   ertc_wait_update();

  41.   /* configure the ertc divider */
  42.   ertc_divider_set(ertc_clk_div_a, ertc_clk_div_b);

  43.   /* configure the ertc hour mode */
  44.   ertc_hour_mode_set(ERTC_HOUR_MODE_24);

  45.   /* set date: 2021-05-01 */
  46.   ertc_date_set(21, 5, 1, 5);

  47.   /* set time: 12:00:00 */
  48.   ertc_time_set(12, 0, 0, ERTC_AM);

  49.   /* set the alarm 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.   /* enable ertc alarm a interrupt */
  54.   ertc_interrupt_enable(ERTC_ALA_INT, TRUE);

  55.   /* enable the alarm */
  56.   ertc_alarm_enable(ERTC_ALA, TRUE);

  57.   ertc_flag_clear(ERTC_ALAF_FLAG);

  58.   /* indicator for the ertc configuration */
  59.   ertc_bpr_data_write(ERTC_DT1, 0x1234);
  60. }

2、时钟显示
  1. void ertc_time_show(void)
  2. {
  3.   ertc_time_type time;
  4.         char buff[8];

  5.   /* get the current time */
  6.   ertc_calendar_get(&time);

  7.   /* display date format : year-month-day */
  8.   printf("Time:  %02d-%02d-%02d ",time.year, time.month, time.day);

  9.   /* display time format : hour:min:sec */
  10.   printf("%02d:%02d:%02d\r\n",time.hour, time.min, time.sec);
  11.         
  12.         sprintf(buff,"%02d:%02d:%02d",time.hour, time.min, time.sec);
  13.         
  14.         GUI_WriteASCII_BIG(15,64,(uint8_t*)buff,0X64BD,0X92C);
  15. }

3、闹钟显示

  1. void ertc_alarm_show(void)
  2. {
  3.   ertc_alarm_value_type alarm;


  4.   /* get the current alarm */
  5.   ertc_alarm_get(ERTC_ALA, &alarm);

  6.   /* display alarm format : hour:min:sec */
  7.   printf("Alarm: %02d:%02d:%02d\r\n",alarm.hour, alarm.min, alarm.sec);

  8. }
4、ERTC中断处理
  1. void ERTC_IRQHandler(void)
  2. {
  3.   if(ertc_interrupt_flag_get(ERTC_ALAF_FLAG) != RESET)
  4.   {
  5.     /* display the alarm */
  6.     ertc_alarm_show();

  7.     at32_led_on(LED2);

  8.     /* clear alarm flag */
  9.     ertc_flag_clear(ERTC_ALAF_FLAG);

  10.     /* clear exint flag */
  11.     exint_flag_clear(EXINT_LINE_17);
  12.   }
  13. }

5、main调用
配置LCD、ERTC时钟、中断设置、使能
  1. void pre_while(void)
  2. {
  3.         
  4.         InitLCD();
  5.         clrScr(VGA_RED);
  6.         
  7.         GUI_Show**(10,10,184,88,VGA_WHITE,VGA_RED);
  8.         GUI_Write16CnChar(30,100,(unsigned char*)"AT-START-L021测评6",VGA_WHITE,VGA_RED);

  9.         
  10.         /* enable the pwc clock interface */
  11.   crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);

  12.   /* allow access to ertc */
  13.   pwc_battery_powered_domain_access(TRUE);

  14.   if (ertc_bpr_data_read(ERTC_DT1) != 0x1234)
  15.   {
  16.     /* printf ertc status */
  17.     printf("ertc has not been initialized\r\n\r\n");

  18.     /* ertc configuration */
  19.     ertc_config();
  20.   }
  21.   else
  22.   {
  23.     /* printf ertc status */
  24.     printf("ertc has been initialized\r\n\r\n");

  25.     /* wait for ertc registers update */
  26.     ertc_wait_update();

  27.     /* clear the ertc alarm flag */
  28.     ertc_flag_clear(ERTC_ALAF_FLAG);

  29.     /* clear the exint line 17 pending bit */
  30.     exint_flag_clear(EXINT_LINE_17);
  31.   }
  32.         
  33.         /* ertc alarm interrupt configuration */
  34.   exint_default_para_init(&exint_init_struct);
  35.   exint_init_struct.line_enable   = TRUE;
  36.   exint_init_struct.line_mode     = EXINT_LINE_INTERRUPT;
  37.   exint_init_struct.line_select   = EXINT_LINE_17;
  38.   exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
  39.   exint_init(&exint_init_struct);

  40.   /* enable the ertc interrupt */
  41.   nvic_irq_enable(ERTC_IRQn, 0, 1);
  42.         delay_ms(1000);
  43.         clrScr(0X92C);
  44. }

外部中断line 17是ERTC闹钟事件:
16.png

6、运行效果
17.jpg
tutieshi_480x270_4s.gif

7、源码
test1.rar (85.63 KB, 下载次数: 4)



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

本版积分规则

84

主题

146

帖子

3

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