细说STM32F407单片机RTC入侵检测和时间戳的原理及使用方法
目录
一、入侵检测的功能
二、示例功能
三、项目设置
1、晶振、DEBUG、CodeGenerator、USART6、KEYLED
2、RTC
(1)设置RTC的模式。
(2)General、Time、Date\Wake Up分组
(3)Tamper分组
1)Filter,滤波
2)Sampling Frequency,输入引脚RTC_AF1的采样频率
3)Precharge Duration,预充电时间
4)Tamper Pull Up,是否对输入引脚使用内部上拉
5)Time Stamp On Tamper Detection,是否保存时间戳
6)Tamper 1 Trigger,有效触发事件类型
3、NVIC
4、GPIO
四、软件设计
1、keyled.c、keyled.h
2、main.h
3、main.c
五、运行调试
本文将通过示例介绍 STM32单片机RTC时钟单元的的入侵检测和时间戳的原理及使用方法。本文将继续使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。本实例将引用本文作者写的其他文章作为参考文献。
参考文章1:细说STM32F407单片机RTC的基本原理及闹钟和周期唤醒功能的使用方法-CSDN博客 https://wenchm.blog.csdn.net/article/details/145575366
参考文章2:细说STM32F407单片机RTC的备份寄存器原理及使用方法-CSDN博客 https://wenchm.blog.csdn.net/article/details/145593205
一、入侵检测的功能
入侵检测和时间戳的HAL驱动程序头文件是stm32f4xx_hal_rtc_ex.h。RTC上有两个入侵检测模块,用Tamper1和Tamper2表示。当发生入侵事件时,如果开启了时间戳功能,就会记录时间戳数据,所以入侵检测通常是和时间戳一起使用的。
常用的入侵检测和时间戳HAL函数如下表所示,其他函数见文件stm32f4xx_hal_rtc_ex.h中的定义。入侵检测和时间戳共用一个中断号,3个中断事件对应表中的3个回调函数。
| 函数名 | 功能 |
| __HAL_RTC_TAMPER1_DISABLE() | 禁用Tamper1 |
| __HAL_RTC_TAMPER1_ENABLE() | 启用Tamper1 |
| __HAL_RTC_TAMPER2_DISABLE() | 禁用Tamper2 |
| __HAL_RTC_TAMPER2_ENABLE() | 启用Tamper2 |
| __HAL_RTC_TIMESTAMP_DISABLE() | 禁用时间戳外设 |
| __HAL_RTC_TIMESTAMP_ENABLE() | 启用时间戳外设 |
| __HAL_RTC_TIMESTAMP_DISABLE_IT() | 禁止时间戳事件产生硬件中断,时间戳中断事件类型是RTC_IT_TS |
| __HAL_RTC_TIMESTAMP_ENABLE_IT() | 允许时间戳事件产生硬件中断,时间戳中断事件类型是RTC_IT_TS |
| HAL_RTCEx_GetTimeStamp() | 读取时间戳的数据 |
| HAL_RTCEx_Tamper1EventCallback() | Tamper1的中断事件回调函数 |
| HAL_RTCEx_Tamper2EventCallback() | Tamper2的中断事件回调函数 |
| HAL_RTCEx_TimeStampEventCallback() | 时间戳中断事件回调函数 |
发生入侵事件时,RTC的20个备份寄存器的内容会被清零,时间戳寄存器保存发生入侵事件时的时间。用函数HAL_RTCEx_GetTimeStamp()可以读取出保存的时间戳数据,其函数原型如下:
HAL_StatusTypeDef HAL_RTCEx_GetTimeStamp(RTC_HandleTypeDef *hrtc,RTC_TimeTypeDef*TimeStamp,RTC_DateTypeDef *sTimeStampDate,uint32_t Format);
其中,参数sTimeStamp返回时间数据的指针,sTimeStampDate返回日期数据的指针,Format省定二进制或BCD码格式。
二、示例功能
将复用引脚RTC_AF1(即引脚PC13)作为Tamper1输入引脚,在输入引脚发生边沿事件(无滤波时是边沿事件)或所需电平(有输入滤波时是电平检测)时,触发入侵事件中断,并自动将RTC的20个备份寄存器复位,自动记录入侵事件发生时刻的时间戳数据。
使用开发板上的按键制造入侵事件,用杜邦线连接引PC13和PF6。PC13是RTC的复用引脚RTC_AF1,PF6是KeyRight按键接入MCU的引脚。设置PC13内部上拉,KeyRight按下后是低电平,入侵检测设置为低电平有效,那么按建KeyRight按下后就会产生入侵事件。在实际调试中,要注意按建抖动的影响。
本文示例用于测试入侵检测功能。
- 采用1s周期的唤醒中断,在唤醒中断里读取RTC时间后显示。
- 可将RTC当前时间保存到备份寄存器。
- 可以读取备份寄存器中保存的时间数据并显示。
- 按下KeyRight键时产生入侵事件,看备份寄存器内容是否被复位。
- 菜单设计:
//菜单设计
[S2]KeyUp = Save time to BKUP //LED2 ON.
[S3]KeyDown = Read BKUP registers //LED3 ON.
[S5]KeyRight= Trigger tamper event //LED1 Flashing.
三、项目设置
1、晶振、DEBUG、CodeGenerator、USART6、KEYLED
与参考文章2相同。
2、RTC
(1)设置RTC的模式。
禁用闹钟A和闹钟B,启用Tamper1,并且使用复用引脚RTC_AF1作为入侵事件输入引脚。启用周期唤醒功能,设置为Internal WakeUp。


