【蓝桥杯嵌入式】四、各种外设驱动(七)RTC实时时钟--时间显示、周期唤醒和闹钟

温馨提示:本文不会重复之前提到的内容,如需查看,请参考附录

【蓝桥杯嵌入式】附录

目录

重点提炼:

一、需求分析

1、需要的外设资源分析:

 2、外设具体分析:

CubeMX配置中,我们需要改动的参数:

二、软件配置

按照分析配置引脚:

然后配置 Parameter Settings :

打开并设置中断优先级:

三、程序功能实现

用到的函数:

在MDK中编写代码:

 找到RTC闹钟的中断服务函数:RTC_Alarm_IRQHandler(void)

四、运行测试


重点提炼:

CubeMX配置中,我们需要改动的参数:

用到的函数:

一、需求分析

        我们将设计一个示例项目RTC_Alarm_Demo,使用闹钟A、闹钟B和周期唤醒功能,它具有如下功能。

  • 使用32.768kHz的LSE时钟作为RTC的时钟源。
  • 系统复位时初始化RTC日期为2023-3-19,时间为9:15:10
  • 每秒唤醒一次,在周期唤醒中断里读取当前日期和时间,并在LCD上显示。
  • 闹钟A设置为在时间xx:15:15触发,其中xx表示任意数字,即在每个小时的15分15秒时刻触发闹钟A。
  • 对闹钟A中断次数计数,并在LCD上显示。
  • 闹钟B设置为在时间xx:xx:20触发,即在每分钟的20秒时刻触发闹钟B。对闹钟B中断次数计数,并 在LCD上显示。

1、需要的外设资源分析:

  • RTC的两个内部时钟,RTC唤醒中断输出引脚PC13用于控制LED;
  • LCD、锁存器控制引脚PD2(见附录);

 2、外设具体分析:

查看原理图,和手册。

CubeMX配置中,我们需要改动的参数:

1、RTC基本参数设置:

  • Hour Format,小时格式,可以选择12 小时制或24小时制。
  • Output Polarity,输出极性。闹钟A、闹钟B、周期唤醒中断事件信号有效时的输出极性,可设置为高电平或低电平。

        Calendar TimeCalendar Data 分组里有用于设置日历的时间参数和初始化数据的如下参数:

  • Data Format,数据格式,可选择二进制格式或BCD格式,这里选择Binary data forms
  • 初始化时间数据,包括时、分、秒的数据。
  • 初始化日期数据,包括年、月、日的数据。

2、Alarm 闹钟设置:

  • 设置闹钟时间数据,包括时、分、秒的数据。
  • Mask项:设置为Enable表示屏蔽某时间值的影响。

3、周期唤醒设置

  • Wake Up Clock 可以设置为各种分频信号,一般设置为1Hz,即每秒一次。
  • Wake Up Counter,周期唤醒重载值,与秒数有差一性,设置为零表示一秒。

4、中断设置

  • RTC的中断唤醒和闹钟的中断的中断优先级都设置为1

二、软件配置

参考附录的内容,建立名为“RTC_Alarm_Demo”的项目。

按照分析配置:

选中RTC,打开两个闹钟,均使用内部闹钟功能;设置WakeUp模式为内部唤醒如图:

切换到时钟配置,选择LSI作为RTC的时钟,这样可以让RTC生成比较标准的1s/Hz,如图:

然后配置 Parameter Settings :

按照前文的分析与介绍,这里的设置如图所示:

打开并设置中断优先级:

生成项目文件后,打开MDK;

导入LCD驱动程序文件。

三、程序功能实现

用到的函数:

中断服务函数名称:

RTC_WKUP_IRQHandler(void);

HAL_RTC_AlarmAEventCallback(hrtc);//对应Alarm A

HAL_RTCEx_AlarmBEventCallback(hrtc);//对应Alarm B

RTC函数名称:

 注意:这两个函数必须一起使用,不管你用不用的着,因为必须取出全部结果才可以重新写入。

HAL_RTC_GetTime(&hrtc,&sTime,RTC_FORMAT_BIN);//获取当前时间
HAL_RTC_GetDate(&hrtc,&sData,RTC_FORMAT_BIN);//获取当前日期

在MDK中编写代码:

main.h中 :

/* USER CODE BEGIN Includes */
#include "lcd.h"
#include <stdio.h>
/* USER CODE END Includes */

main函数中初始化LCD,并设置背景色和画笔颜色,清屏:

stm32g4xx_it.c 中,定义两个全局变量,用于计数:

找到RTC唤醒的中断服务函数:RTC_WKUP_IRQHandler(void)   大约在204行

在如下代码段编写程序:

代码如下:

  /* USER CODE END RTC_WKUP_IRQn 0 */
  HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc);
  /* USER CODE BEGIN RTC_WKUP_IRQn 1 */
	RTC_TimeTypeDef sTime;
	RTC_DateTypeDef sData;
	
	if(HAL_RTC_GetTime(&hrtc,&sTime,RTC_FORMAT_BIN) == HAL_OK)
	{
		HAL_RTC_GetDate(&hrtc,&sData,RTC_FORMAT_BIN);
		char str[20];
		sprintf(str,"Data:20%2d-%2d-%2d",sData.Year,sData.Month,sData.Date);
		LCD_DisplayStringLine(Line3,str);
		sprintf(str,"Time:%2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);
		LCD_DisplayStringLine(Line5,str);
		}
  /* USER CODE END RTC_WKUP_IRQn 1 */
 找到RTC闹钟的中断服务函数:
RTC_Alarm_IRQHandler(void)

由于要分别对Alarm A 和 Alarm B 计数,所以必须在对应的中断回调函数里实现;

右击 HAL_RTC_AlarmIRQHandler (&hrtc); 然后点击Go To Definition,如图:

自动跳转到这里:该函数判断了到底是哪个闹钟引起了中断,并调用了对应的中断回调函数。

HAL_RTC_AlarmAEventCallback(hrtc);对应Alarm A

HAL_RTCEx_AlarmBEventCallback(hrtc);对应Alarm B

同样的右击,然后点击Go To Definition,就可以找到这两个函数。

这两个函数是弱函数,需要用户重新实现。复制函数的定义,如:

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)

粘贴到 stm32g4xx_it.c 中的如下位置:(最底下的用户代码段)

完成后如图:

 之后在里面实现功能,代码如下:

/* USER CODE BEGIN 1 */
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
	char str[20];
	CntA++;
	sprintf(str,"Alarm A count: %d",CntA);
	LCD_DisplayStringLine (Line7,str);
}

void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
{
	char str[20];
	CntB++;
	sprintf(str,"Alarm B count: %d",CntB);
	LCD_DisplayStringLine (Line9,str);
}
/* USER CODE END 1 */

四、运行测试

编译、下载(见附录)。

运行结果如下:

RTC_Alarm实验结果

  • 30
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值