震动传感器(接到PA4,下降沿触发中断):震动输出低电平,反之高电平
继电器(接到PB7):低电平闭合导通,高电平断开
高功率喇叭:用上面继电器控制
433M无线发射接收模块(上升沿触发中断):接收到信号,接收模块对应针脚输出高电平,有D0 D1 D2 D3,对应遥控器的ABCD
A(打开警报模式):D0(接到PA5)
D1(关闭警报模式):(接到PA6)
工程用CubeMX配置
如果直接在中断服务函数里面调用HAL_Delay()函数,则会造成系统卡死
原因:程序在初始化时默认把滴答定时器的中断优先级设为最低,其他的中断源很容易打断它导致卡死
解决:在main里面使用以下函数把滴答定时器的中断优先级提升为0
设置中断优先级
HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
{
uint32_t prioritygroup = 0x00U;
/* Check the parameters */
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
prioritygroup = NVIC_GetPriorityGrouping();
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
}
主要重写这个中断回调函数
实现逻辑如下
#define jb_on 1
#define jb_off 2
//重写中断服务函数,如果检测到EXTI中断请求,则进入此函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
static uint16_t mark = jb_off;
switch(GPIO_Pin){
case GPIO_PIN_5: //如果PA5被拉高,设定为报警模式,喇叭响两秒,mark设为jd_on
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5) == GPIO_PIN_SET){
mark = jb_on;
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
}
break;
case GPIO_PIN_6: //如果PA6被拉高,关掉警报模式,喇叭响一秒,mark设为jd_off
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6) == GPIO_PIN_SET){
mark = jb_off;
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
}
break;
case GPIO_PIN_4: //如果PA4被拉低,并且警报模式打开的话,则将继电器拉低导通,喇叭一直响
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == GPIO_PIN_RESET && mark==jb_on){
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);
}
break;
}