打印

GD32F4—RTC闹钟及自动唤醒中断配置详解

[复制链接]
1434|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
9dome猫|  楼主 | 2022-12-24 15:03 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
GD32F4x的RTC例程网上资源较少,详细阅读用户手册后做出如下配置。RTC模块提供了一个包含日期(年/月/日)和时间(时/分/秒/亚秒)的日历功能。除亚秒用二进制码显示外,时间和日期都以BCD码的形式显示。RTC可以进行夏令时补偿。RTC可以工作在省电模式下,并通过软件配置来智能唤醒。RTC支持外接更高精度的低频时钟,用以达到更高的日历精度。下边就以RTC模块的框图为引线,对RTC的相关功能和操作做相关介绍。

框图:

RTC单元有三个可选的独立时钟源:LXTAL、IRC32K和HXTAL,一般选用LXTAL外部32.768K晶振,内部晶振受温漂影响,计时会存在较大的误差。LXTAL随后经过一个7位的异步预分频(默认值为127+1)和一个15位的同步预分频(255+1),得到1Hz的时钟频率。

使用特权

评论回复
沙发
9dome猫|  楼主 | 2022-12-24 15:09 | 只看该作者
RTC 初始化和配置
在默认情况下,PMU_CTL寄存器的BKPWEN位被清0。所以写RTC寄存器前需要软件提前设置BKPWEN位。RTC_BKPx寄存器处于VDD备份域中,即使VDD电源被切断,该区域的寄存器的电源还可由VBAT提供。从待机模式唤醒或系统复位操作都不会影响这些寄存器。只有当被检测到有侵入事件和备份域复位时,这些寄存器复位。

使用特权

评论回复
板凳
9dome猫|  楼主 | 2022-12-24 15:09 | 只看该作者
#define BKP_VALUE    0x32F1
void RTC_Config(void)
{
        //rcu_bkp_reset_enable();//复位备份域
        rcu_periph_clock_enable(RCU_PMU);//使能PMU电源管理单元时钟
        pmu_backup_write_enable();//使能电源备份源,置位BKPWEN位。
       
        /***配置外部时钟***/
        rcu_osci_on(RCU_LXTAL); //使用外部晶振32.768K
        rcu_osci_stab_wait(RCU_LXTAL);//等待振荡器稳定标志位置位或振荡器起振超时
        rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);//配置RTC时钟源为外部晶振32.768K
        rcu_periph_clock_enable(RCU_RTC);//使能RTC外设时钟
        rtc_register_sync_wait();//等待RTC寄存器(RTC_TIME、RTC_DATE)与RTC的APB时钟同步
        WakeupConfig();//唤醒中断配置
        //AlarmConfig();//闹钟中断配置
        if(RTC_BKP0 == BKP_VALUE)//设置后系统复位不会在重新配置时间
          return;
        RTC_SetTime(22,9,30,23,59,59);//配置时间
        RTC_BKP0 = BKP_VALUE;
}

使用特权

评论回复
地板
9dome猫|  楼主 | 2022-12-24 15:10 | 只看该作者
RTC时间是由BCD编码进行配置的,时间的BCD码和二进制转换:
uint8_t RTC_BCDToByte(uint8_t Value)//BCD转二进制
{
        uint8_t tmp;
  tmp = ((Value & 0xF0u) >> 4u) * 10u;
  return (tmp + (Value & 0x0Fu));
}
uint8_t RTC_ByteToBCD(uint8_t Value)//二进制转BCD
{
  uint32_t bcdhigh = 0u;
  uint8_t Param = Value;

  while(Param >= 10u)
  {
    bcdhigh++;
    Param -= 10u;
  }
  return  ((uint8_t)(bcdhigh << 4u) | Param);
}

使用特权

评论回复
5
9dome猫|  楼主 | 2022-12-24 15:11 | 只看该作者
RTC时间是由结构体rtc_parameter_struct进行配置,时间配置函数:
void RTC_SetTime(unsigned short year,unsigned short month,unsigned short day,unsigned short hour,unsigned short min,unsigned short sec)
{
        rtc_parameter_struct RTC_TimeStructure;
        RTC_TimeStructure.year              = RTC_ByteToBCD(year);
        RTC_TimeStructure.month             = RTC_ByteToBCD(month);
        RTC_TimeStructure.date              = RTC_ByteToBCD(day);
        RTC_TimeStructure.hour              = RTC_ByteToBCD(hour);
        RTC_TimeStructure.minute            = RTC_ByteToBCD(min);
        RTC_TimeStructure.second            = RTC_ByteToBCD(sec);
        RTC_TimeStructure.display_format    = RTC_24HOUR;
        RTC_TimeStructure.am_pm             = RTC_AM;
        RTC_TimeStructure.factor_asyn = 0X7F;
  RTC_TimeStructure.factor_syn  = 0XFF;
        //RTC_TimeStructure.day_of_week       = RTC_THURSDAY;
        rtc_init(&RTC_TimeStructure);
}

使用特权