(2)General、Time、Date\Wake Up分组
参数设置和参考项目2的示例相同。
(3)Tamper分组
1)Filter,滤波
当选择为Disable时,禁用滤波。禁用滤波时,下面的Tamper 1 Trigger参数只能是边沿触发。使用滤波时,Tamper 1 Trigger只能是电平触发。
如果使用滤波,可选项为Tamper activated after 2 consecutive samples、Tamper activated after 4 consecutive samples和Tamper activated after 8 consecutive samples,即经过2、4或8个连续采样都是所设置的触发电平时,才确认产生入侵事件。带滤波的方式适用于按键抖动时的检测,相当于有一定的消抖作用。
2)Sampling Frequency,输入引脚RTC_AF1的采样频率
采样频率设置为RCCCLK的分频,分频系数为32768~256,且只能是2N。例如,当RCCCLK是32.768kHz时,分频系数设置为512,则采样频率为64Hz。又将滤波参数设置为连续4个采样信号有效,则需要电平持续时间为4/64s,即62.5ms。这个时间差不多是按键按下或释放时的抖动阶段时间,所以有一定的消除按键抖动影响的作用。
3)Precharge Duration,预充电时间
可选择为1、2、4或8个RTCCLK周期,这是每次采样之前激活上拉的持续时间。
4)Tamper Pull Up,是否对输入引脚使用内部上拉
可选Enable或Disable。因为按键输入是低有效,所以需要设置为上拉。
5)Time Stamp On Tamper Detection,是否保存时间戳
设置在发生入侵事件时是否保存时间戳数据,这里设置为保存,即Time Stamp on Tamper Detection event saved。
6)Tamper 1 Trigger,有效触发事件类型
当Filter参数设置为Disable时,有效事件为边沿触发,可选项为Rising Edge(上跳沿)和Falling Edge(下跳沿)。当Filter参数设置为Enable时,使用滤波,有效事件为电平触发,可选项为Low Level(低电平)和High Level(高电平)。本示例使用了滤波,且按键按下时输入是低电平,所以选择Low Level。
3、NVIC

启用RTC入侵检测和时间戳中断,启用RTC周期唤醒中断。在NVIC组件中将这两个中断的抢占优先级都设置为1。将这两个中断的抢占优先级设置为相同的,是为了避免它们之间发生抢占,导致串口显示出现混乱。
4、GPIO
本示例要用到3个按键,将与KeyRight连接的GPIO引脚PF6复位成原始状态,其他按键和LED的GPIO设置与参考文章2相同。

