基于STM32的家居智能台灯

1.光敏传感器

(1)ADC采集,PA0模拟输入,获取值/4095*3.3;光照越弱,光电压值越大,用来检测环境亮度

2.用红外感应传感器检测是否有人

(1)外部中断EIXT,将PB14引脚复用为中断14号线,接AO口/输出OUT,配置为上升沿触发,进入中断,判断引脚是否为高电平(是否有人靠近)

(2)应用:将标志位置1,代表有人

3.声音传感器

(1)外部中断PA2,标志位置1,在夜晚开启夜灯

4.蜂鸣器PB12

5.超声波传感器检测使用者与台灯之间的距离

(1)原理:超声波传感器的工作原理涉及到触发信号的发送(Trig)和回波信号的接收(Echo),这些都需要通过GPIO端口来实现,而测量超声波往返时间则依赖于定时器的精确计时。

(2)配置与Trig引脚相连的GPIO引脚PA6为推挽输出模式,用于发送高电平信号以触发超声波传感器发送超声波(通常为10微秒以上),再拉低。

(3)配置与Echo引脚相连的GPIO引脚PA7为浮空输入模式,并启用中断(如果需要实时检测距离变化)来读取回波信号。

(4)距离计算:公式: uS/58=厘米或者uS/148=英寸; 或是: 距离=高电平时间*声速( 340M/S) /2; 建议测量周期为 60ms以上, 以防止发射信号对回响信号的影响。

(5)应用:如果距离过近(如小于一定阈值),则执行以下操作:

·激活警报系统,如使蜂鸣器发出声音或点亮LED警报灯,以提醒使用者保持距离。

6.利用PWM控制灯光亮度?

(1)TIM3-CH3通道3输出比较,配置OC,引脚PB0输出PWM脉冲调制波形

7.最终实现的功能

(1)要求人体靠近台灯(1.5米)时且环境较暗时,红外感应开灯。

(2)当人在台灯下工作时间过长(45分钟),通过闪烁灯提醒人注意保持距离(可手动停止闪烁或关闭该功能)。

(3)当人离开(或者亮度变亮时)智能关灯。

(4)小夜灯功能,夜间有声音时,以较小亮度打开灯,持续3分钟关闭。

(5)五个档位,按键按下一次,亮度增加20%

8.犯的错误

(1)把LED灯的长脚(正极)接到了PB0,但是配置为输出高电平,导致占空比为0时,亮度确为100;把配置改为低电平,或者正极接到电源端

(2)设置占空比应该放在if判断以外,不然只会在按键按下的时候亮

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
#include "HC-SR04.h"
#include "PWM.h"
#include "CountSensor.h"
#include "AD.h"
#include "Timer4.h"
#include "Buzzer.h"


#define close 0
#define open 1
#define twinkle 2


uint8_t AI=1;                 //智能模式,默认开启
uint8_t People_Flag=0;          //默认人体活动标志位为0
uint8_t Sound_Flag;            //获取声音标志位
uint8_t Night_Flag;            //获取夜灯标志位
uint16_t ADvalue;                //光敏电阻传感器转换值
uint16_t  Light;                //亮度值
uint8_t LED_Status;              //灯光状态
static uint16_t KeyNum;
static float length;           //距台灯的距离
void oled_show(void);

uint8_t     PIS_cnt;                 //热释电模块检测周期延时
uint16_t     time_cnt=0;              //LED开启时间计数
uint8_t  night_cnt=0;               //夜灯开启时间计数

