蓝桥杯嵌入式——RTC

蓝桥杯嵌入式——RTC

配置

  1. cubeMX
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

程序编写

  1. 获取时间
RTC_TimeTypeDef T;
RTC_DateTypeDef D;

void rtc_proc()
{
	HAL_RTC_GetTime(&hrtc, &T, RTC_FORMAT_BIN); //日期和时间都要获取
	HAL_RTC_GetDate(&hrtc, &D, RTC_FORMAT_BIN);

	if(second != T.Seconds)
	{
		second = T.Seconds;
		printf("%02d-%02d-%02d\r\n",T.Hours,T.Minutes,T.Seconds);
	}	
}

注:需要在调用HAL_RTC_GetTime()后再调用HAL_RTC_GetDate(),即使用不到日期。

  1. 闹钟中断

在闹钟不变的情况下:

如果 忽略小时,忽略分钟,不忽略秒。 一分钟中断一次
如果 忽略小时,不忽略分钟,不忽略秒。 一小时中断一次
如果 不忽略小时,不忽略分钟,不忽略秒。 一天中断一次

如每分钟中断一次:
在这里插入图片描述
3. 秒中断(1~59s 的中断)

定义一个包含 时、分、秒的结构体

typedef struct
{
    uint8_t h;
    uint8_t m;
    uint8_t s;    
}nTime;

用到的变量

static uint8_t first_time_flag=1;  //用于判断是否为第一次中断
static uint8_t sAlarm_flag=0;	   //闹钟标志位
RTC_AlarmTypeDef sAlarm;
nTime Time;

这里我建立了新的bsp_rtc.c\bsp_rtc.h文件,专门放中断和设置闹钟时间

//单独处理要设置的闹钟时间
void dev_set_alarm_time(void)
{
    if(first_time_flag==1)
    {
        Time.h=1;
        Time.m=1;
        Time.s=10;
        first_time_flag=0;
    }
    Time.s+=5;  //每5秒进入一次
    if(Time.s>= 60)
    {
        Time.m+=1;
        if(Time.m>=60)
            {
                Time.h+= 1;
                if(Time.h >= 24)
                    {
                        Time.h = 0;
                    }
                Time.m= 0;
            }
        Time.s -=60;
    }
    sAlarm.AlarmTime.Hours   = Time.h;
    sAlarm.AlarmTime.Minutes = Time.m;
    sAlarm.AlarmTime.Seconds = Time.s;
}

//用于main函数的调用,轮询判断是否要重新启动闹钟
void dev_rtc_alarm(RTC_HandleTypeDef *hrtc)
{
    if(sAlarm_flag==1)//收到闹钟标志位
    {
        dev_set_alarm_time();//时间设置
    	sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS|RTC_ALARMMASK_MINUTES;     //闹钟掩码设置
        sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;   //日期(日/星期)选择,此位只有当AlarmMask中不设置RTC_ALARMMASK_DATEWEEKDAY时才有效
        sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
        sAlarm.AlarmDateWeekDay = 1;
        sAlarm.Alarm = RTC_ALARM_A;
        
        HAL_RTC_SetAlarm_IT(hrtc,&sAlarm,RTC_FORMAT_BIN);   // 再次启动闹钟中断事件
        
        sAlarm_flag=0;//清除闹钟标志位
    }
}

//闹钟中断回调函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
    //代码
    printf("你好\r\n");

    sAlarm_flag=1;  //闹钟标志位
            
}