细说STM32F407单片机RTC入侵检测和时间戳的原理及使用方法

news2025/3/13 11:26:41

目录

一、入侵检测的功能

二、示例功能

三、项目设置

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 BKUP
	  		  RTC_SaveToBKUP();
	  		  break;

	  	  case KEY_DOWN:  //[S3]KeyDown = Read BKUP registers
	  		  RTC_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:ss
		char 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:ss
		char 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);	//Hour
	sprintf(regStr,"Saved time(Hour) ,BKP_DR2= %lu",regValue);
	printf(" %s\r\n",regStr);

	regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);	//Minute
	sprintf(regStr,"Saved time(Min) , BKP_DR3= %lu",regValue);
	printf(" %s\r\n",regStr);

	regValue=HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);	//Second
	sprintf(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亮。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2300445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搜狗浏览器卸载教程

需求背景 今天发现geek居然无法卸载搜狗浏览器&#xff0c;作为一个老司机&#xff0c;这是不允许的。如果你使用geek或者windows的卸载&#xff0c;或者直接在它的安装包的Uninstall.exe中卸载&#xff0c;他走到100%就一直不动了。那玩意是假的。 卸载教程 结束 -----华丽的…

音视频入门基础:RTP专题(9)——FFmpeg接收RTP流的原理和内部实现

一、引言 由《音视频入门基础&#xff1a;RTP专题&#xff08;2&#xff09;——使用FFmpeg命令生成RTP流》可以知道&#xff0c;推流端通过下面FFmpeg命令可以将一个媒体文件转推RTP&#xff0c;生成RTP流&#xff1a; ffmpeg -re -stream_loop -1 -i input.mp4 -vcodec cop…

STM32 串口转 虚拟串口---实现USB转串口功能

一&#xff0c;USART与UART 区别 USART&#xff08;Universal Synchronous/Asynchronous Receiver/Transmitter&#xff09;通用同步/异步串行接收/发送器 相较于UART&#xff1a;通用异步收发传输器&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;多了…

【进程与线程】Linux 线程、同步以及互斥

每个用户进程有自己的地址空间。 线程是操作系统与多线程编程的基础知识。 系统为每个用户进程创建一个 task_struct 来描述该进程&#xff1a;该结构体中包含了一个指针指向该进程的虚拟地址空间映射表&#xff1a; 实际上 task_struct 和地址空间映射表一起用来表示一个进程…

胶囊网络动态路由算法:突破CNN空间局限性的数学原理与工程实践

一、CNN的空间局限性痛点解析 传统CNN的瓶颈&#xff1a; 池化操作导致空间信息丢失&#xff08;最大池化丢弃85%激活值&#xff09;无法建模层次空间关系&#xff08;旋转/平移等变换不敏感&#xff09;局部感受野限制全局特征整合 示例对比&#xff1a; # CNN最大池化示例…

当pcie设备变化时centos是否会修改网络设备的名称(AI回答)

当pcie设备变化时centos是否会修改网络设备的名称 在CentOS&#xff08;以及其他基于Linux的操作系统&#xff09;中&#xff0c;网络接口的命名通常遵循特定的规则&#xff0c;尤其是在使用PCIe设备&#xff08;如网络适配器&#xff09;时。网络接口的命名通常基于设备的物理…

【做一个微信小程序】校园地图页面实现

前言 上一个教程我们实现了小程序的一些的功能&#xff0c;有背景渐变色&#xff0c;发布功能有的呢&#xff0c;已支持图片上传功能&#xff0c;表情和投票功能开发中&#xff08;请期待&#xff09;。下面是一个更高级的微信小程序实现&#xff0c;包含以下功能&#xff1a;…

Web后端 - Maven管理工具

一 Maven简单介绍 Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具。 Maven的作用 二 Maven 安装配置 依赖配置 依赖传递 依赖范围 生命周期 注意事项&#xff1a;在同一套生命周期中&#xff0c;当运行后面的阶段时&#xff0c;前面的阶段都…

20250217-POMO笔记

文章目录 前言一、伪代码一&#xff1a;POMO Training二、伪代码二&#xff1a;POMO Inference三、POMO注意力模型3.1、自注意力机制3.2、AM模型 前言 以下主要讲解两个算法的伪代码以及注意力模型。 一、伪代码一&#xff1a;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 回顾我们之前停留的位置 在这段内容中&#xff0c;讨论了如何处理游戏中的三维效果&#xff0c;特别是如何处理额外的“Z层”。由于游戏中的艺术资源是位图而不是3D模型&#xff0c;因此实现三维效果变得非常具有挑战性。虽然可…

ComfyUI流程图生图原理详解

一、引言 ComfyUI 是一款功能强大的工具&#xff0c;在图像生成等领域有着广泛应用。本文补充一点ComfyUI 的安装与配置过程遇到的问题&#xff0c;并深入剖析图生图过程及相关参数&#xff0c;帮助读者快速入门并深入理解其原理。 二、ComfyUI 的安装与配置中遇到的问题 &a…

使用右侧值现象来处理一个word导入登记表的需求

需求也简单&#xff0c;导word文件用户登记表&#xff0c;有各部门的十几个版本&#xff08;为什么这么多&#xff1f;不知道&#xff09;。这里说下谈下我的一些代码做法&#xff1a; 需求分析&#xff1a; 如果能解决java字段和各项填的值怎么配对的问题&#xff0c;那么就…

《open3d pyqt》Alpha重建

《open3d pyqt》Alpha重建 一、效果展示二、qt设置2.1 主界面添加动作2.2 dialog 界面、布局如下:三、核心代码一、效果展示 二、qt设置 2.1 主界面添加动作 2.2 dialog 界面、布局如下: 并生成py文件,参考前述章节 三、核心代码 main.py文件增加 from Su

小程序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 功能说明 技术栈&#xff1a;uniapp、vue、canvas 2d 需求&#xff1a; 实现横版的全…

MoE演变过程

MoE演变过程 1 MoE1.1 BasicMoE1.2 SparseMoE1.2.1 实现 1.3 Shared Expert SparseMoE 1 MoE 参考&#xff1a;https://huggingface.co/blog/zh/moe 1.1 BasicMoE 用router给出各专家的权重&#xff0c;然后让输入过每一个专家&#xff0c;然后做加权求和。 1.2 SparseMoE …

【实战项目】BP神经网络识别人脸朝向----MATLAB实现

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

【1.8w字深入解析】从依赖地狱到依赖天堂:pnpm 如何革新前端包管理?

目录 前言npm 的诞生与发展嵌套依赖模型存在的问题npm3架构与yarnYarn 的诞生与局限Yarn 的诞生背景Yarn 仍然存在的问题 何为幽灵依赖依赖结构的不确定性pnpm王牌登场 -- 网状平铺结构安装包速度快依赖管理软链接 和 硬链接 机制 幽灵依赖产生的根本原因包管理工具的依赖解析机…

137,【4】 buuctf web [SCTF2019]Flag Shop

进入靶场 都点击看看 发现点击work会增加&#xffe5; 但肯定不能一直点下去 抓包看看 这看起来是一个 JWT&#xff08;JSON Web Token&#xff09;字符串。JWT 通常由三部分组成&#xff0c;通过点&#xff08;.&#xff09;分隔&#xff0c;分别是头部&#xff08;Header&…

【c++】c++内存管理

目录 c和c的内存分布回顾C语言动态管理内存的方式malloccallocreallocfree C动态管理内存的方式new和deleteoperator new和operator delete定位new c和c的内存分布 回顾C语言动态管理内存的方式 malloc void* malloc (size_t size);malloc可以在堆上开辟指定内存的空间&#…