评论回复
6
9dome猫|  楼主 | 2022-12-24 15:14 | 只看该作者
闹钟时间是由结构体rtc_alarm_struct进行配置
void Set_Alarm(uint8_t hour,uint8_t min,uint8_t sec)
{
        rtc_alarm_struct setTime;
        rtc_alarm_disable(RTC_ALARM0);
        setTime.alarm_mask = RTC_ALARM_DATE_MASK;//日期掩码,只判断时分秒
        setTime.weekday_or_date = RTC_ALARM_DATE_SELECTED;
        //setTime.alarm_day = day;
        setTime.alarm_hour = hour;
        setTime.alarm_minute = min;
        setTime.alarm_second = sec;
        setTime.am_pm = RTC_AM;
        rtc_alarm_config(RTC_ALARM0,&setTime);//配置RTC闹钟
        rtc_alarm_enable(RTC_ALARM0);//使能闹钟
}

使用特权

评论回复
7
9dome猫|  楼主 | 2022-12-24 15:15 | 只看该作者
闹钟中断配置初始化:
void AlarmConfig()
{
        rtc_alarm_disable(RTC_ALARM0);
        rtc_flag_clear(RTC_FLAG_ALRM0);//清空中断标志
          exti_flag_clear(EXTI_17);
                 
        exti_interrupt_flag_clear(EXTI_17);       
        nvic_irq_enable(RTC_Alarm_IRQn, 3U, 0U);
        exti_init(EXTI_22, EXTI_INTERRUPT, EXTI_TRIG_RISING);//上升沿
        Set_Alarm(RTC_TimeStructure.hour,RTC_TimeStructure.minute,RTC_TimeStructure.second+1);//设置闹钟
/* RTC alarm configuration */       
        rtc_interrupt_enable(RTC_INT_ALARM0);//使能中断
}

使用特权

评论回复
8
9dome猫|  楼主 | 2022-12-24 15:16 | 只看该作者
RTC具有一个16位的自动递减计数器用来周期性产生唤醒标志。该功能通过WTEN置1来使能,并且可以工作在省电模式。自动递减计数器有两种可选的时钟来控制:

RTC 时钟的 2/4/8/16 分频:
如果 RTC 时钟为 LXTAL(32.768 KHz),则唤醒中断周期在 122us 和 32s 之间,分辨率低至 61us。
内部时钟 ck_spre:
如果 ck_spre 为 1Hz,则唤醒中断周期在 1s 到 36h 之间,分辨率低至 1s。
WTCS[2:1] = 0b10,唤醒中断周期在 1s 到 18h
WTCS[2:1] = 0b11,唤醒中断周期在 18h 到 36h
该功能使能后,计数器自动递减。当计数器到0时,WTF标志位置1,唤醒计数器自动重载RTC_WUT的值。当WTF置1后,必须软件清除该标志。如果WTIE被置位,计数器到0时,会产生唤醒中断,从而使系统退出省电模式。系统复位对该功能没有影响。WTF标志可以从RTC_ALARM通道输出到PC13。

使用特权

评论回复
9
9dome猫|  楼主 | 2022-12-24 15:20 | 只看该作者
唤醒中断配置初始化:
void WakeupConfig()
{
        rtc_wakeup_disable();
        rtc_flag_clear(RTC_FLAG_WT);//清空中断标志
          exti_flag_clear(EXTI_22);
       
        exti_interrupt_flag_clear(EXTI_22);       
        nvic_irq_enable(RTC_WKUP_IRQn, 3U, 0U);
        exti_init(EXTI_22, EXTI_INTERRUPT, EXTI_TRIG_RISING);//上升沿
       
        rtc_wakeup_clock_set(WAKEUP_CKSPRE);//设置RTC自动唤醒定时器时钟
        rtc_wakeup_timer_set(0x0000);//自动唤醒定时器重载值,定时一秒
        rtc_wakeup_enable();
        rtc_interrupt_enable(RTC_INT_WAKEUP);//使能中断
}

使用特权

评论回复
10
9dome猫|  楼主 | 2022-12-24 15:21 | 只看该作者
中断服务函数:
void RTC_WKUP_IRQHandler(void)
{
        if (rtc_flag_get(RTC_FLAG_WT) != RESET)
        {       

                exti_interrupt_flag_clear(EXTI_22);               
                rtc_flag_clear(RTC_FLAG_WT);
        }
}
void RTC_Alarm_IRQHandler(void)
{
        if (rtc_flag_get(RTC_FLAG_ALRM0) != RESET)
        {
               
                exti_interrupt_flag_clear(EXTI_17);               
                rtc_flag_clear(RTC_FLAG_ALRM0);
        }
}

使用特权

评论回复
11
pixhw| | 2023-1-6 12:32 | 只看该作者
掉电以后数据会不会丢失了呢?              

使用特权

评论回复
12
abotomson| | 2023-1-6 17:11 | 只看该作者
这个RTC的精度怎么样?              

使用特权

评论回复
13
pentruman| | 2023-1-6 17:59 | 只看该作者
如何保存RTC的时间呢?              

使用特权

评论回复
14
belindagraham| | 2023-1-7 16:28 | 只看该作者
可以产生毫秒级别的中断吗?              

使用特权

评论回复
15
mattlincoln| | 2023-1-9 12:29 | 只看该作者
自动唤醒单片机最短的时钟间隔是多少?

使用特权

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

本版积分规则

133

主题

1406

帖子

2

粉丝