STM32-笔记6-震动控制灯(中断法)

embedded/2024/12/21 10:31:56/
1、复制06工程文件,重命名07-震动控制灯(中断法)

打开工程文件

打开exti.c文件

将震动传感器的DO口接32板的A4引脚

更改代码

2、代码(老师的)

exti.c

#include "sys.h"
#include "exti.h"
#include "delay.h"
#include "led.h"uint8_t vibrate_flag = FALSE;void exti_init(void)
{//使能GPIO时钟GPIO_InitTypeDef gpio_initstruct;//定义一个结构体gpio_initstruct//打开时钟-使能GPIO时钟__HAL_RCC_GPIOA_CLK_ENABLE();//设置GPIO输入模式//设置AFIO(开启时钟,IO口映射)//设置EXTI(屏蔽,上/下沿)//调用GPIO初始化函数gpio_initstruct.Mode = GPIO_MODE_IT_FALLING;//下降沿输出//结构体函数的四种类型,引脚模式、引脚、引脚上拉下拉、引脚速度gpio_initstruct.Pin = GPIO_PIN_4;//LED1对应的引脚gpio_initstruct.Pull = GPIO_PULLUP;//上拉HAL_GPIO_Init(GPIOA,&gpio_initstruct);//设置NVIC(优先级分组,设置优先级,使能中断)HAL_NVIC_SetPriority(EXTI4_IRQn,2,0);HAL_NVIC_EnableIRQ(EXTI4_IRQn);}
//设置中断服务函数
void EXTI4_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
}
//回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{//delay_ms(20);//消抖if(GPIO_Pin == GPIO_PIN_4){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == GPIO_PIN_RESET)//led1_Toggle();vibrate_flag = TRUE;}
}
uint8_t vibrate_flag_get(void)//把值传出去
{uint8_t temp = vibrate_flag;vibrate_flag = FALSE;return temp;
}
void vibrate_flag_set(uint8_t value)//让外界对这个值可以操作
{vibrate_flag = value;
}

exti.h

#ifndef __EXTI_H__
#define __EXTI_H__
#include "stdint.h"
#define TRUE 0
#define FALSE 1void exti_init(void);
uint8_t vibrate_flag_get(void);
void vibrate_flag_set(uint8_t value);
#endif

main.c

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "exti.h"int main(void)
{HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */led_init();//初始化led灯exti_init();while(1){ if(vibrate_flag_get() == TRUE){led1_ON();delay_ms(2000);led1_OFF();vibrate_flag_set(FALSE);}}
}
3、代码(自己理解的)只展示不同的地方

 exti.c

uint8_t vibrate_flag_get(void)//把值传出去
{return vibrate_flag;
}
4、不同的地方(AI分析)

现象一致

在提供的两段代码中,vibrate_flag_get 函数的实现有所不同,而其他部分(vibrate_flag_set 函数和主循环)则保持一致。这两段代码的核心区别在于如何处理 vibrate_flag 标志在获取后的状态。

第一段代码(自己的)
c
Copy Code
uint8_t vibrate_flag_get(void) {
    return vibrate_flag;
}


在这段代码中,vibrate_flag_get 函数直接返回 vibrate_flag 的当前值,而不改变它的状态。这意味着,如果在主循环中 vibrate_flag 被检测为 TRUE,并且相应的 LED 操作被执行后,vibrate_flag 仍然保持为 TRUE,直到显式地通过 vibrate_flag_set(FALSE) 将其设置为 FALSE。

第二段代码(老师的)
c
Copy Code
uint8_t vibrate_flag_get(void) {
    uint8_t temp = vibrate_flag;
    vibrate_flag = FALSE;
    return temp;
}


