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

1、复制06工程文件,重命名07-震动控制灯(中断法)

打开工程文件

打开exti.c文件

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

更改代码

2、代码(老师的)

exti.c

cpp 复制代码
#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

cpp 复制代码
#ifndef __EXTI_H__
#define __EXTI_H__
#include "stdint.h"
#define TRUE 0
#define FALSE 1

void exti_init(void);
uint8_t vibrate_flag_get(void);
void vibrate_flag_set(uint8_t value);
#endif

main.c

cpp 复制代码
#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

cpp 复制代码
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的时候手动置位

区别总结

‌标志状态管理‌:

第一段代码中,标志状态需要在外部显式清零。

第二段代码中,标志状态在获取时自动清零。

‌使用场景‌:

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

如果希望事件处理完后自动清除标志状态,以避免重复处理,应选择第二段代码的实现。

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

相关推荐
国科安芯25 分钟前
商业航天星载数据管理单元的存储容错与接口集成方案研究
嵌入式硬件·架构·ecc·商业航天·抗辐射
天空'之城26 分钟前
单片机基础核心知识点汇总(三十八)
单片机·嵌入式硬件
小叶肥辉35 分钟前
LangChain链和LangGraph图的学习笔记【六】——提示语模板(3)——Few-Shot Prompting(少样本提示) 模板类
笔记·python·学习·langchain·prompt·aigc
Zw-awa1 小时前
标准外设库到底在替你做什么:从时钟到 GPIO 的一次完整调用
stm32
zhangzhangkeji1 小时前
srm32 , 6-2 :定时器中断与定时器外部时钟
stm32
志尊宝2 小时前
Vue3 零基础每日笔记(032):Suspense 与异步组件——懒加载与顶层 await 终极方案
前端·javascript·vue.js·笔记·html5
今儿敲了吗2 小时前
04英文文本关键词提取(TF-IDF)
笔记·python
志尊宝2 小时前
Vue3 零基础每日笔记(035):什么是 Composables——mixin 之死与逻辑复用新方案
笔记·vue·html·前端开发·软件开发
恒锐丰科技林技术员2 小时前
EG2203:一款高性价比 600V 半桥驱动芯片
经验分享·嵌入式硬件·硬件工程
动词ing2 小时前
【学习笔记】数据结构 二分查找(二分查找模板+边界处理+查找区间+旋转数组)
笔记·学习