网站开发技术有哪些,手工艺品网站建设,深圳的软件公司,企业门户网站建设公司目录
1、准备材料
2、实验目标
3、实验流程
3.0、前提知识
3.1、CubeMX相关配置
3.1.1、时钟树配置
3.1.2、外设参数配置
3.1.3、外设中断配置
3.2、生成代码
3.2.1、外设初始化调用流程
3.2.2、外设中断调用流程
3.2.3、添加其他必要代码
4、常用函数
5、烧录验…目录
1、准备材料
2、实验目标
3、实验流程
3.0、前提知识
3.1、CubeMX相关配置
3.1.1、时钟树配置
3.1.2、外设参数配置
3.1.3、外设中断配置
3.2、生成代码
3.2.1、外设初始化调用流程
3.2.2、外设中断调用流程
3.2.3、添加其他必要代码
4、常用函数
5、烧录验证
5.1、具体步骤
5.2、实验现象
6、奇怪的现象
参考资料 1、准备材料
开发板正点原子stm32f407探索者开发板V2.4
STM32CubeMX软件Version 6.10.0
野火DAP仿真器
keil µVision5 IDEMDK-Arm
CH340G Windows系统驱动程序CH341SER.EXE
XCOM V2.6串口助手
杜邦线一根
2、实验目标
使用STM32CubeMX软件配置STM32F407开发板RTC实现入侵检测和时间戳功能具体为周期唤醒回调中使用串口输出当前RTC时间按键WK_UP存储当前RTC时间到备份寄存器按键KEY_2从备份寄存器中读取上次存储的时间按键KEY_1负责产生入侵事件
3、实验流程
3.0、前提知识
STM32F407的RTC上有两个入侵检测模块但是笔者使用的LQFP144封装的STM32F407ZGT6只有一个入侵检测模块只有一个入侵检测模块的STM32F407单片机是利用RTC_AF1PC13引脚来进行触发的和按键外部中断类似如果设置入侵检测触发为低电平触发那么当PC13为低电平时就会进入Tampere1事件回调函数当发生入侵事件时RTC的20个备份寄存器中的值会全部丢失
由于开发板上PC13引脚并没有按键控制不方便实现其电平的翻转变化操作因此本实验需要一根杜邦线将按键KEY_1所使用的PE3引脚与PC13引脚短接相当于使用按键KEY_1来间接控制PC13的电平变化如下图所示当按键KEY_1松开时此时PE3/PC13状态应该由外部上/下拉决定而当按键KEY_1按下时PE3/PC13的状态应该为低电平通过设置PC13外部上拉就可以实现KEY_1按键松开时为高电平按下为低电平 3.1、CubeMX相关配置
请阅读“STM32CubeMX STM32F4 HAL库 实时时钟RTC - 周期唤醒、闹钟A/B事件和备份寄存器”实验3.1.1小节配置RCC和SYS
3.1.1、时钟树配置
系统时钟树配置与上一实验一致均设置为STM32F407总线能达到的最高时钟频率配置LSERTC时钟频率为32.768kHz具体如下图所示 3.1.2、外设参数配置
本实验需要需要初始化USART1作为输出信息渠道具体配置步骤请阅读“STM32CubeMX教程9 USART/UART 异步通信”
单击Pinout Configuration页面左边Timers/RTC并在页面中间激活日历周期唤醒WakeUp采用内部模式勾选入侵检测1将其输入复用到引脚RTC_AF1PC13则此后PC13引脚便作为入侵检测引脚具体配置如下图所示 与上一小节实验类似需要配置RTC通用参数、日历日期时间、周期唤醒参数和入侵检测参数
①滤波设置中如果不滤波则入侵检测的触发方式只能选择边沿触发而如果选择滤波则触发方式只能选择电平触发这里由于使用的机械按键存在抖动因此对输入滤波
②入侵引脚是否上拉设置中如上述3.0小节所述我们需要PE3/PC13外部上拉才能实现目标因此此处选择上拉
③保存了入侵时间戳就可以在Tampere1事件回调函数中使用HAL_RTCEx_GetTimeStamp获取入侵时间戳
④入侵检测触发方式设置中由于按键按下为低电平因此这里选择低电平 3.1.3、外设中断配置
在Pinout Configuration页面左边System Core/NVIC中勾选入侵检测及周期唤醒中断然后选择合适的中断优先级即可 3.2、生成代码
请阅读“STM32CubeMX STM32F4 HAL库 工程建立”实验3.4.3小节配置Project Manager
单击页面右上角GENERATE CODE生成工程
3.2.1、外设初始化调用流程
与上一小节RTC初始化函数MX_RTC_Init对比可以发现本小节的初始化函数中减少了闹钟A/B的初始化但是新增加了入侵检测的初始化如下图所示也即我们在CubeMX中设置的参数类似的中断相关的初始化设置仍然在HAL_RTC_MspInit函数中 3.2.2、外设中断调用流程
在CubeMX中勾选RTC入侵检测启动中断后在stm32f4xx_it.c中均会生成对应的中断服务函数TAMP_STAMP_IRQHandler()
在该TAMP_STAMP_IRQHandler()中断服务函数中调用了HAL库HAL_RTCEx_TamperTimeStampIRQHandler()函数统一处理时间戳/入侵事件
最终根据发生的事件来源调用了时间戳事件回调函数HAL_RTCEx_TimeStampEventCallback()、入侵检测1事件回调函数HAL_RTCEx_Tamper1EventCallback()和入侵检测2事件HAL_RTCEx_Tamper2EventCallback()
具体流程如下图所示 3.2.3、添加其他必要代码
由于无入侵检测2笔者这里只实现了入侵检测1事件回调函数HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)将其实现在了rtc.c中另外周期唤醒回调函数内容与上一小结内容一致这里不再赘述入侵检测1事件回调函数具体代码如下图所示 源代码如下
/*Tampere1事件回调函数*/
void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)
{RTC_TimeTypeDef sTime;RTC_DateTypeDef sDate;if(HAL_RTCEx_GetTimeStamp(hrtc, sTime, sDate, RTC_FORMAT_BIN) HAL_OK){char str[24];sprintf(str,TimeStamp %2d:%2d:%2d\r\n,sTime.Hours,sTime.Minutes,sTime.Seconds);printf(Tampere1 Event Happend, %s, str);}HAL_GPIO_TogglePin(GREEN_LED_GPIO_Port,GREEN_LED_Pin);
}经过了上述的过程之后目前还缺少两个操作利用按键WK_UP存储当前RTC时间到备份寄存器按键KEY_2从备份寄存器中读取上次存储的时间其代码实现在了主函数主循环中简单采用轮询的方式处理按键如下图所示 源代码如下
/*按下WK_UP按键将当前时间存储到备份寄存器*/
if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin) GPIO_PIN_SET)
{HAL_Delay(50);if(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin) GPIO_PIN_SET){RTC_TimeTypeDef sTime;RTC_DateTypeDef sDate;if(HAL_RTC_GetTime(hrtc, sTime, RTC_FORMAT_BIN) HAL_OK){HAL_RTC_GetDate(hrtc, sDate, RTC_FORMAT_BIN);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);printf(Store %s to the backup register\r\n, timeStr);while(HAL_GPIO_ReadPin(WK_UP_GPIO_Port,WK_UP_Pin));}}
}/*按下KEY2按键将存储到备份寄存器的时间利用串口输出*/
if(HAL_GPIO_ReadPin(KEY_2_GPIO_Port,KEY_2_Pin) GPIO_PIN_RESET)
{HAL_Delay(50);if(HAL_GPIO_ReadPin(KEY_2_GPIO_Port,KEY_2_Pin) GPIO_PIN_RESET){uint32_t sHour,sMinute,sSecond;sHour HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR2); //HoursMinute HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR3); //MinutesSecond HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR4); //Secondchar timeStr[30];sprintf(timeStr,%u:%u:%u,sHour,sMinute,sSecond);printf(Read out %s from the backup register\r\n, timeStr);while(!HAL_GPIO_ReadPin(KEY_2_GPIO_Port,KEY_2_Pin));}
}4、常用函数
/*时间戳回调函数*/
void HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef *hrtc)/*Tampere1事件回调函数*/
void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)/*Tampere2事件回调函数*/
void HAL_RTCEx_Tamper2EventCallback(RTC_HandleTypeDef *hrtc)/*获取RTC时间戳*/
HAL_StatusTypeDef HAL_RTCEx_GetTimeStamp(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTimeStamp, RTC_DateTypeDef *sTimeStampDate, uint32_t Format)
5、烧录验证
5.1、具体步骤
“RTC Mode and Configuration中启用内部模式的WakeUp周期唤醒 - 勾选入侵检测Tamper1 Routed to AF1 - 配置合适的日历通用参数、日历日期时间、周期唤醒参数和入侵检测参数 - NVIC中勾选RTC周期唤醒中断及RTC入侵检测中断并选择合适的中断优先级 - 在生成的工程代码中重新实现周期唤醒回调函数、Tampere1事件回调函数HAL_RTCEx_Tamper1EventCallback - 添加必要的代码逻辑具体看上述3.2”
5.2、实验现象
烧录程序利用杜邦线短接PE3和PC13当开发板上电后会在周期唤醒回调函数中不断地输出当前RTC的时间另外开发板上的红色LED灯也会不断地闪烁当按下开发板上的WK_UP按键之后会将当前RTC日历的时间存储到备份寄存器RTC_BKP_DR2~4中按下开发板上的KEY_2按键可以从备份寄存器中将上次存储的时间读出来
然后当按下按键KEY_1的时候会发生入侵事件此时入侵被检测到会触发Tampere1事件回调函数通过串口输出入侵事件的信息并且如果再去通过KEY_2按键读取备份寄存器中存储的时间会发现由于入侵的发生备份寄存器中的值已经被清空
上述整个流程串口输出信息如下图所示 6、奇怪的现象
有时候会出现写备份寄存器写不进去的情况如果你也遇到了可以尝试将开发板完全断电电源线、USB串口和调试器接口然后重新上电复位再向备份寄存器中写入试试
参考资料
STM32Cube高效开发教程基础篇