项目需求
点击遥控器 A 按键,系统进入警戒模式,一旦检测到震动(小偷偷车),则喇叭发出声响报警,
吓退小偷。
点击遥控器 B 按键,系统退出警戒模式,再怎么摇晃系统都不会报警,否则系统一直发出尖叫,
让车主尴尬。
项目连接图
一,完成振动传感器实战
震动是点亮LED灯,具体思路如下
单片机供电VCC GND接单片机
产品不震动,输出高电平,模块上的DO口
产品震动,输出低电平,绿色指示灯亮
AO口不用
cubeMX配置如下
- 设置串口
- 设置时钟
- 设置GPIO初始化
- 打开中断(使能中断)
- 配置工程
代码如下
// 重写中断服务函数,如果检测到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);
二、 继电器介绍及实战
继电器工作原理
单片机供电VCC GND接单片机,VCC需要接3.3V,5V不行!
最大负载电路交流250V/10A,直流30V/10A
引脚 IN 接收到低电平时,开关闭合。导通电
由于在震动的时候 PB8 会被拉低,所以继电器的 IN 接到 PB8无需额外再修改代码。
三、433M无线发射接收模块介绍及实战
433M无线发射接收模块介绍
433M供电VCC GND 接单片机的 VCC GND
接收到信号,接收模块对应针脚输出高电平
有D0 D1 D2 D3,对应遥控器的ABCD
编程实现
需求:按下遥控器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
{
//如果未检测到PA6,则关闭LED1
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
}
break;
}
// 一根中断线上接有多个中断源,判断中断源是否来自PA4
if(GPIO_Pin == GPIO_PIN_4)
{
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
}
}
}
四、汇总实现电动车报警器
项目设计
- 如果检测到PA4被拉低(小偷偷车),并且警报模式打开。
- 则将PB7拉低(喇叭响),2秒后恢复电平(喇叭不响),表示进入警报模式。
- 如果检测到PA5被拉高(按键A按下),设定为开启警报模式。
- 则将PB7拉低(喇叭响),2秒后恢复电平(喇叭不响),表示进入警报模式。
- 同时将标志位设置为ON。
- 如果检测到PA6被拉高(按键B按下),设定为关闭警报模式。
- 则将PB7拉低(喇叭响),1秒后恢复电平(喇叭不响),表示关闭警报模式
- 同时将标志位设置为OFF
接线和上面有一点点区别
去掉PB8 PB9 配置,新增PB7配置
代码如下:
#define J_ON 1
#define J_OFF 0
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;
}
}