gd32的rtc使用心得

本文介绍了在GD32微控制器中,当外部低速振荡器(LSE)无法启动时,如何切换到内部低速振荡器(LSI)并保持RTC时钟精度的解决方案。通过配置RTC设置和监控系统运行时间,确保在LSE故障时无缝过渡到LSI模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

gd32的rtc用起来真是不好用,对晶振要求太高,不容易起振。本文章旨在解决外部LSE不起振时,使用LSI并保证精度的解决方案。

struct RTC_MONITOR
{
uint8_t monitor_on;//0:on,1:off
uint8_t rtcclk_source;//0:lse,1:lsi

uint8_t rtc_backsecond;
uint8_t rtc_second;

uint32_t timer_period;
uint32_t sysrun_bytimer;
uint32_t sysrun_bytimers;
uint32_t sysrun_byrtc;

uint8_t get_second;
uint8_t get_minute;
uint8_t get_hour;
uint8_t get_day;
uint8_t get_month;
uint32_t get_year;
uint32_t get_counter;
};


struct RTC_MONITOR rtc_monitor;

int main(void)

{

//init hardware

RTC_Configuration();

init_rtc_monitor();

while(1)

{

rtc_monitor_on();  

}

}

uint32_t lwoff_timeout,rsf_timeout,lsifrequency;
void RTC_Configuration(void)
{
  uint32_t WaitForOscSource;


  
  /*Enables the clock to Backup and power interface peripherals    */
  RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_BKP | RCC_APB1PERIPH_PWR,ENABLE);
  /* RTC clock source configuration ------------------------------------------*/
  /* Allow access to BKP Domain */
  PWR_BackupAccess_Enable(ENABLE);

/*Enable 40 kHz internal oscillator */
RCC_LSI_Enable(ENABLE);//´ò¿ªLSI


while(RCC_GetBitState(RCC_FLAG_LSISTB)==RESET);//µÈ´ýÖ±µ½LSIÎȶ¨

//read back
rtc_monitor.get_day  = BKP_ReadBackupRegister(BKP_DR3);
  rtc_monitor.get_month = BKP_ReadBackupRegister(BKP_DR2);
  rtc_monitor.get_year  = BKP_ReadBackupRegister(BKP_DR4);
rtc_monitor.get_second   = BKP_ReadBackupRegister(BKP_DR5);
  rtc_monitor.get_minute = BKP_ReadBackupRegister(BKP_DR6);
  rtc_monitor.get_hour  = BKP_ReadBackupRegister(BKP_DR7);
rtc_monitor.get_counter = RTC_GetCounter();

