小实验--震动点灯

发布于:2025-08-08 ⋅ 阅读:(18) ⋅ 点赞:(0)

1.实验目的

使用中断的方法,震动传感器检测到震动时,LED1点亮2秒,之后熄灭。

2.硬件清单

  • 震动传感器
  • STM32开发板
  • ST-Link

3.硬件连接

STM32 震动传感器
PA4 DO
3V3 VCC
GND GND

4.代码

4.1exti.c

#include "exti.h"
#include "sys.h"
#include "delay.h"
#include "led.h"

uint8_t vibrate_flag = FALSE;

void exti_init(void)
{
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    GPIO_InitTypeDef gpio_initstruct;
    //初始化GPIO
    gpio_initstruct.Mode =GPIO_MODE_IT_FALLING;
    gpio_initstruct.Pin =GPIO_PIN_4;
    gpio_initstruct.Pull =GPIO_PULLUP;
    gpio_initstruct.Speed =GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &gpio_initstruct);
    //设置中断线
    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)
{
    if(GPIO_Pin == GPIO_PIN_4)
    {
        if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == GPIO_PIN_RESET)
        {
            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;
}

4.2main.c

#include "sys.h"
#include "uart1.h"
#include "delay.h"
#include "exti.h"
#include "led.h"


int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    led_init();
    exti_init();
    
    while(1)
    { 
        if(vibrate_flag_get() == TRUE)
        {
            led1_on();
            delay_ms(2000);
            led1_off();
            vibrate_flag_set(FALSE);
        }
    }
}

4.3exti.h

#ifndef __HAL_EXTI_H
#define __HAL_EXTI_H

#include "stdint.h"

#define TRUE    1
#define FALSE   0

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

#endif

exti_init这个函数就是中断的相关配置,在之前的文章有讲。

因为在中断函数中最好不要出现延时函数,
所以这里是用了标志的方法,
在大型项目中一般就写两个函数uint8_t vibrate_flag_get(void);
和void vibrate_flag_set(uint8_t value);
来分别传出标志符和修改标志符。

然后我在.h文件中宏定义了两个符号TRUE和FALSE,使用vibrate_flag变量保存.
分别表示震动模块的打开和关闭。
但是因为当震动模块打开后,没有将vibrate_flag变量复位为FALSE,
这样就会造成main函数中的if一直成立灯就会一直亮,
所以就使用定义临时变量temp来将vibrate_flag变量复位为FALSE。

还有一个问题就是当碰一下震动模块,震动模块会触发很多上升沿和下降沿,
导致灯不会亮2秒,会亮很多秒,
所以在延时两秒后又通过vibrate_flag_set函数将vibrate_flag手动复位为FALSE。


网站公告

今日签到

点亮在社区的每一天
去签到