STM32HAL库RTC闹钟事件
最近遇到stm32f系列看门狗不能关闭的事情,需要开启RTC闹钟定时唤醒喂狗。这里给RTC闹钟打一个标签把,我设置为每20秒开启一次闹钟。
首先是HAL库的配置
配置时钟:
选择下载方式
选择时钟和选择闹钟A
闹钟配置
开启中断
设置时钟
我的是 外部晶振为25MHz
项目文件设置
完成之后生成工程
我用的是STM32F4的芯片,RTC的时间都在HAL里面设置完成之后生成。
生成的代码段
时间日期设置
//闹钟和时间结构体用全局变量设置RTC_AlarmTypeDef sAlarm = {0};RTC_TimeTypeDef sTime = {0};
/* USER CODE END 0 */RTC_HandleTypeDef hrtc;/* RTC init function */
void MX_RTC_Init(void)
{/* USER CODE BEGIN RTC_Init 0 */HAL_LockTypeDef rtc_time={0};/* USER CODE END RTC_Init 0 */RTC_TimeTypeDef sTime = {0};RTC_DateTypeDef sDate = {0};RTC_AlarmTypeDef sAlarm = {0};/* USER CODE BEGIN RTC_Init 1 *//* USER CODE END RTC_Init 1 *//** Initialize RTC Only*/hrtc.Instance = RTC;hrtc.Init.HourFormat = RTC_HOURFORMAT_24;hrtc.Init.AsynchPrediv = 127;hrtc.Init.SynchPrediv = 255;hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;if (HAL_RTC_Init(&hrtc) != HAL_OK){Error_Handler();}/* USER CODE BEGIN Check_RTC_BKUP *//* USER CODE END Check_RTC_BKUP *//** Initialize RTC and set the Time and Date*/sTime.Hours = 12;sTime.Minutes = 12;sTime.Seconds = 0;sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;sTime.StoreOperation = RTC_STOREOPERATION_RESET;if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}sDate.WeekDay = RTC_WEEKDAY_MONDAY;sDate.Month = RTC_MONTH_JANUARY;sDate.Date = 1;sDate.Year = 0;if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}
闹钟和时间结构体用全局变量设置
闹钟时间设置
/** Enable the Alarm A*/sAlarm.AlarmTime.Hours = 12;sAlarm.AlarmTime.Minutes = 12;sAlarm.AlarmTime.Seconds = 10;sAlarm.AlarmTime.SubSeconds = 5;sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS|RTC_ALARMMASK_MINUTES;sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;sAlarm.AlarmDateWeekDay = 1;sAlarm.Alarm = RTC_ALARM_A;if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}
闹钟的配置有不懂的可以看下面的注释
/*** @brief RTC Alarm structure definition*/
typedef struct
{RTC_TimeTypeDef AlarmTime; //设置时间uint32_t AlarmMask; //闹钟掩码设置//RTC_ALARMMASK_NONE,闹钟比较时匹配所有比较项目,包括日期(日/星期)、时、分、秒,完全匹配才会产生闹钟中断/事件//RTC_ALARMMASK_DATEWEEKDAY,屏蔽日期(日/星期),闹钟比较时将不关心日期(日/星期)//RTC_ALARMMASK_HOURS,屏蔽时钟,闹钟比较时将不关心小时数//RTC_ALARMMASK_MINUTES,屏蔽分钟,闹钟比较时将不关心分钟数//RTC_ALARMMASK_SECONDS,屏蔽秒钟,闹钟比较时将不关心秒钟数//RTC_ALARMMASK_ALL,屏蔽所有,设置后将不会产生闹钟中断/事件uint32_t AlarmSubSecondMask; //亚秒掩码设置//在RTC_Alarm_Sub_Seconds_Masks_Definitions中设置亚秒匹配规则uint32_t AlarmDateWeekDaySel; //日期(日/星期)选择,此位只有当AlarmMask中不设置RTC_ALARMMASK_DATEWEEKDAY时才有效//RTC_ALARMDATEWEEKDAYSEL_DATE,选择匹配日期//RTC_ALARMDATEWEEKDAYSEL_WEEKDAY,选择匹配星期uint8_t AlarmDateWeekDay; //日期(日/星期)设置,此位只有当AlarmMask中不设置RTC_ALARMMASK_DATEWEEKDAY时才有效//如果AlarmDateWeekDaySel选择RTC_ALARMDATEWEEKDAYSEL_DATE,该值范围【1-31】,代表设置一个月当中的第几号//如果AlarmDateWeekDaySel选择RTC_ALARMDATEWEEKDAYSEL_WEEKDAY,该值范围在RTC_WeekDay_Definitions定义,代表设置一周当中的星期几uint32_t Alarm; //设置闹钟//RTC_ALARM_A,选择闹钟A//RTC_ALARM_B,选择闹钟B}RTC_AlarmTypeDef;
下一次闹钟时间
这里我建立了新的dev_rtc.c\dev_rtc.h文件,专门放中断和设置闹钟时间
闹钟中断函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{HAL_RTC_GetTime(hrtc,&sTime,RTC_FORMAT_BIN); // 获取当前时间 dev_wdt_feed(); sAlarm_flag=1;//闹钟标志位// 再次启动闹钟中断事件if (HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}HAL_RTC_SetAlarm_IT(hrtc,&sAlarm,RTC_FORMAT_BIN);}
中断不能放太多代码,“sAlarm_flag”作为一个标志位来闹钟事件来开启下一次闹钟时间
设置闹钟时间结构体
在dev_rtc.h里面建立闹钟时、分、秒结构体
/*定义闹钟时、分、秒结构体*/
typedef struct
{uint8_t Hourss;uint8_t Minutess;uint8_t Secondss;} nTime;
引用结构体的时候一定要在全局变量里面用
sAlarm_flag标志位不能放在第一个,不然会出现进入中断后标志位直接清零的现象,小编因为这个debug了好久。
设置闹钟时间
由于代码较长,看起来不美观,这里我是建立了函数来单独设置时间“dev_set_alarm_time”;在20一次闹钟(可以根据自己的需要设置,分钟闹的话就把秒钟去掉就好了)
/****************************************************************************
**Description: 设置闹钟时间
**Input parameters:
**Output parameters: 无
**Returned value: **Created by:
**Modified by:
**Remark: time_flag=1表示第二次闹钟时间
*****************************************************************************/
void dev_set_alarm_time(void)
{if(second_time_flag==1) 设置第二次闹钟时间,此标志位只进来一次{Time.Hourss=12;Time.Minutess=12;Time.Secondss=20;second_time_flag=0; }Time.Secondss+=20; //每20秒进入一次if(Time.Secondss>= 60){Time.Minutess+=1;if(Time.Minutess>=60){Time.Hourss+= 1;if(Time.Hourss >= 24){Time.Hourss = 0;}Time.Minutess= 0;}Time.Secondss= 0;}
}
进入下一次闹钟函数
/****************************************************************************
**Description: 闹钟函数
**Input parameters:
**Output parameters: 无
**Returned value: **Created by:
**Modified by:
**Remark: 闹钟掩码和日期选择是不可避免的
*****************************************************************************/void dev_rtc_alarm(void)
{if(sAlarm_flag==1)//收到闹钟标志位{HAL_RTC_GetTime(&hrtc,&sTime,RTC_FORMAT_BIN); // 获取当前时间 dev_set_alarm_time();//时间设置sAlarm.AlarmTime.Hours =Time.Hourss;sAlarm.AlarmTime.Minutes = Time.Minutess; sAlarm.AlarmTime.Seconds = Time.Secondss;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;if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}sAlarm_flag=0;//清除闹钟标志位dev_alarm_wdt_feed();//喂狗}}
开启闹钟
当下载代码后中断会自动开启第一次闹钟,而第二次和后面的闹钟在while(1)里面启用“dev_rtc_alarm()”函数就可以了
总体dev_rtc.c代码
#include "dev_wdt.h"
#include "dev_rtc.h"
#include "rtc.h"static s8 sAlarm_flag=0;//闹钟事件
static s8 second_time_flag=1;//第二次事件
extern RTC_AlarmTypeDef sAlarm ;//声明闹钟结构体
extern RTC_TimeTypeDef sTime ;//声明时间结构体
nTime Time;
/****************************************************************************
**Description: 闹钟函数
**Input parameters:
**Output parameters: 无
**Returned value: **Created by:
**Modified by:
**Remark: 闹钟掩码和日期选择是不可避免的
*****************************************************************************/void dev_rtc_alarm(void)
{dev_eeprom_read(SLEEP_FLAG_ADDR,&sAlarm_sleeps_flag,SLEEP_FLAG_LEN);if(sAlarm_flag==1)//收到闹钟标志位{HAL_RTC_GetTime(&hrtc,&sTime,RTC_FORMAT_BIN); // 获取当前时间 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;if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}sAlarm_flag=0;//清除闹钟标志位dev_alarm_wdt_feed();//喂狗}}
/****************************************************************************
**Description: 设置闹钟时间
**Input parameters:
**Output parameters: 无
**Returned value: **Created by:
**Modified by:
**Remark: time_flag=1表示第二次闹钟时间
*****************************************************************************/
void dev_set_alarm_time(void)
{if(second_time_flag==1) {Time.Hourss=12;Time.Minutess=12;Time.Secondss=20;second_time_flag=0; }Time.Secondss+=20; //每20秒进入一次if(Time.Secondss>= 60){Time.Minutess+=1;if(Time.Minutess>=60){Time.Hourss+= 1;if(Time.Hourss >= 24){Time.Hourss = 0;}Time.Minutess= 0;}Time.Secondss= 0;}sAlarm.AlarmTime.Hours =Time.Hourss;sAlarm.AlarmTime.Minutes = Time.Minutess; sAlarm.AlarmTime.Seconds = Time.Secondss;
}
/****************************************************************************
**Description: 喂狗且再次进入睡眠
**Input parameters:
**Output parameters: 无
**Returned value: **Created by:
**Modified by:
**Remark:
*****************************************************************************/
void dev_alarm_wdt_feed(void)
{dev_wdt_feed(); if(sAlarm_sleeps_flag==1){dev_charger_sleep();}
}/****************************************************************************
**Description: 闹钟中断函数
**Input parameters:
**Output parameters: 无
**Returned value: **Created by:
**Modified by:
**Remark:
*****************************************************************************/
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{HAL_RTC_GetTime(hrtc,&sTime,RTC_FORMAT_BIN); // 获取当前时间 dev_wdt_feed(); sAlarm_flag=1;//钟标志位闹// 再次启动闹钟中断事件if (HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}HAL_RTC_SetAlarm_IT(hrtc,&sAlarm,RTC_FORMAT_BIN);}
实验现象
我用的是debug调试
下面是两次闹钟现象
以上就是小编针对RTC闹钟得出的结果,写得不好还请多多包涵!!!
STM32HAL库RTC闹钟事件相关推荐
- STM32F030的低功耗案例(RTC闹钟中断定时唤醒喂狗+按键外部中断唤醒)
最近使用到低功耗方案,采用的是STM32F030C8T6芯片,由于任务开启了看门狗,进入休眠后(采用的是STOP模式),需要及时喂狗,故而使用RTC闹钟中断定时唤醒来喂狗. 对比三种休眠模式:就设备的 ...
- stm32hal库使用RTC时PC13作为普通GPIO注意事项
stm32hal库使用RTC时PC13作为普通GPIO注意事项 问题现象 现象分析 问题解决 问题现象 做项目采用STM32L4系列,为了方便PCB布板,使用PC13作为电源控制管脚,项目初期未进行B ...
- STM32HAL库GPIO和EXTI
STM32HAL库 GPIO STM32芯片最多拥有7组端口(GPIOA-GPIOG),每组端口最多有用16个引脚(Pin0-Pin15) STM32的每个I/O端口都可以自由编程,但I/O端口寄存器 ...
- GD32F4—RTC闹钟及自动唤醒中断配置详解
GD32F4-RTC闹钟及自动唤醒中断配置详解 一.简介 二.框图 三.RTC 初始化和配置 一.简介 GD32F4x的RTC例程网上资源较少,详细阅读用户手册后做出如下配置.RTC模块提供了一个包含 ...
- STM32CubeMX(stm32F030C8T6) 之RTC闹钟唤醒停机模式-STM32开发实战 (2)
一.概述 本例程是用STOP休眠模式,用RTC的周期性自动唤醒功能来唤醒芯片. 根据手册的说明:这里有个可编程的可自动重装的向下计数器,按照相应的时钟频率赋予适当的值,每当向下计数到0时便产生一个唤醒 ...
- STM32HAL库电子广告牌显示广告+温湿度+时间设置
STM32HAL库电子广告牌显示广告+温湿度+时间 概述 第一天进度 材料采购 1.新建KEIL工程 2.软件编写 第二天进度 1.开始接线 2.开始调试 总结 概述 电子广告牌多用于显示一些简短的信 ...
- RTC闹钟和ELAPSED_REALTIME最大的差别
AlarmManager.RTC,硬件闹钟,不唤醒手机(也可能是其它设备)休眠:当手机休眠时不发射闹钟. AlarmManager.RTC_WAKEUP,硬件闹钟,当闹钟发躰时唤醒手机休眠: Alar ...
- STM32:RTC闹钟唤醒
想使用闹钟唤醒功能使系统从待机下唤醒,遇到一个问题:使用闹钟唤醒就不能使用wakeup pin唤醒.二者只能取其一. 此问题解决,画了个板子wakeup pin 接下拉电阻解决. 写新代码时候遇到一个 ...
- CM3计算板RTC闹钟唤醒系统
1.前言 一个周期性控制系统的核心为CM3计算板,在电池供电情况下要求尽可能提高使用时长.由于系统空闲时长较多,因此在考虑低功耗的情况下将系统关机以进一步降低功耗.需要注意的是,系统关机后需要在指定时 ...
最新文章
- 浅谈本地文件包含利用
- javarxtx串口接收时数据会分成好几段_【STM32】串口通信基本原理(超基础、详细版)...
- [python] 之all()和any()内置函数
- mnist 0与mnist x 相互衰变半衰期汇总
- 解压缩文件命令linux
- Android开发之RecyclerView之刷新数据notifyDataSetChanged失败的问题
- MySQL+Amoeba实现数据库主从复制和读写分离
- 193. 有效电话号码
- React 深入系列4:组件的生命周期
- 从一张表里选择一列加入到另一张表_将Excel多个文件汇总到一张表
- Java程序员从笨鸟到菜鸟之(四十八)细谈struts2(十)ognl概念和原理详解
- python期末考试及答案广东_PYTHON语言应用答案试题题目及答案,期末考试题库,章节测验答案...
- 文件夹病毒残余文件的解决办法
- SAP UI5 应用开发教程之六十一 - 在 SAP UI5 应用里绘制甘特图 Gantt Chart 试读版
- PG数据库创建视图并授权给新用户
- 智慧消防:如何利用智能化手段,精准防控消防风险?
- Axure可视化原型模板+大数据图表组件 提升您的设计效率 做出甲方买不起的样子
- 《徐志摩传》记得也好,最好你忘掉
- CodeForces 372 A. Counting Kangaroos is Fun
- 回撤率 python_最大回撤用python怎么计算
热门文章
- 轻量级网络综述 — 主干网络篇
- 2017年携程旅游校招Java研发笔试编程题(3个)
- matlab ax=b x=,matlab 求解 Ax=B 时所用算法
- Mockplus走进四川师范大学
- 企业——nginx的图片压缩、https模块、重写规则、盗链
- Ubuntu 20.4 美化桌面、美化引导界面、Mac 既视感
- 一份非常完整的 MySQL 规范非原创(ps:我怕论坛会删掉 自己拿来用了)
- 中国卫生材料及医药用品行业发展前景与投资战略规划分析报告2022-2028年
- pd.read_csv()中文乱码,解决方法
- C#连接mysql数据库实现登陆注册界面【小白教程】