int main(void)
{
    /*模块初始化*/
    OLED_Init();        //OLED初始化
    Key_Init();
    HC_SR04_Init();
    PWM_Init();
    Buzzer_Init();
    Timer4_Init();
    CountSensor_Init();
    
    while (1)
    {
        length=Senor_Using();
        KeyNum=Key_GetNum();
        ADvalue=AD_GetValue();
        
        OLED_ShowString(2,1,"HCSR:");
        
        oled_show();            //不断刷新显示length
        
        /*      触摸模式    */
        if(KeyNum==2)                 //按键PB11按下
        {
            Delay_ms(10);
            LED_Status=open;                //灯开启
            Light+=20;
            if(Light>100)                    //大于100时,调到最低亮度20
            {
                Light=0;
              LED_Status=close;                    //灯关闭
            }
        }
        PWM_SetCompare3(Light);
        Delay_ms(10);
        
        if(KeyNum==1)                        //按键PB1按下
        {
            Delay_ms(10);
            AI = !AI;//关闭或打开智能模式
        }
    

        /*      智能模式    */
        if(AI==1)
        {
            Sound_Flag=SoundSensor_Get();    //获取声音标志位
            if(Sound_Flag==1&&ADvalue<2000)                 //当有声音并且环境比较暗时,开启夜灯
            {
                Night_Flag=1;                                 //夜灯开启
                PWM_SetCompare3(100);                         //开灯
            }
            if(LED_Status!=twinkle && Night_Flag==0)//当LED没有闪烁并且没有开启夜灯功能时,才执行以下程序
            {
                People_Flag=CountSensor_Get();    //获取人体活动标志位
                if(People_Flag==1&&ADvalue<2000)                 //当有人并且环境比较暗时
                {
                    PWM_SetCompare3(100);                         //开灯
                    LED_Status=open;
                }
                else
                {
                    PWM_SetCompare3(0);//关闭LED
                    LED_Status = close;//更新LED状态
                }
            }
            if(length<5.000&&LED_Status==open)
            {
                    GPIO_ResetBits(GPIOB, GPIO_Pin_12);//初始默认置高
                    Delay_ms(100);
                    GPIO_SetBits(GPIOB, GPIO_Pin_12);//初始默认置高                
            }
                
        }
                        
    }
}

void TIM4_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET) //检查是否发生TIM4中断
    {
        if(AI==1)                                      //智能模式下
        {
            if(People_Flag==0)                                 //没有人体活动或者可能离开
            {    PIS_cnt++;                                    //在没有输出高电平时,计次
                if(PIS_cnt>=2*20 )                            //0.5*2*20=20s
                {
                    PWM_SetCompare3(0);                                     //人体离开20s后,关闭灯光
                    PIS_cnt=0;                                    //计次清零
                }
            }
            if(Night_Flag==1)
            {
                night_cnt++;                                    //夜灯开启时,开始计次
                if(night_cnt>=2*30)                              //计次60次,计时0.5*60=30s
                {
                    PWM_SetCompare3(0);                          //30s后,关闭灯光
                    night_cnt=0;                                    //计次清零
                }
            }
            
            if(LED_Status==open)                                 //触摸使得灯开启
            { 
                time_cnt++;                                        //开始计次
                if(time_cnt>=2*40)                                    //灯光连续开启40s时
                {
                    LED_Status=twinkle;                                 //灯状态变为闪烁
                }
            }
            
            if(LED_Status ==twinkle)
            {
                    if(Light)                                //如果此时亮度值非0
                    {
                        Light=0;
                        PWM_SetCompare3(Light);//关闭LED
                    }                            
                    else                                        //亮度值为0,以定时器时间0.5s闪烁
                    {
                        Light=100;
                        PWM_SetCompare3(Light);//打开LED
                    }                
            }
            
        }
        
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update ); //清楚中断更新标志

    }
}

void oled_show(void)
{
    int int_length,decimal_lenght;
    int_length = (uint16_t)length; //获取整数值
    decimal_lenght = length * 1000 - int_length * 1000;       //获取小数值    
    OLED_ShowString(1,1,"HCSR:");
    OLED_ShowNum(1,6,int_length,1);
    OLED_ShowString(1,7,".");
    OLED_ShowNum(1,8,decimal_lenght,3);
    OLED_ShowString(1,11,"cm");    
}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值