RTC走时功能+GPIO控制LCD12864显示
[复制链接]
本文记录rtc走时功能,并使用GPIO控制LCD12864液晶显示出当前时间
新建rtc.c文件,添加到工程当中,
其中:
0. rtc使用32k晶体时钟;
set_rtc_time函数是设置rtc的时间,
1. 芯片上电后,仅设置一次rtc时间,重复调用不会重新设置rtc时间,rtc时间丢失后才会重新设置时间;
2. 设置的时间为代码编译时的系统时间;
set_rtc_alarm函数是设置alarm中断功能,
3. 利用subsecond alarm中断功能,实现每秒进一次RTC Alarm中断,并在中断处理函数中获取当前时间,并显示出来;
代码如下:
#include "gd32l23x.h"
#include "rtc.h"
#include "lcd12864.h"
//#define RTC_CLOCK_SOURCE_IRC32K
#define RTC_CLOCK_SOURCE_LXTAL
#define BKP_VALUE 0x32F0
static rtc_parameter_struct rtc_initpara;
static rtc_alarm_struct rtc_alarm;
__IO uint32_t prescaler_a = 0, prescaler_s = 0;
void rtc_pre_config(void)
{
/* enable PMU and BKP clock */
rcu_periph_clock_enable(RCU_PMU);
rcu_periph_clock_enable(RCU_BKP);
/* enable the access of the RTC registers */
pmu_backup_write_enable();
#if defined (RTC_CLOCK_SOURCE_IRC32K)
rcu_osci_on(RCU_IRC32K);
rcu_osci_stab_wait(RCU_IRC32K);
rcu_rtc_clock_config(RCU_RTCSRC_IRC32K);
prescaler_s = 0x13F;
prescaler_a = 0x63;
#elif defined (RTC_CLOCK_SOURCE_LXTAL)
rcu_osci_on(RCU_LXTAL);
rcu_osci_stab_wait(RCU_LXTAL);
rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
prescaler_s = 0xFF;
prescaler_a = 0x7F;
#else
#error RTC clock source should be defined.
#endif /* RTC_CLOCK_SOURCE_IRC32K */
rcu_periph_clock_enable(RCU_RTC);
rtc_register_sync_wait();
}
static uint8_t gSystemDate[12] = __DATE__;
static uint8_t gSystemTime[16] = __TIME__;
void set_rtc_time(void)
{
uint32_t tmp;
rtc_parameter_struct rtc_stime;
rtc_parameter_struct rtc_gtime;
int i,j,k=0;
char month[12][3]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",};
rtc_pre_config();
rtc_current_time_get(&rtc_gtime);
tmp = rtc_gtime.year;
//Set rtc time only once after power up
if(tmp<0x22)
{
//month
for(i=0; i<12; i++)
{
for(j=0; j<3; j++)
{
if(gSystemDate[j] == month[i][j])
{
k++;
}
else
{
k=0;
break;
}
}
if(k==3)
{
if(i>=9) i+=6;
rtc_stime.month = i+1;
break;
}
}
//day
if(gSystemDate[4] == ' ') gSystemDate[4] = '0';
rtc_stime.date = (gSystemDate[4]-'0')*16 + (gSystemDate[5]-'0');
//year
rtc_stime.year = (gSystemDate[9]-'0')*16 + (gSystemDate[10]-'0');
//hour
rtc_stime.hour = (gSystemTime[0]-'0')*16 + (gSystemTime[1]-'0') ;
//minute
rtc_stime.minute = (gSystemTime[3]-'0')*16 + (gSystemTime[4]-'0') ;
//second
rtc_stime.second = (gSystemTime[6]-'0')*16 + (gSystemTime[7]-'0') ;
rtc_stime.day_of_week = RTC_SATURDAY;
rtc_stime.display_format = RTC_24HOUR;
rtc_stime.factor_asyn = prescaler_a;
rtc_stime.factor_syn = prescaler_s;
rtc_stime.am_pm = RTC_AM;
if (ERROR == rtc_init(&rtc_stime))
{
LCD_printf_line(7,"rtc init error");
}
}
}
void set_rtc_alarm(void)
{
rtc_alarm_struct rtc_alarm_time;
//
rtc_alarm_time.alarm_mask = RTC_ALARM_ALL_MASK;
rtc_alarm_config(RTC_ALARM0, &rtc_alarm_time);
// subsecond
rtc_alarm_subsecond_config(RTC_ALARM0, RTC_MSKSSC_NONE, 0);
rtc_flag_clear(RTC_FLAG_ALARM0);
rtc_interrupt_enable(RTC_INT_ALARM0);
rtc_alarm_enable(RTC_ALARM0);
/* RTC alarm interrupt configuration */
exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
nvic_irq_enable(RTC_Alarm_IRQn, 2U);
}
void get_rtc_time_and_display(void)
{
rtc_parameter_struct rtc_gtime;
rtc_current_time_get(&rtc_gtime);
LCD_printf_line(7,"20%02x-%02x-%02x %02x:%02x:%02x %x", \
rtc_gtime.year, rtc_gtime.month, rtc_gtime.date, \
rtc_gtime.hour, rtc_gtime.minute, rtc_gtime.second, \
rtc_gtime.day_of_week);
}
中断处理函数:
void RTC_Alarm_IRQHandler(void)
{
if (SET == rtc_flag_get(RTC_FLAG_ALARM0))
{
rtc_flag_clear(RTC_FLAG_ALARM0);
get_rtc_time_and_display();
}
}
|