在这段代码中,vibrate_flag_get 函数不仅返回 vibrate_flag 的当前值,还立即将 vibrate_flag 设置为 FALSE。这意味着,一旦在主循环中检测到 vibrate_flag 为 TRUE 并执行了相应的 LED 操作后,vibrate_flag 会自动被清零,无需再显式调用 vibrate_flag_set(FALSE)。然而,在您的代码中,您仍然调用了 vibrate_flag_set(FALSE),这实际上是多余的,因为 vibrate_flag_get 已经完成了清零工作。

        在老师的代码中,如果不加入上述一行代码,会在每一次震动的时候,四秒灯才灭,原因如下:
            因为在人为给予震动的时候,对于振动传感器来说是一个很缓慢的过程,在人眼看来是一个震动,在传感器看来是一行波动,所以,传感器接收到第一次震动的时候触发程序,执行函数,但是代码执行的速度是很快的所以,执行完一次之后灯光处于打开状态,但是vibrate_flag标志位虽然在get函数中将其置回FALSE,但是在接收到震动的时候还会再次触发一遍代码,就会产生四秒的延迟,故在主函数中,需要调用vibrate_flag_set函数,在检测到一次true的时候手动置位

区别总结

‌标志状态管理‌:

第一段代码中,标志状态需要在外部显式清零。
第二段代码中,标志状态在获取时自动清零。

‌使用场景‌:

如果希望在处理完事件后仍然保留标志状态,以便后续可能再次使用,应选择第一段代码的实现。
如果希望事件处理完后自动清除标志状态,以避免重复处理,应选择第二段代码的实现。

在实际应用中,您应根据具体需求选择适合的实现方式。如果事件只需要处理一次,并且不希望重复触发,那么第二段代码的实现(自动清零)可能更为合适。如果事件可能需要被多次处理,或者您希望在处理完事件后仍然能够知道标志的状态,那么第一段代码的实现(不自动清零)可能更为合适。


http://www.ppmy.cn/embedded/147507.html

相关文章

专业125+总分400+南京理工大学818考研经验南理工电子信息与通信工程,真题,大纲,参考书。

考研成功上岸,苦尽甘来,专业818信号系统与数字电路125,总分400,被南理工录取,从最早信心满满,到中期犹豫不决,到后期破釜沉舟,一路颠颠簸簸,总算坚持过来了,群…

使用 Lambda 创建 Authorizer 对 API Gateway 访问进行鉴权

背景介绍 对于配置好的 API Gateway 资源来说, 默认会允许所有客户端进行访问. 我们可以配置 API key 进行简单的访问控制, 不过需要注意, API key 主要应用场景其实还是结合 Usage plan 对访问量进行控制, 并不提供鉴权的目的. 毕竟 API key 会作为一个静态的 Header x-api-k…

方正畅享全媒体新闻采编系统 screen.do SQL注入漏洞复现

0x01 产品简介 方正畅享全媒体新闻生产系统是以内容资产为核心的智能化融合媒体业务平台,融合了报、网、端、微、自媒体分发平台等全渠道内容。该平台由协调指挥调度、数据资源聚合、融合生产、全渠道发布、智能传播分析、融合考核等多个平台组成,贯穿新闻生产策、采、编、发…

【功能安全】硬件架构度量

目录 01 硬件架构度量介绍 02 硬件架构度量相关说明 03 硬件架构度量示例 04 硬件架构度量模板 01 硬件架构度量介绍 GBT 34590 2022 part5

网络协议与网络安全学习记录

SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密 HTTPS,代表Hyper Text Transfer Protocol Secure,将SSL/T…

一款轻量级的开源笔记服务软件

大家好,我是兔兔,一位写作爱好者,今天分享的内容是,如何搭建一个开源的、隐私优先的轻量级笔记服务应用。 不知道大家是否有这样的需求: 1、自己想搭建一个个人的学习笔记文档,既要自己看也可以单独分享给…

WebRTC搭建与应用(一)-ICE服务搭建

WebRTC搭建与应用(一) 近期由于项目需要在研究前端WebGL渲染转为云渲染,借此机会对WebRTC、ICE信令协议等有了初步了解,在此记录一下,以防遗忘。 第一章 ICE服务搭建 文章目录 WebRTC搭建与应用(一)前言一、ICE是什么?二、什么…

XML Schema 复合类型 - 混合内容

XML Schema 复合类型 - 混合内容 XML Schema 是一种用于定义 XML 文档结构和内容的语言。在 XML Schema 中,复合类型是一种包含其他元素和/或属性的复杂类型。混合内容(Mixed Content)是复合类型的一种特殊形式,它允许元素包含其…