项目需求
点击遥控器 A 按键,系统进入警戒模式,一旦检测到震动(小偷偷车),则喇叭发出声响报警, 吓退小偷。 点击遥控器 B 按键,系统退出警戒模式,再怎么摇晃系统都不会报警,否则系统一直发出尖叫, 让车主尴尬。
项目框图
![](https://i-blog.csdnimg.cn/blog_migrate/8fc689cc582a1b8ab036b9c01b4201bb.png)
硬件清单
振动传感器 继电器 高功率喇叭 433M无线接收发射模块 杜邦线
a.振动传感器介绍及实战
振动传感器介绍
单片机供电VCC GND接单片机 产品不震动,输出高电平,模块上的DO口 产品震动,输出低电平,绿色指示灯亮 AO口不用
![](https://i-blog.csdnimg.cn/blog_migrate/36436f47965fe14a3904d36f1bee6e54.png)
编程实现
需求:当振动传感器接收到振动信号时,使用中断方式点亮LED1。
//重写中断服务函数,如果检测到EXTI中断请求,则进入此函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
//一根中断线上接有多个中断源,判断中断请求是否来自PA4
if (GPIO_Pin == GPIO_PIN_4) {
//如果检测到PA4被拉低
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == GPIO_PIN_RESET) {
//则点亮LED1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
//延时1秒
HAL_Delay(1000);
//关闭LED1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
} else {
//未检测到PA4被拉低,则关闭LED1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
}
}
}
注意!
如果直接在中断服务函数里调用 HAL_Delay 函数,则会造成系统卡死。
原因:程序初始化时默认把滴答定时器的中断优先级设为最低,其它中断源很容易打断它导致卡 死。
解决:在 main 函数里使用以下函数提高滴答定时器的中断优先级(提升至0):
HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
并且将 EXTI4 的中断优先级设置比滴答定时器的中断优先级低,比如 2 。
当然也可以在cubeMX里配置
![](https://i-blog.csdnimg.cn/blog_migrate/a4c6ff69cb43988c7facceb7186160a7.png)
b. 继电器介绍及实战
继电器工作原理
单片机供电VCC GND接单片机,VCC需要接3.3V,5V不行!
最大负载电路交流250V/10A,直流30V/10A
引脚 IN 接收到低电平时,开关闭合。
![](https://i-blog.csdnimg.cn/blog_migrate/e8de4e358dd3d4d96b90ed595af3ea9c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cbb11ffa36f964cd4259331403bdac86.png)
c. 433M无线发射接收模块介绍及实战
433M无线发射接收模块介绍
单片机供电VCC GND接单片机
接收到信号,接收模块对应针脚输出高电平
有D0 D1 D2 D3,对应遥控器的ABCD
![](https://i-blog.csdnimg.cn/blog_migrate/9faf7ce982b701e7e6254300f08a550a.png)
编程实现
需求:按下遥控器A按键,LED1亮1秒;按下遥控器B按键,LED2亮1秒。 D0 -- PA5 D1 -- PA6
//重写中断服务函数,如果检测到EXTI中断请求,则进入此函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
switch (GPIO_Pin) {
// 如果检测到PA5被拉高(按键A被按下)
case GPIO_PIN_5:
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_SET) {
//则点亮LED1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
} else {
//如果未检测到PA5,则关闭LED1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
}
break;
// 如果检测到PA6被拉高(按键B按下)
case GPIO_PIN_6:
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == GPIO_PIN_SET) {
//则点亮LED2
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
} else {
//如果未检测到PA4,则关闭LED1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
}
break;
}
}
项目设计及实现
项目设计
如果检测到PA4被拉低(小偷偷车),并且警报模式打开
则将PB7拉低,继电器通电,喇叭一直响
如果检测到PA5被拉高(按键A按下),设定为开启警报模式
则将PB7拉低(喇叭响),2秒后恢复电平(喇叭不响),表示进入警报模式
同时将标志位设置为ON
如果检测到PA6被拉高(按键B按下),设定为关闭警报模式
则将PB7拉低(喇叭响),1秒后恢复电平(喇叭不响),表示关闭警报模式
同时将标志位设置为OFF
![](https://i-blog.csdnimg.cn/blog_migrate/275c5a26fd4fa3646ba18777ad49d1b5.png)
编程实现
#define J_ON 1
#define J_OFF 0
//重写中断服务函数,如果检测到EXTI中断请求,则进入此函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
static int mark = J_OFF;
switch (GPIO_Pin) {
case GPIO_PIN_4:
//如果检测到PA4被拉低(小偷偷车),并且警报模式打开
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == GPIO_PIN_RESET && mark == J_ON) {
//则将PB7拉低,继电器通电,喇叭一直响
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
}
break;
// 如果检测到PA5被拉高(按键A按下),设定为开启警报模式
case GPIO_PIN_5:
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_SET) {
// 则将PB7拉低(喇叭响),2秒后恢复电平(喇叭不响),表示进入警报模式
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
// 同时将标志位设置为ON
mark = J_ON;
}
break;
// 如果检测到PA6被拉高(按键B按下),设定为关闭警报模式
case GPIO_PIN_6:
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6) == GPIO_PIN_SET) {
// 则将PB7拉低(喇叭响),1秒后恢复电平(喇叭不响),表示关闭警报模式
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
// 同时将标志位设置为OFF
mark = J_OFF;
}
break;
}
}