打印
[活动专区]

【AT-START-L021测评】6、ERTC做个时钟

[复制链接]
758|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AT32L021之ERTC:增强型RTC,具有闹钟、亚秒级精度、及硬件日历,带校准功能

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

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

  /* allow access to ertc */
  pwc_battery_powered_domain_access(TRUE);

  /* reset ertc domain */
  crm_battery_powered_domain_reset(TRUE);
  crm_battery_powered_domain_reset(FALSE);

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

  /* wait till lick is ready */
  while(crm_flag_get(CRM_LICK_STABLE_FLAG) == RESET)
  {
  }

  /* select the ertc clock source */
  crm_ertc_clock_select(CRM_ERTC_CLOCK_LICK);

  /* ertc second(1hz) = ertc_clk(lick) / (ertc_clk_div_a + 1) * (ertc_clk_div_b + 1) */
  ertc_clk_div_b = 255;
  ertc_clk_div_a = 127;
#elif defined (ERTC_CLOCK_SOURCE_LEXT)
  /* enable the lext osc */
  crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE);

  /* wait till lext is ready */
  while(crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET)
  {
  }

  /* select the ertc clock source */
  crm_ertc_clock_select(CRM_ERTC_CLOCK_LEXT);

  /* ertc second(1hz) = ertc_clk / (ertc_clk_div_a + 1) * (ertc_clk_div_b + 1) */
  ertc_clk_div_b = 255;
  ertc_clk_div_a = 127;
#endif

  /* enable the ertc clock */
  crm_ertc_clock_enable(TRUE);

  /* deinitializes the ertc registers */
  ertc_reset();

  /* wait for ertc registers update */
  ertc_wait_update();

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

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

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

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

  /* set the alarm 12:00:10 */
  ertc_alarm_mask_set(ERTC_ALA, ERTC_ALARM_MASK_DATE_WEEK);
  ertc_alarm_week_date_select(ERTC_ALA, ERTC_SLECT_DATE);
  ertc_alarm_set(ERTC_ALA, 1, 12, 0, 10, ERTC_AM);

  /* enable ertc alarm a interrupt */
  ertc_interrupt_enable(ERTC_ALA_INT, TRUE);

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

  ertc_flag_clear(ERTC_ALAF_FLAG);

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

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

  /* get the current time */
  ertc_calendar_get(&time);

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

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

3、闹钟显示

void ertc_alarm_show(void)
{
  ertc_alarm_value_type alarm;


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

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

}
4、ERTC中断处理
void ERTC_IRQHandler(void)
{
  if(ertc_interrupt_flag_get(ERTC_ALAF_FLAG) != RESET)
  {
    /* display the alarm */
    ertc_alarm_show();

    at32_led_on(LED2);

    /* clear alarm flag */
    ertc_flag_clear(ERTC_ALAF_FLAG);

    /* clear exint flag */
    exint_flag_clear(EXINT_LINE_17);
  }
}

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

        
        /* enable the pwc clock interface */
  crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE);

  /* allow access to ertc */
  pwc_battery_powered_domain_access(TRUE);

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

    /* ertc configuration */
    ertc_config();
  }
  else
  {
    /* printf ertc status */
    printf("ertc has been initialized\r\n\r\n");

    /* wait for ertc registers update */
    ertc_wait_update();

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

    /* clear the exint line 17 pending bit */
    exint_flag_clear(EXINT_LINE_17);
  }
        
        /* ertc alarm interrupt configuration */
  exint_default_para_init(&exint_init_struct);
  exint_init_struct.line_enable   = TRUE;
  exint_init_struct.line_mode     = EXINT_LINE_INTERRUPT;
  exint_init_struct.line_select   = EXINT_LINE_17;
  exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
  exint_init(&exint_init_struct);

  /* enable the ertc interrupt */
  nvic_irq_enable(ERTC_IRQn, 0, 1);
        delay_ms(1000);
        clrScr(0X92C);
}

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


6、运行效果



7、源码
test1.rar (85.63 KB)



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

48

主题

96

帖子

0

粉丝