打印

GD32L233 怎么通过RTC实现秒中断

[复制链接]
917|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fxliuqq|  楼主 | 2025-6-21 15:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
GD32L233 怎么通过RTC实现秒中断

使用特权

评论回复
沙发
hbzjt2011| | 2025-6-24 13:18 | 只看该作者

GD32L233 怎么通过RTC实现秒中断

#include "gd32l23x.h"
#include <stdio.h>

// 时间结构体定义
typedef struct {
    uint8_t seconds;
    uint8_t minutes;
    uint8_t hours;
    uint8_t day;
    uint8_t date;
    uint8_t month;
    uint16_t year;
} rtc_time;

volatile uint32_t seconds_counter = 0;  // 秒计数器
volatile uint8_t time_updated = 0;      // 时间更新标志

// 时间初始化值
rtc_time initial_time = {
    .seconds = 0,
    .minutes = 0,
    .hours = 12,
    .day = 1,     // 周一
    .date = 1,    // 1号
    .month = 1,   // 1月
    .year = 2024  // 2024年
};

// RTC初始化函数
void rtc_configuration(void)
{
    /* 1. 使能时钟 */
    rcu_periph_clock_enable(RCU_PMU);
    rcu_periph_clock_enable(RCU_BDCU);

    /* 2. 使能备份域写访问 */
    pmu_backup_write_enable();

    /* 3. 配置RTC时钟源为LXTAL */
    rcu_osci_on(RCU_LXTAL);
    rcu_osci_stab_wait(RCU_LXTAL);
    rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);

    /* 4. 使能RTC时钟 */
    rcu_periph_clock_enable(RCU_RTC);

    /* 5. 等待RTC寄存器同步 */
    rtc_register_sync_wait();

    /* 6. 配置预分频器 */
    // 异步分频器:127 (32768/(127+1)=256Hz)
    // 同步分频器:255 (256/(255+1)=1Hz)
    rtc_prescaler_config(127, 255);

    /* 7. 配置秒中断 */
    rtc_interrupt_enable(RTC_INT_SECOND);

    /* 8. 等待配置完成 */
    rtc_lwoff_wait();

    /* 9. 初始化时间 */
    rtc_time_set(&initial_time);

    /* 10. 使能NVIC中断 */
    nvic_irq_enable(RTC_IRQn, 0, 0);
}

// 设置时间
void rtc_time_set(rtc_time *time)
{
    /* 等待寄存器可写 */
    rtc_lwoff_wait();

    /* 设置时间 */
    rtc_counter_set(
        (uint32_t)time->seconds +
        (uint32_t)time->minutes * 60 +
        (uint32_t)time->hours * 3600
    );

    /* 设置日期 */
    rtc_date_set(
        time->year,
        time->month,
        time->date,
        time->day
    );
}

// 获取时间
void rtc_time_get(rtc_time *time)
{
    uint32_t counter = rtc_counter_get();
    rtc_date_struct date;
    rtc_current_date_get(&date);

    time->seconds = counter % 60;
    time->minutes = (counter / 60) % 60;
    time->hours = counter / 3600;
    time->day = date.weekday;
    time->date = date.day;
    time->month = date.month;
    time->year = date.year;
}

// RTC中断服务函数
void RTC_IRQHandler(void)
{
    if(RESET != rtc_flag_get(RTC_FLAG_SECOND)) {
        /* 清除秒中断标志 */
        rtc_flag_clear(RTC_FLAG_SECOND);

        /* 更新秒计数器 */
        seconds_counter++;

        /* 设置时间更新标志 */
        time_updated = 1;
    }
}

// 打印当前时间
void print_current_time(void)
{
    rtc_time current_time;
    rtc_time_get(&current_time);

    printf("当前时间: %04u-%02u-%02u %02u:%02u:%02u 星期%u\n",
           current_time.year,
           current_time.month,
           current_time.date,
           current_time.hours,
           current_time.minutes,
           current_time.seconds,
           current_time.day);
}

int main(void)
{
    /* 系统时钟配置 */
    rcu_system_clock_config(RCU_CKSYSSRC_HXTAL, RCU_PLL_MUL6, RCU_PLL_DIV1);

    /* 初始化串口 */
    // 这里省略串口初始化代码,实际使用时需要添加

    /* 初始化RTC */
    rtc_configuration();

    printf("GD32L233 RTC秒中断演示\n");
    printf("RTC已初始化,每秒产生一次中断\n");

    while(1) {
        if(time_updated) {
            time_updated = 0;
            print_current_time();
            printf("系统运行秒数: %lu\n", seconds_counter);
        }

        // 主循环中执行其他任务...
    }
}

使用特权

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

本版积分规则

4

主题

12

帖子

0

粉丝