【STM32】【HAL库】【实用制作】遥控关灯

12 篇文章 3 订阅
6 篇文章 1 订阅

目录

需求分析

方案设计

硬件设计

电源

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

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值