目录
需求分析
方案设计
硬件设计
电源
stm32系统
复位电路
?晶振
引导跳线
?编辑
?STLink下载电路
主芯片电源
?主芯片
?电压检测
舵机驱动
?编辑
?红外
软件部分
思路
运动过程
?HAL初始化
?代码
低功耗
电压检测
LED
开灯和关灯
外部中断
主函数
成品
需求分析
房间里的灯的开关距离床铺较远,每次睡觉前都得爬下床去关灯
因此设计一个可以远距离遥控的设备
需要满足:
- 无需修改家庭电路(怕被骂)
- 使用电池供电(开关距离插座很远)
- 低功耗?
- 检测电池电压
- 使用家用遥控器(废旧遥控器)
- 可以不影响开关使用
方案设计
使用stm32f103c6t6为主控(价格便宜 当前价格3r)
使用2节18650串联供电,使电压为7-8V(外置保护板)
通过ldo降压到3v3和5v(单片机和红外接收)
使用红外遥控(wifi/蓝牙需要的功耗很高,价格也较贵)?
?使用舵机来模拟人手控制开关
通过电阻分压获取当前电池的电压,在电压过低时发出信号?
硬件设计
电源
使用AMS1117来获取3V3和5V电压给系统供电?
stm32系统
复位电路
?晶振
引导跳线
?STLink下载电路
主芯片电源
?主芯片
?电压检测
舵机驱动
?舵机是5V电压驱动的,需要使用开漏上拉使输出高电平为5V
?红外
软件部分
思路
使用之前做好的红外库和舵机操控库
接收红外信号,当接收到指定的红外信号时
操作舵机打开开关或者关闭开关
通过定时器实现上电时LED闪烁
当电量较低时LED常亮报警?
运动过程
默认状态
开灯状态?
?
关灯状态?
开灯流程
默认状态--->开灯状态---->默认状态
关灯流程
默认状态--->关灯状态---->默认状态
?只需要给舵机一个较大的速度将开关冲过去即可
持续一段时间确保开关按到位(当然也可以加电流检测)
注意:这里用的是360°舵机?
?HAL初始化
红外解码需要: 1.外部中断,下降沿触发,上拉
2.定时器,分频后为1us,中断时间大于15ms
?
?
舵机驱动需要: 1.GPIO 开漏浮空输出,外接5V上拉
2.定时器20us触发中断
?
?
?ADC需要
单通道
?
?
LED需要
GPIO推挽输出?
?
定时器中断1s发送中断
?
?代码
低功耗
进入休眠模式,外部中断可以将其唤醒,从这个函数的结束处继续运行
/**
* @brief 进入休眠模式
* @param 无
* @return 无
* @author HZ12138
* @date 2022-08-03 16:47:42
*/
void enter_stop_mode(void)
{
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
退出休眠模式为保证正常运行需要调用所有的hal库生成的初始化函数
/**
* @brief 退出休眠模式
* @param 无
* @return 无
* @author HZ12138
* @date 2022-08-03 16:47:54
*/
void exit_stop_mode(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_ADC1_Init();
}
电压检测
整个函数再定时器中断里调用,等待无操作6秒后调用
检测电压,多次达到额定值以下触发报警?
/**
* @brief 电压检测
* @param 无
* @return 无
* @author HZ12138
* @date 2022-08-03 16:44:06
*/
void Voltage_detection(void)
{
uint16_t V = 0;
HAL_ADC_Start(&hadc1); //开启ADC
HAL_ADC_PollForConversion(&hadc1, 100); //开启电压检测
if (HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)) //转化完成
{
V = HAL_ADC_GetValue(&hadc1); //获取电压值
if (V < 2600)
{
HAL_Delay(100);
HAL_ADC_PollForConversion(&hadc1, 100); //去抖
if (HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
{
V = HAL_ADC_GetValue(&hadc1);
if (V < 2600)
{
HAL_Delay(100);
HAL_ADC_PollForConversion(&hadc1, 100); //再去抖
if (HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
{
V = HAL_ADC_GetValue(&hadc1);
if (V < 2600)
{
// LED_Ctl = 0;
STOP_Ctl = 0;
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); //点亮灯
}
}
}
}
}
else
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); //关闭led
}
}
HAL_ADC_Stop(&hadc1); //关闭adc
}
LED
上电LED闪烁
uint8_t LED_Ctl = 0; // LED控制计时
/**
* @brief 上电时LED闪
* @param 无
* @return 无
* @author HZ12138
* @date 2022-08-03 16:43:29
*/
void INIT_LED(void)
{
if (LED_Ctl % 2)
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
}
LED_Ctl++;
}
LED与休眠控制
1s定时器中断调用
uint8_t STOP_Ctl = 0; //进入休眠模式计时
/**
* @brief led控制
* @param 无
* @return 无
* @author HZ12138
* @date 2022-08-03 16:46:48
*/
void LED_Ctrl(void)
{
if (LED_Ctl < 6)
{
INIT_LED(); //前6秒闪烁
}
else
{
STOP_Ctl++;
Voltage_detection();
}
if (STOP_Ctl >= 6)
{
STOP_Ctl = 0;
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); //关灯
enter_stop_mode(); //休眠
exit_stop_mode(); //退出休眠
}
}
开灯和关灯
这部分的延迟时间需要根据自己的开关来调试和确定?
/**
* @brief 开灯
* @param 无
* @return 无
* @author HZ12138
* @date 2022-08-03 16:43:01
*/
void OPEN(void)
{
Steering_Engine_360(0, 30);
HAL_Delay(400);
Steering_Engine_360(1, 50);
HAL_Delay(100);
Steering_Engine_Stop();
HAL_Delay(2000);
}
/**
* @brief 关灯
* @param 无
* @return 无
* @author HZ12138
* @date 2022-08-03 16:43:14
*/
void CLOSE(void)
{
Steering_Engine_360(1, 30);
HAL_Delay(400);
Steering_Engine_360(0, 50);
HAL_Delay(180);
Steering_Engine_Stop();
HAL_Delay(2000);
}
外部中断
调用红外解码函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_0)
{
IR_NEC_Read_Decode(air);
STOP_Ctl = 0;
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
}
}
主函数
读取成功标志,根据自己的遥控器判断信号是否触发
之后调用之前的开关灯函数即可
if (IR_NEC_Read_OK)
{
IR_NEC_Read_OK = 0;
if (IR_NEC_Read_Dat[0] == 0x4D && IR_NEC_Read_Dat[1] == 0xB2 && IR_NEC_Read_Dat[2] == 0xA3 && IR_NEC_Read_Dat[3] == 0x5C)
{
OPEN();
}
else if (IR_NEC_Read_Dat[0] == 0x4D && IR_NEC_Read_Dat[1] == 0xB2 && IR_NEC_Read_Dat[2] == 0x59 && IR_NEC_Read_Dat[3] == 0xA6)
{
CLOSE();
}
if (IR_NEC_Read_Dat[0] == 0x84 && IR_NEC_Read_Dat[1] == 0xff && IR_NEC_Read_Dat[2] == 0x81 && IR_NEC_Read_Dat[3] == 0x7e)
{
OPEN();
}
else if (IR_NEC_Read_Dat[0] == 0x84 && IR_NEC_Read_Dat[1] == 0xff && IR_NEC_Read_Dat[2] == 0x01 && IR_NEC_Read_Dat[3] == 0xfe)
{
CLOSE();
}
IR_NEC_Read_OK = 0;
}
成品
Githubhttps://github.com/HZ1213825/HAL_STM32_Remote_Control_Lamp
|