if(BKP_ReadBackupRegister(BKP_DR1)==CONFIGURATION_RESET)
{
    /* Backup Domain Reset */
//rtc clk init
BKP_DeInit(); 
PWR_BackupAccess_Enable(ENABLE);


while((PWR->CTLR & PWR_CTLR_BKPWE) == RESET);
/*Enable 32.768 kHz external oscillator */
RCC_LSEConfig(RCC_LSE_EN);
for(WaitForOscSource=0;WaitForOscSource<5000;WaitForOscSource++)
{
}


RCC_RTCCLKConfig(RCC_RTCCLKSOURCE_LSE);
/* RTC Enabled */
RCC_RTCCLK_Enable(ENABLE);

//RTC_WaitLWOFF();
lwoff_timeout = LSE_STARTUP_TIMEOUT;
/* Loop until RTOFF flag is set */
while (((RTC->CTLR2 & RTC_FLAG_LWOFF) == (uint16_t)RESET)&&(lwoff_timeout))
{
lwoff_timeout--;
}

/*Wait for RTC registers synchronisation */
//RTC_WaitRSF();
/* Clear RSF flag */
RTC->CTLR2 &= ~((uint16_t)RTC_FLAG_RSF);
/* Loop until RSF flag is set */

<think>好的,我现在需要帮助用户了解如何在GD32微控制器上配置RTC闹钟控制。首先,我需要回顾一下GD32RTC模块的基本知识。GD32RTC模块通常依赖于外部低速振荡器(LSE)或者内部低速RC(LSI)作为时钟源,用户需要根据实际需求选择合适的时钟源,并配置相应的预分频器来得到1Hz的时钟信号。 接下来,配置RTC的步骤可能包括初始化RTC时钟源、设置日期和时间、使能闹钟中断,以及编写中断服务函数。我需要确保代码示例中正确配置了RTC的寄存器,特别是闹钟寄存器和中断使能位。同时,要注意GD32不同型号之间的差异,比如寄存器地址或者库函数的名称可能有所不同,需要提醒用户查阅具体的参考手册。 用户可能遇到的问题包括时钟源不稳定导致RTC计时不准,或者闹钟中断无法触发。这时候需要检查LSE/LSI的启动情况,以及中断配置是否正确,比如NVIC的设置是否启用,中断服务函数是否有误。此外,电源管理部分也需要注意,确保在低功耗模式下RTC仍然能够正常工作。 在代码示例部分,我需要使用GD32的标准外设库函数,例如rtc_init()、rtc_alarm_config()等,并展示如何设置闹钟时间和日期。同时,中断服务函数中需要清除中断标志位,防止重复进入中断。用户可能需要了解如何通过库函数获取当前RTC时间,并设置闹钟的匹配方式,比如按秒、分、时或者日期匹配。 最后,生成的相关问题需要覆盖常见的使用场景和问题排查,比如如何校准RTC、处理闹钟不触发的情况,以及低功耗模式下的配置注意事项。这些相关问题能够帮助用户更全面地理解和应用RTC闹钟功能。</think>### GD32 RTC闹钟控制实现步骤 #### 一、硬件配置要点 1. **时钟源选择**:推荐使用$32.768kHz$外部晶振(LSE),误差±20ppm对应日误差约1.728秒 2. **备份域供电**:确保VBAT引脚连接备用电源(3V纽扣电池) 3. **寄存器写保护**:操作前需解除写保护,修改后重新上锁 #### 二、软件配置流程 ```c #include "gd32f30x.h" void rtc_config(void) { /* 使能时钟和备份域访问 */ rcu_osci_on(RCU_LSE); // 启动LSE while(!rcu_osci_stab_wait(RCU_LSE)); // 等待振荡稳定[^1] rcu_rtc_clock_config(RCU_RTCSRC_LSE); // 选择RTC时钟源 rcu_periph_clock_enable(RCU_RTC); // 使能RTC时钟 rtc_register_sync_wait(); // 等待寄存器同步 /* 配置RTC预分频器 */ rtc_prescaler_set(32767); // 32768Hz/(32767+1)=1Hz rtc_counter_set(0); // 初始化计数器 /* 配置闹钟 */ rtc_alarm_config(ALARM_TIME); // ALARM_TIME为秒数 rtc_interrupt_enable(RTC_INT_ALARM); // 使能闹钟中断 nvic_irq_enable(RTC_IRQn, 0, 0); // 配置NVIC } void rtc_alarm_irq_handler(void) { if(rtc_flag_get(RTC_FLAG_ALARM) == SET){ rtc_flag_clear(RTC_FLAG_ALARM); // 清除中断标志 /* 用户处理代码 */ } } ``` #### 三、关键参数说明 1. **预分频公式**: $$ PREDIV = (LSE_{freq} / 1Hz) - 1 $$ 当使用$32.768kHz$晶振时: $$ PREDIV = 32768 - 1 = 32767 $$ 2. **时间换算**: 设置$12:30:00$对应的秒数: $$ total\_seconds = 12×3600 + 30×60 = 45000 $$ #### 四、调试注意事项 1. **首次编程**:需通过ISP工具解锁Flash 2. **寄存器保护**:修改配置前执行: ```c pmu_backup_write_enable(); rtc_unlock(); /* 配置操作 */ rtc_lock(); ``` 3. **低功耗模式**:唤醒后需检查RTC状态寄存器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值