四、软件设计
1、keyled.c、keyled.h
与参考文章2相同。
2、main.h
/* USER CODE BEGIN Private defines */
void RTC_SaveToBKUP();
void RTC_ReadBKUP();
/* USER CODE END Private defines */
3、main.c
/* USER CODE BEGIN Includes */
#include "keyled.h"
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
uint8_t RTC_isReading=0;
/* USER CODE END PV */
/* USER CODE BEGIN 2 */__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc); //禁止RTC周期唤醒printf("Demo11_3_RTC_Tamper:RTC tamper and timestamp.\r\n");printf("Please connect PF6 and PC13 by line.\r\n");printf("KeyRight simulate tamper event.\r\n\r\n");/* USER CODE END 2 */
/* Infinite loop *//* USER CODE BEGIN WHILE *///菜单设计printf("[S2]KeyUp = Save time to BKUP,LED2 ON.\r\n");printf("[S3]KeyDown = Read BKUP registers,LED3 ON.\r\n");printf("[S5]KeyRight= Trigger tamper event,LED1 Flashing.\r\n\r\n");__HAL_RTC_WAKEUPTIMER_ENABLE(&hrtc); //启用RTC周期唤醒while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */KEYS curKey=ScanPressedKey(KEY_WAIT_ALWAYS);switch(curKey){case KEY_UP: //[S2]KeyUp = Save time to BKUPRTC_SaveToBKUP();break;case KEY_DOWN: //[S3]KeyDown = Read BKUP registersRTC_ReadBKUP();break;default:break;}HAL_Delay(300); //消除按键后抖动的影响}/* USER CODE END 3 */
在main()函数里,执行MX_RTC_Init()后立刻执行__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc)禁止了RTC周期唤醒功能,在进入while循环之前,重新开启了RTC周期唤醒功能。
while循环里检测按键并执行响应代码。只有KeyUp键和KeyDown键是执行菜单选项,KeyRight用于产生RTC入侵事件。KeyUp键按下时,调用函数RTC_SaveToBKUP(),用于将RTC当前时间写入备份寄存器;KeyDown键按下时,调用函数RTC_ReadBKUP(),用于读取备份寄存器中的数据并在串口助手上显示。这两个按键的功能是测试入侵事件发生后备份寄存器的内容是否被复位。
/* USER CODE BEGIN 4 */
//周期唤醒中断回调函数
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{LED1_Toggle();RTC_isReading=1;if (HAL_RTC_GetTime(hrtc,&sTime,RTC_FORMAT_BIN) == HAL_OK){//调用HAL_RTC_GetTime()之后必须调用HAL_RTC_GetDate()以解锁数据,才能连续更新日期和时间HAL_RTC_GetDate(hrtc,&sDate,RTC_FORMAT_BIN);RTC_isReading=0;//显示时间hh:mm:sschar str[40];sprintf(str,"RTC WakeUp Time = %2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);printf(" %s\r\n",str);}
}/* 入侵和时间戳事件回调函数 */
void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)
{printf("Tamper1 is triggered and all BKUP-Regs are cleared.\r\n");RTC_TimeTypeDef time;RTC_DateTypeDef date;if (HAL_RTCEx_GetTimeStamp(hrtc,&time,&date,RTC_FORMAT_BIN) == HAL_OK){//显示时间hh:mm:sschar str[40];sprintf(str,"RTC Tamper1 Time = %2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds);printf(" %s\r\n",str);}
}/* 保存RTC时间到备份寄存器 */
void RTC_SaveToBKUP()
{LED2_ON();while(RTC_isReading)HAL_Delay(1);HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR2, sTime.Hours);HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR3, sTime.Minutes);HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR4, sTime.Seconds);char timeStr[30];sprintf(timeStr,"%2d:%2d:%2d",sTime.Hours,sTime.Minutes,sTime.Seconds); //转换为字符串,自动添加"\0"printf("Time %s is saved in BKUP.\r\n",timeStr);HAL_Delay(5000);LED2_OFF();
}void RTC_ReadBKUP()
{LED3_ON();uint32_t regValue;char regStr[40];regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2); //Hoursprintf(regStr,"Saved time(Hour) ,BKP_DR2= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3); //Minutesprintf(regStr,"Saved time(Min) , BKP_DR3= %lu",regValue);printf(" %s\r\n",regStr);regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4); //Secondsprintf(regStr,"Saved time(Sec) , BKP_DR4= %lu",regValue);printf(" %s\r\n",regStr);HAL_Delay(5000);LED3_OFF();
}//串口打印
int __io_putchar(int ch)
{HAL_UART_Transmit(&huart6,(uint8_t*)&ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */
Tamper1事件中断回调函数的主要功能就是调用函数HAL_RTCEx_GetTimeStamp()读取时间戳数据,然后在串口助手上显示这个时间。程序运行时,按下KeyRight键就会触发入侵事件,并在串口助手上显示相应的的信息。
五、运行调试
首次下载或S6键复位后,在串口助手上显示功能菜单。

正常情况下不按任何键,连续显示中断唤醒RTC时间,1秒1次。当按下S5键,切换显示入侵RTC时间。 然后恢复显示中断唤醒RTC时间。LED1闪烁。

按S2键,存储当前RTC时间到备份寄存器,LED2亮;按S3键,读取备份寄存器RTC时间,LED3亮。

相关文章:
细说STM32F407单片机RTC入侵检测和时间戳的原理及使用方法
目录 一、入侵检测的功能 二、示例功能 三、项目设置 1、晶振、DEBUG、CodeGenerator、USART6、KEYLED 2、RTC (1)设置RTC的模式。 (2)General、Time、Date\Wake Up分组 (3)Tamper分组 1ÿ…...
STM32 CAN过滤器配置和应用方法介绍
目录 概述 一、CAN过滤器核心概念 二、过滤器配置步骤(以标准ID为例) 三、不同模式的配置示例 四、高级配置技巧 五、调试与问题排查 六、关键计算公式 总结 概述 在STM32微控制器中,CAN过滤器可以配置为标识符屏蔽模式和标识符列表模…...
搜狗浏览器卸载教程
需求背景 今天发现geek居然无法卸载搜狗浏览器,作为一个老司机,这是不允许的。如果你使用geek或者windows的卸载,或者直接在它的安装包的Uninstall.exe中卸载,他走到100%就一直不动了。那玩意是假的。 卸载教程 结束 -----华丽的…...
Go 模块管理工具 `go mod tidy` 和 `go.sum` 文件详解
Go 模块管理工具 go mod tidy 和 go.sum 文件详解 引言 Go 语言自引入模块(module)系统以来,极大地简化了依赖管理和版本控制。go mod tidy 和 go.sum 文件是 Go 模块系统中的两个重要组成部分,它们共同确保项目的依赖项是最新的…...
音视频入门基础:RTP专题(9)——FFmpeg接收RTP流的原理和内部实现
一、引言 由《音视频入门基础:RTP专题(2)——使用FFmpeg命令生成RTP流》可以知道,推流端通过下面FFmpeg命令可以将一个媒体文件转推RTP,生成RTP流: ffmpeg -re -stream_loop -1 -i input.mp4 -vcodec cop…...
STM32 串口转 虚拟串口---实现USB转串口功能
一,USART与UART 区别 USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步串行接收/发送器 相较于UART:通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)多了…...
【进程与线程】Linux 线程、同步以及互斥
每个用户进程有自己的地址空间。 线程是操作系统与多线程编程的基础知识。 系统为每个用户进程创建一个 task_struct 来描述该进程:该结构体中包含了一个指针指向该进程的虚拟地址空间映射表: 实际上 task_struct 和地址空间映射表一起用来表示一个进程…...
胶囊网络动态路由算法:突破CNN空间局限性的数学原理与工程实践
一、CNN的空间局限性痛点解析 传统CNN的瓶颈: 池化操作导致空间信息丢失(最大池化丢弃85%激活值)无法建模层次空间关系(旋转/平移等变换不敏感)局部感受野限制全局特征整合 示例对比: # CNN最大池化示例…...
当pcie设备变化时centos是否会修改网络设备的名称(AI回答)
当pcie设备变化时centos是否会修改网络设备的名称 在CentOS(以及其他基于Linux的操作系统)中,网络接口的命名通常遵循特定的规则,尤其是在使用PCIe设备(如网络适配器)时。网络接口的命名通常基于设备的物理…...
【人工智能】释放数据潜能:使用Featuretools进行自动化特征工程
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 特征工程是机器学习流程中至关重要的一步,它直接影响模型的性能。然而,手动特征工程既耗时又需要领域专业知识。Featuretools是一个强大的…...
docker批量pull/save/load/tag/push镜像shell脚本
目录 注意: 脚本内容 执行效果 注意: 以下脚本为shell脚本通过docker/nerdctl进行镜像独立打包镜像的相关操作脚本内仓库信息和镜像存取路径需自行更改需自行创建images.txt并填写值,并且与脚本位于同级目录下 [rootmaster01 sulibao]# l…...
对正则表达式说不!!!
可能大家都会和我一样,时常会遇到正则表达式,有时候会忘记某些字符而苦恼。今天就帮助大家克服它,虽然不多,但我认为掌握这些足够了,万变不离其宗,以不变应万变。 一、正则表达式内容分类 1. 字符类 [abc…...
Redis日志分析
主从同步尝试: 日志中多次出现“Master is currently unable to PSYNC but should be in the future: -NOMASTERLINK Can’t SYNC while not connected with my master”。这表明从服务器尝试与主服务器进行部分重同步(PSYNC),但由…...
【做一个微信小程序】校园地图页面实现
前言 上一个教程我们实现了小程序的一些的功能,有背景渐变色,发布功能有的呢,已支持图片上传功能,表情和投票功能开发中(请期待)。下面是一个更高级的微信小程序实现,包含以下功能:…...
Web后端 - Maven管理工具
一 Maven简单介绍 Maven是apache旗下的一个开源项目,是一款用于管理和构建java项目的工具。 Maven的作用 二 Maven 安装配置 依赖配置 依赖传递 依赖范围 生命周期 注意事项:在同一套生命周期中,当运行后面的阶段时,前面的阶段都…...
20250217-POMO笔记
文章目录 前言一、伪代码一:POMO Training二、伪代码二:POMO Inference三、POMO注意力模型3.1、自注意力机制3.2、AM模型 前言 以下主要讲解两个算法的伪代码以及注意力模型。 一、伪代码一:POMO Training POMO Training是POMO模型训练的伪…...
JavaEE-SpringBoot快速入门
文章目录 本节目标Maven什么是Maven创建一个Maven项目maven项目功能maven的依赖管理全球仓库, 私服, 本地服务器, 配置国内镜像 第一个SpringBoot项目创建项目运行SpringBoot程序 SpringBoot原理初步Web服务器 总结 本节目标 了解什么是maven, 配置国内源使用Springboot创建项…...
游戏引擎学习第107天
仓库:https://gitee.com/mrxiao_com/2d_game_2 回顾我们之前停留的位置 在这段内容中,讨论了如何处理游戏中的三维效果,特别是如何处理额外的“Z层”。由于游戏中的艺术资源是位图而不是3D模型,因此实现三维效果变得非常具有挑战性。虽然可…...
Sprinig源码解析
前言 Spring 框架是 Java 企业级开发的基石,其源码设计体现了模块化、扩展性和灵活性。以下从 IoC 容器、AOP 实现、核心模块和关键设计模式四个角度对 Spring 源码进行深度解析,帮助理解其底层机制。即使Spring会使用的人见得就能使用。 一、IoC 容器源…...
ComfyUI流程图生图原理详解
一、引言 ComfyUI 是一款功能强大的工具,在图像生成等领域有着广泛应用。本文补充一点ComfyUI 的安装与配置过程遇到的问题,并深入剖析图生图过程及相关参数,帮助读者快速入门并深入理解其原理。 二、ComfyUI 的安装与配置中遇到的问题 &a…...
使用右侧值现象来处理一个word导入登记表的需求
需求也简单,导word文件用户登记表,有各部门的十几个版本(为什么这么多?不知道)。这里说下谈下我的一些代码做法: 需求分析: 如果能解决java字段和各项填的值怎么配对的问题,那么就…...
《open3d pyqt》Alpha重建
《open3d pyqt》Alpha重建 一、效果展示二、qt设置2.1 主界面添加动作2.2 dialog 界面、布局如下:三、核心代码一、效果展示 二、qt设置 2.1 主界面添加动作 2.2 dialog 界面、布局如下: 并生成py文件,参考前述章节 三、核心代码 main.py文件增加 from Su...
深度解析HTTP/HTTPS协议:从原理到实践
深入浅出HTTP/HTTPS协议:从原理到实践 前言 在当今互联网世界中,HTTP和HTTPS协议如同空气般存在于每个网页请求的背后。作为开发者或技术爱好者,理解这些基础协议至关重要。本文将用六大板块,配合原理示意图和实操案例࿰…...
数据结构:顺序表(Sequence List)及其实现
什么是顺序表? 顺序表是一种最简单的数据结构,它就像一排连续的小房子,每个房子里都住着一个数据元素。这些房子是按顺序排列的,每个房子都有一个门牌号(下标),我们可以通过门牌号快速找到对应…...
小程序canvas2d实现横版全屏和竖版逐字的签名组件(字帖式米字格签名组件)
文章标题 01 功能说明02 效果预览2.1 横版2.2 竖版 03 使用方式04 横向签名组件源码4.1 html 代码4.2 业务 Js4.3 样式 Css 05 竖向签名组件源码5.1 布局 Html5.2 业务 Js5.3 样式 Css 01 功能说明 技术栈:uniapp、vue、canvas 2d 需求: 实现横版的全…...
MoE演变过程
MoE演变过程 1 MoE1.1 BasicMoE1.2 SparseMoE1.2.1 实现 1.3 Shared Expert SparseMoE 1 MoE 参考:https://huggingface.co/blog/zh/moe 1.1 BasicMoE 用router给出各专家的权重,然后让输入过每一个专家,然后做加权求和。 1.2 SparseMoE …...
【Leetcode 热题 100】1287. 有序数组中出现次数超过25%的元素
问题背景 给你一个非递减的 有序 整数数组,已知这个数组中恰好有一个整数,它的出现次数超过数组元素总数的 25 % 25\% 25%。 请你找到并返回这个整数。 数据约束 1 ≤ a r r . l e n g t h ≤ 1 0 4 1 \le arr.length \le 10 ^ 4 1≤arr.length≤104 0…...
ruby 的安装
在51cto搜索的资料 ruby on rails的安装 http://developer.51cto.com/art/200906/129669.htm http://developer.51cto.com/art/200912/169391.htm http://developer.51cto.com/art/200908/147276.htm 史上最完整的ruby,rails环境架设配置(Apachefast…...
【java】List<String> fruits = new ArrayList<>(); 这一句是什么
1. 代码分解 java Copy List<String> fruits new ArrayList<>(); List<String>: List 是 Java 中的一个接口,表示一个有序的集合(可以重复元素)。 <String> 是泛型,表示这个列表中的元素…...
通俗诠释 DeepSeek-V3 模型的 “671B” ,“37B”与 “128K”,用生活比喻帮你理解模型的秘密!
欢迎来到涛涛聊AI。 在DeepSeek-V3模型的参数描述中,你可能会看到类似“671B 37B 128K”这样的标记。这些字母和数字的组合看起来像密码,但其实它们揭示了模型的“大脑容量”和“工作方式”。我们用日常生活的比喻来解释: 一、数字含义&…...
