最近遇到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闹钟事件相关推荐

  1. STM32F030的低功耗案例(RTC闹钟中断定时唤醒喂狗+按键外部中断唤醒)

    最近使用到低功耗方案,采用的是STM32F030C8T6芯片,由于任务开启了看门狗,进入休眠后(采用的是STOP模式),需要及时喂狗,故而使用RTC闹钟中断定时唤醒来喂狗. 对比三种休眠模式:就设备的 ...

  2. stm32hal库使用RTC时PC13作为普通GPIO注意事项

    stm32hal库使用RTC时PC13作为普通GPIO注意事项 问题现象 现象分析 问题解决 问题现象 做项目采用STM32L4系列,为了方便PCB布板,使用PC13作为电源控制管脚,项目初期未进行B ...

  3. STM32HAL库GPIO和EXTI

    STM32HAL库 GPIO STM32芯片最多拥有7组端口(GPIOA-GPIOG),每组端口最多有用16个引脚(Pin0-Pin15) STM32的每个I/O端口都可以自由编程,但I/O端口寄存器 ...

  4. GD32F4—RTC闹钟及自动唤醒中断配置详解

    GD32F4-RTC闹钟及自动唤醒中断配置详解 一.简介 二.框图 三.RTC 初始化和配置 一.简介 GD32F4x的RTC例程网上资源较少,详细阅读用户手册后做出如下配置.RTC模块提供了一个包含 ...

  5. STM32CubeMX(stm32F030C8T6) 之RTC闹钟唤醒停机模式-STM32开发实战 (2)

    一.概述 本例程是用STOP休眠模式,用RTC的周期性自动唤醒功能来唤醒芯片. 根据手册的说明:这里有个可编程的可自动重装的向下计数器,按照相应的时钟频率赋予适当的值,每当向下计数到0时便产生一个唤醒 ...

  6. STM32HAL库电子广告牌显示广告+温湿度+时间设置

    STM32HAL库电子广告牌显示广告+温湿度+时间 概述 第一天进度 材料采购 1.新建KEIL工程 2.软件编写 第二天进度 1.开始接线 2.开始调试 总结 概述 电子广告牌多用于显示一些简短的信 ...

  7. RTC闹钟和ELAPSED_REALTIME最大的差别

    AlarmManager.RTC,硬件闹钟,不唤醒手机(也可能是其它设备)休眠:当手机休眠时不发射闹钟. AlarmManager.RTC_WAKEUP,硬件闹钟,当闹钟发躰时唤醒手机休眠: Alar ...

  8. STM32:RTC闹钟唤醒

    想使用闹钟唤醒功能使系统从待机下唤醒,遇到一个问题:使用闹钟唤醒就不能使用wakeup pin唤醒.二者只能取其一. 此问题解决,画了个板子wakeup pin 接下拉电阻解决. 写新代码时候遇到一个 ...

  9. CM3计算板RTC闹钟唤醒系统

    1.前言 一个周期性控制系统的核心为CM3计算板,在电池供电情况下要求尽可能提高使用时长.由于系统空闲时长较多,因此在考虑低功耗的情况下将系统关机以进一步降低功耗.需要注意的是,系统关机后需要在指定时 ...

最新文章

  1. 浅谈本地文件包含利用
  2. javarxtx串口接收时数据会分成好几段_【STM32】串口通信基本原理(超基础、详细版)...
  3. [python] 之all()和any()内置函数
  4. mnist 0与mnist x 相互衰变半衰期汇总
  5. 解压缩文件命令linux
  6. Android开发之RecyclerView之刷新数据notifyDataSetChanged失败的问题
  7. MySQL+Amoeba实现数据库主从复制和读写分离
  8. 193. 有效电话号码
  9. React 深入系列4:组件的生命周期
  10. 从一张表里选择一列加入到另一张表_将Excel多个文件汇总到一张表
  11. Java程序员从笨鸟到菜鸟之(四十八)细谈struts2(十)ognl概念和原理详解
  12. python期末考试及答案广东_PYTHON语言应用答案试题题目及答案,期末考试题库,章节测验答案...
  13. 文件夹病毒残余文件的解决办法
  14. SAP UI5 应用开发教程之六十一 - 在 SAP UI5 应用里绘制甘特图 Gantt Chart 试读版
  15. PG数据库创建视图并授权给新用户
  16. 智慧消防:如何利用智能化手段,精准防控消防风险?
  17. Axure可视化原型模板+大数据图表组件 提升您的设计效率 做出甲方买不起的样子
  18. 《徐志摩传》记得也好,最好你忘掉
  19. CodeForces 372 A. Counting Kangaroos is Fun
  20. 回撤率 python_最大回撤用python怎么计算

热门文章

  1. 轻量级网络综述 — 主干网络篇
  2. 2017年携程旅游校招Java研发笔试编程题(3个)
  3. matlab ax=b x=,matlab 求解 Ax=B 时所用算法
  4. Mockplus走进四川师范大学
  5. 企业——nginx的图片压缩、https模块、重写规则、盗链
  6. Ubuntu 20.4 美化桌面、美化引导界面、Mac 既视感
  7. 一份非常完整的 MySQL 规范非原创(ps:我怕论坛会删掉 自己拿来用了)
  8. 中国卫生材料及医药用品行业发展前景与投资战略规划分析报告2022-2028年
  9. pd.read_csv()中文乱码,解决方法
  10. C#连接mysql数据库实现登陆注册界面【小白教程】