目录
概述:
震动传感器 感应震动,433M无线射频模块 遥控,继电器 控制 喇叭(蜂鸣器代替也行)。
无线遥控器两按键对应 “锁起” 和 "关闭" 两种状态;
“锁起” 状态下,感受到震动就通过继电器使喇叭响起一段时间;
"关闭" 状态下,锁状态指示灯常亮。
也可以做更多功能扩展,如针对不同按键被按下时,有不同的喇叭声响应效果。
注:此项目参考本人之前做过的C51版本,更多详情如外设原理等,请看该文章
本文建议:
不直接在CubeMX中修改代码,自己手动修改也可以增进对代码的理解。
一.震动传感器
1.模块功能测试
思路:
传感器感受到震动输出低电平,用中断捕获下降沿,让LED亮起来
尝试自主修改代码,不用cubeMX
直接在上个文章末尾的最后一个工程里改代码来实现模块功能
(51条消息) STM32入门(cubeMX)_我有在好好学习的博客-CSDN博客
原工程里面用了A0、A1两个中断控制B8、B9两个LED
现用A4作为震动传感器的中断,修改源代码即可
增加了一个A4口
******************************************************************************
* @file gpio.c
* @brief This file provides code for the configuration
* of all used GPIO pins.
******************************************************************************
... ... ... ...
void MX_GPIO_Init(void)
{
... ... ... ...
/*Configure GPIO pins : PA0 PA1 PA4*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
... ... ... ...
HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
}
... ... ... ...
添加中断4
******************************************************************************
* @file stm32f1xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
... ... ... ...
void EXTI4_IRQHandler(void)
{
/* USER CODE BEGIN EXTI1_IRQn 0 */
/* USER CODE END EXTI1_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
/* USER CODE BEGIN EXTI1_IRQn 1 */
/* USER CODE END EXTI1_IRQn 1 */
}
修改主函数文件中中断服务代码,添加传感器和LED状态关系的代码
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
switch(GPIO_Pin)
{
case GPIO_PIN_4:
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);//B8状态翻转
break;
}
}
/* USER CODE END 0 */
2.感受到震动就亮一秒
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
如果直接在中断服务函数里调用 HAL_Delay 函数,则会造成系统卡死。
原因:程序初始化时默认把滴答定时器的中断优先级设为最低,其它中断源很容易打断它导致卡死。
解决:在 main 函数里使用以下函数提高滴答定时器的中断优先级(提升至0):
/* USER CODE BEGIN SysInit */
HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
/* USER CODE END SysInit */
发现还是不行,因为原本中断优先级也是0,所以修改上面的代码
HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
成功。
二.添加继电器&喇叭
硬件原理及接线:
关于硬件模块详情和原理,直接参考开头说的C51实现的文章,注意继电器接3.3v
思路:
感受到震动,GPIO口输出低电平给继电器,使得继电器让喇叭所在回路闭合,喇叭响起。
实现:
继电器直接连接上文使用的LED使用的PB8口,就无需再修改代码。
三.433M无线射频模块
硬件原理及接线:
关于硬件模块详情和原理,直接参考开头说的C51实现的文章。
思路:
俩按键对应模块输出D0D1两个口(点动),默认低电平,按下拉高。用中断0和1对应。
测试:
按下D0对应按键点亮LED,再按下关闭LED。
按下D1对应的键点亮LED一秒。
接线B5、B6
这里用的中断因为没有中断5、6,所以是
配置文件:
/*Configure GPIO pin : PA4 */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PA5 PA6 */
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB8 PB9 */
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
void EXTI9_5_IRQHandler(void)
{
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
/* USER CODE END EXTI9_5_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
/* USER CODE END EXTI9_5_IRQn 1 */
}
主函数文件:
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
switch(GPIO_Pin)
{
case GPIO_PIN_5:
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);//B9状态翻转
break;
case GPIO_PIN_6:
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
break;
case GPIO_PIN_4:
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
break;
}
}
/* USER CODE END 0 */
四.项目实现
整合以上模块功能。
功能:
无线遥控器两按键对应 “锁起” 和 "关闭" 两种状态;
“锁起” 状态下,感受到震动就通过继电器使喇叭响起一段时间;
"关闭" 状态下,锁状态指示灯常亮。
接线:
PB8、9 -->GPIO_Output;//对应两板载LED灯
PA4、5、6 -->EXIT;
B9接继电器,A4接震动传感器,A5、A6接无线模块D0、D1 。
代码:
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
#define Locker_ON 1
#define Locker_OFF 0
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t Locker_Flag = Locker_ON;
/* USER CODE END PV */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
switch(GPIO_Pin)
{
//“锁起”状态
case GPIO_PIN_5:
//锁状态指示灯关闭
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
//锁起
Locker_Flag = Locker_ON;
break;
//“关闭”状态
case GPIO_PIN_6:
//锁状态指示灯常亮
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
//关闭
Locker_Flag = Locker_OFF;
break;
//震动传感器
case GPIO_PIN_4:
//判断是否锁起
if(Locker_Flag == Locker_ON)
{
//喇叭响起1s
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
}
break;
}
}
/* USER CODE END 0 */