RTC时钟初始化(GD32F303)

最近需要用到时钟,掉电走时的。装上纽扣电池。怼起来!

rtc.h

#ifndef __RTC_H
#define __RTC_H


#include "gd32f30x.h"
#include <stdbool.h>

typedef struct
{
	bool status;
	uint8_t second;
	uint8_t minute;
	uint8_t hour;
	uint8_t day;
	uint8_t week;
	uint8_t month;
	uint8_t year;
} RTC_struct;

//主函数中需要用到这两个
void vrtcConfiguration(void);//配置
void vrtcInit(void); //初始化   



void vrtcUpdataTime(void);
void vrtcGetTime(uint32_t rtctime);
	
#endif

rtc.c

#include "stdio.h"
#include "stdlib.h"
#include "systick.h"
#include "../User/BSP/RTC/rtc.h"

RTC_struct RtcDate;

bool rtcflag;



/***********************************************************
*@fuction	:vrtcConfiguration
*@brief		:
*@param		:--
*@return	:void
*@author	:flechazo
*@date		:2023-06-13
***********************************************************/
void vrtcConfiguration(void)
{
    /* enable PMU and BKPI clocks*/
    rcu_periph_clock_enable(RCU_BKPI);
    rcu_periph_clock_enable(RCU_PMU);

    /* allow access to BKP domain*/
    pmu_backup_write_enable();

    /* reset backup domain */
    //bkp_deinit();

    /* enable LXTAL ʹ 32.768K */
    rcu_osci_on(RCU_LXTAL);

    /* wait till LXTAL is ready */
    rcu_osci_stab_wait(RCU_LXTAL);

    /* select RCU_LXTAL as RTC clock source */
    rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);

    /* enable RTC Clock ʹRTC*/
    rcu_periph_clock_enable(RCU_RTC);

    rtc_configuration_mode_enter();

    /* wait for RTC registers synchronization */
    rtc_register_sync_wait();

    /* wait until last write operation on RTC registers has finished RTC*/
    rtc_lwoff_wait();

    /* enable the RTC second interrupt ʹRTC'*/
    rtc_interrupt_enable(RTC_INT_SECOND);

    /* wait until last write operation on RTC registers has finished RTC*/
    rtc_lwoff_wait();

    /* set RTC prescaler: set RTC period to 1s */
    rtc_prescaler_set(32767);
    /* wait until last write operation on RTC registers has finished RTC*/
    rtc_lwoff_wait();

    //nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
    nvic_irq_enable(RTC_IRQn, 3U, 0U);

}




/***********************************************************
*@fuction	:vrtcInit
*@brief		:
*@param		:--
*@return	:void
*@author	:flechazo
*@date		:2023-06-13
***********************************************************/
void vrtcInit(void)
{
    if(0xFC1F != bkp_read_data(BKP_DATA_0))
    {
        vrtcConfiguration();
        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();
        /* change the current time */
        //rtc_counter_set(0);
        /* wait until last write operation on RTC registers has finished */
        rtc_lwoff_wait();
        rtc_lwoff_wait();
        rtc_lwoff_wait();
        bkp_write_data(BKP_DATA_0, 0xFC1F);
    }
    else
    {
        /* check if the power on reset flag is set */
        if(rcu_flag_get(RCU_FLAG_PORRST) != RESET)
        {
            printf("\r\n\n Power On Reset occurred....");
        }
        else if(rcu_flag_get(RCU_FLAG_SWRST) != RESET)
        {
            /* check if the pin reset flag is set */
            printf("\r\n\n External Reset occurred....");
        }
        printf("\r\n No need to configure RTC....");
        rtc_register_sync_wait();
        rtc_interrupt_enable(RTC_INT_SECOND);
        rtc_lwoff_wait();
    }
    rtc_configuration_mode_exit();
    rcu_all_reset_flag_clear();
}


/***********************************************************
*@fuction	:vrtcGetTime
*@brief		:
*@param		:--
*@return	:void
*@author	:flechazo
*@date		:2023-06-13
***********************************************************/
void vrtcGetTime(uint32_t rtctime)
{
    uint8_t s, m, h;
    s = rtctime % 0x60;
    RtcDate.second = s;
    m = rtctime / 0x60 % 0x60;
    RtcDate.minute = m;
    h = rtctime / 0x60 / 0x60 % 0x24;
    RtcDate.hour = h;
    RtcDate.day = rtctime / 0x60 / 0x60 / 0x24 % 30;
    RtcDate.week = rtctime / 0x60 / 0x60 / 0x24 % 7;
}


/***********************************************************
*@fuction	:vrtcUpdataTime
*@brief		:
*@param		:--
*@return	:void
*@author	:flechazo
*@date		:2023-06-13
***********************************************************/
void vrtcUpdataTime(void)
{
    uint32_t rtcvalue = RtcDate.week * 0x60 * 0x60 * 0x24  + RtcDate.hour * 0x60 * 0x60 + RtcDate.minute * 0x60 + RtcDate.second;
    rtc_counter_set(rtcvalue);
}


/**
  * @brief  This function handles RTC exception.
  * @param  None
  * @retval None
  */
void RTC_IRQHandler(void)
{
    if(rtc_flag_get(RTC_FLAG_SECOND) != RESET) 
    {
        rtc_flag_clear(RTC_FLAG_SECOND);

        RtcDate.second++;
        if((RtcDate.second & 0x0F) > 9)
        {
            RtcDate.second += (0x10 - 10);
        }
        if(RtcDate.second > 95)
        {
            RtcDate.second = 0;
            RtcDate.minute++;
            if((RtcDate.minute & 0x0F) > 9)
            {
                RtcDate.minute += (0x10 - 10);
            }
            if(RtcDate.minute > 95)
            {
                RtcDate.minute = 0;
                RtcDate.hour++;
                if((RtcDate.minute & 0x0F) > 9)
                {
                    RtcDate.minute += (0x10 - 10);
                }
                if(RtcDate.hour > 35)
                {
                    RtcDate.hour = 0;
                    RtcDate.day++;
                    //flush task execute status
                    vtaskIndexInit();
                    if((RtcDate.day & 0x0F) > 9)
                    {
                        RtcDate.day += (0x10 - 10);
                    }
                    if(RtcDate.day > 47)
                    {
                        RtcDate.day = 0;
                    }
                }
            }
        }

        rtcflag = true;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlechazoCLF

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值