一、实验功能
本实验实现:
- 震动传感器检测到震动 → 继电器吸合 1 秒
- 无震动 → 继电器保持断开
- 继电器自带 LED 同步指示状态
二、硬件连接
- 震动传感器 OUT → PA1
- 继电器 IN → PA0
- 继电器 VCC → 5V
- 继电器 GND → 开发板 GND
- 继电器COM→开发板VCC
- 继电器NO→LED的VCC
- LED的GND→开发板的GND
三、工作原理
- 震动传感器未震动时输出高电平
- 震动时输出低电平
- 单片机检测到低电平 → 驱动继电器吸合 1 秒→LED亮1秒
- 继电器为低电平触发
四、代码逻辑
- 初始化震动传感器(PA1 上拉输入)
- 初始化继电器(PA0 推挽输出)
- 循环检测震动信号
- 检测到震动 → 继电器吸合 1 秒后自动断开
main.c (主程序:震动传感器控制继电器吸合 1 秒)
// 包含STM32标准库底层驱动
#include "stm32f10x.h"
// 工程主头文件
#include "main.h"
// 继电器驱动头文件
#include "relay.h"
// 震动传感器驱动头文件
#include "shake.h"
/**
* @brief 毫秒级软件延时函数
* @param time: 延时时长,单位约1ms
* @retval 无
*/
void delay(uint16_t time)
{
uint16_t i = 0;
// 外层循环控制总延时时间
while(time--)
{
i = 12000;
// 内层空循环消耗CPU时间,实现延时
while(i--);
}
}
/**
* @brief 主函数,程序上电入口
* @retval int
*/
int main()
{
// 初始化震动传感器引脚 PA1
Shake_Init();
// 初始化继电器控制引脚 PA0
Relay_Init();
// 初始状态:PA0输出高电平 → 继电器默认断开
GPIO_SetBits(GPIOA, GPIO_Pin_0);
// 死循环,持续检测震动信号
while(1)
{
// 判断:PA1是否检测到震动(低电平表示触发)
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1) == 0)
{
// PA0输出低电平 → 继电器吸合
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
// 保持吸合 1秒
delay(1000);
// PA0输出高电平 → 继电器断开
GPIO_SetBits(GPIOA, GPIO_Pin_0);
// 保持断开 1秒
delay(1000);
}
// 无震动时
else
{
// 继电器保持断开状态
GPIO_SetBits(GPIOA, GPIO_Pin_0);
}
}
}
shake.c (震动传感器驱动)
// 震动传感器头文件
#include "shake.h"
// STM32标准库
#include "stm32f10x.h"
/**
* @brief 震动传感器初始化
* @param 无
* @retval 无
*/
void Shake_Init(void)
{
// 定义GPIO配置结构体
GPIO_InitTypeDef GPIO_Initstruct;
// 开启GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置 PA1 为震动传感器输入引脚
GPIO_Initstruct.GPIO_Pin = GPIO_Pin_1;
// 上拉输入模式:未震动为高电平,震动为低电平
GPIO_Initstruct.GPIO_Mode = GPIO_Mode_IPU;
// 初始化PA1引脚
GPIO_Init(GPIOA, &GPIO_Initstruct);
}
relay.c (继电器驱动)
// STM32标准库
#include "stm32f10x.h"
// 继电器头文件
#include "relay.h"
/**
* @brief 继电器初始化
* @param 无
* @retval 无
*/
void Relay_Init(void)
{
// 定义GPIO配置结构体
GPIO_InitTypeDef relay_initstruct;
// 开启GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置 PA0 为继电器控制引脚
relay_initstruct.GPIO_Pin = GPIO_Pin_0;
// 推挽输出模式,可稳定驱动继电器
relay_initstruct.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO速度 10MHz
relay_initstruct.GPIO_Speed = GPIO_Speed_10MHz;
// 初始化PA0
GPIO_Init(GPIOA, &relay_initstruct);
}
shake.h
#ifndef SHAKE_H_
#define SHAKE_H_
void Shake_Init(void);
#endif
relay.h
#ifndef RELAY_H_
#define RELAY_H_
void Relay_Init(void);
#endif
五、实验现象
- 无震动:继电器断开,灯灭
- 震动触发:继电器吸合,灯亮,1 秒后自动关闭