【STM32项目】智能台灯

发布于:2025-07-25 ⋅ 阅读:(17) ⋅ 点赞:(0)

 

✌️✌️大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是基于《基于STM32的智能台灯设计》。

目录

1、系统功能

2.1、硬件清单

2.2、功能介绍

2.3、控制模式

2、演示视频和实物

3、系统设计框图

4、软件设计流程图

5、原理图

6、主程序

7、总结


1、系统功能

2.1、硬件清单

STM32+OLED+光敏传感器+人体热释电传感器+语音识别+三路LED灯+蓝牙

2.2、功能介绍(下面视频有详细讲解)

(1)灯光控制模块:包含三个 LED 灯,分别对应客厅、厨房、卧室的灯光控制,每个区域的灯支持暖光、白光、暖光与白光同时开启三种状态。
(2)语音识别模块:支持通过唤醒词 “小智” 激活语音控制功能,可接收并执行打开 / 关闭指定区域灯光、切换灯光类型(暖光 / 白光)等语音指令。
(3)人体识别传感器:用于检测环境中是否有人体靠近,检测结果(“有人” 或 “无人”)实时显示于 OLED 屏幕,作为自动模式的触发条件之一。
(4)光敏传感器:实时检测环境光照强度,检测数据显示于 OLED 屏幕,为自动模式下灯光亮度调节提供依据。
(5)OLED 显示模块:采用 0.96 寸液晶显示屏,第一行实时显示时间及当前工作模式(手动 / 自动 / 语音),第二行显示光照强度数值及人体检测状态(“人体:1” 表示有人)。
(6)按键模块:用于手动模式下切换灯光状态,支持单独控制各区域灯光的开关及暖光 / 白光模式切换,配合 APP 实现本地按键控制。
(7)蓝牙模块:支持与手机 APP 连接,实现手动模式下通过手机远程控制各区域灯光的开关及模式切换。

2.3、控制模式

  1. 手动模式:通过按键或蓝牙连接的手机 APP 直接控制各区域灯光的开关及暖光 / 白光模式切换,OLED 屏实时显示当前模式及操作状态。
  2. 语音模式:通过唤醒词 “小智” 激活语音交互,支持语音指令控制各区域灯光的开关、暖光 / 白光切换(如 “打开厨房暖光灯”“关闭卧室灯”),语音指令执行结果通过语音反馈及 OLED 屏显示。
  3. 自动模式:需通过按键或 APP 开启,仅在人体识别传感器检测到有人时生效,系统根据光敏传感器检测的光照强度自动调节对应区域灯光亮度(光照强度低于阈值时逐级增强亮度,高于阈值时关闭灯光),实现无人时自动关灯、有人时智能调光。

2、演示视频和实物

基于STM32的智能台灯设计-(语音识别+蓝牙控制+三路LED)


3、系统设计框图


4、软件设计流程图


5、原理图


6、主程序

#include "sys.h"                //头文件
#include "delay.h"
#include "led.h"
#include "Key.h"
#include "Buzzer.h"
#include "OLED.h"
#include "AD.h"
#include "MyRTC.h"
#include "dht11.h"
#include "Serial.h"
#include "PWM.h"
#include "Serial2.h"
#include <stdio.h>
#include <string.h>
#include "BODY_HW.h"
uint32_t bufe[5];           //存储传感器采集的数据
uint16_t AD4;    //存储4路ADC值
uint8_t RxData;      //蓝牙接收到的数据

uint32_t GuangYu = 40;     //光照强度阈值下限
uint32_t GuangYu1 = 20, GuangYu2 = 40, GuangYu3 = 60, GuangYu4 = 80;               //光照强度阈值上限
u8 temp, humi;                //存放温湿度
u8 state, state2, state2_1, state2_2, state3, state4, state5, state6, state7;      //按键状态标志
u8 t = 0;                       //传感器读取时间间隔
uint8_t KeyNum;                      //存储按键值
u8 k1, k2, k3;
u16 value = 0;
u16 pre_value = 0;
void shoudong()
{

    if (Serial_GetRxFlag() == 1)  //蓝牙接收部分
    {
        RxData = Serial_GetRxData();     //蓝牙接收
        switch (RxData)   //控制阈值
        {
        case 1:
            state2++;
            if (state2 > 3)
            {
                state2 = 0;
            }
            break;
        case 2:
            state2_1++;
            if (state2_1 > 3)
            {
                state2_1 = 0;
            }
            break;
        case 3:
            state2_2++;
            if (state2_2 > 3)
            {
                state2_2 = 0;
            }
            break;
        }
    }

    if (KeyNum == 2)        //按键PB0控制窗户开关
    {
        delay_ms(20);
        if (KeyNum == 2)
        {
            state2++;
            if (state2 > 3)
            {
                state2 = 0;
            }
        }
    }

    switch (state2)
    {
    case 0:
        PWM_SetCompare1(100);    //全灭
        PWM_SetCompare2(100);

        break;
    case 1:
        PWM_SetCompare1(0);    //暖光
        PWM_SetCompare2(100);
        break;
    case 2:
        PWM_SetCompare1(100);    //白光
        PWM_SetCompare2(0);
        break;
    case 3:
        PWM_SetCompare1(0);    //全亮
        PWM_SetCompare2(0);
        break;
    default:
        break;
    }
    if (KeyNum == 3)        //按键PB0控制窗户开关
    {
        delay_ms(20);
        if (KeyNum == 3)
        {
            state2_1++;
            if (state2_1 > 3)
            {
                state2_1 = 0;
            }
        }
    }

    switch (state2_1)
    {
    case 0:
        GPIO_SetBits(GPIOA, GPIO_Pin_6);                        //PB.5 输出高
        GPIO_SetBits(GPIOA, GPIO_Pin_7);

        break;
    case 1:
        GPIO_ResetBits(GPIOA, GPIO_Pin_6);                      //PB.5 输出高
        GPIO_SetBits(GPIOA, GPIO_Pin_7);
        break;
    case 2:
        GPIO_SetBits(GPIOA, GPIO_Pin_6);                        //PB.5 输出高
        GPIO_ResetBits(GPIOA, GPIO_Pin_7);
        break;
    case 3:
        GPIO_ResetBits(GPIOA, GPIO_Pin_6);                      //PB.5 输出高
        GPIO_ResetBits(GPIOA, GPIO_Pin_7);
        break;
    default:
        break;
    }
    if (KeyNum == 4)        //按键PB0控制窗户开关
    {
        delay_ms(20);
        if (KeyNum == 4)
        {
            state2_2++;
            if (state2_2 > 3)
            {
                state2_2 = 0;
            }
        }
    }

    switch (state2_2)
    {
    case 0:
        GPIO_SetBits(GPIOB, GPIO_Pin_0);                        //PB.5 输出高
        GPIO_SetBits(GPIOB, GPIO_Pin_1);

        break;
    case 1:
        GPIO_ResetBits(GPIOB, GPIO_Pin_0);                      //PB.5 输出高
        GPIO_SetBits(GPIOB, GPIO_Pin_1);
        break;
    case 2:
        GPIO_SetBits(GPIOB, GPIO_Pin_0);                        //PB.5 输出高
        GPIO_ResetBits(GPIOB, GPIO_Pin_1);
        break;
    case 3:
        GPIO_ResetBits(GPIOB, GPIO_Pin_0);                      //PB.5 输出高
        GPIO_ResetBits(GPIOB, GPIO_Pin_1);
        break;
    default:
        break;
    }

}
void zhidong()
{
    if (value == 1)
    {
        if (KeyNum == 2)        //按键PB0控制窗户开关
        {
            delay_ms(20);
            if (KeyNum == 2)
            {
                state5++;
                if (state5 > 1)
                {
                    state5 = 0;
                }
            }
        }

        if (state5 == 0)
        {
            k1 = 0;

        }
        if (state5 == 1)
        {
            k1 = 1;
        }
        if (KeyNum == 3)        //按键PB0控制窗户开关
        {
            delay_ms(20);
            if (KeyNum == 3)
            {
                state6++;
                if (state6 > 1)
                {
                    state6 = 0;
                }
            }
        }

        if (state6 == 0)
        {
            k2 = 0;

        }
        if (state6 == 1)
        {
            k2 = 1;
        }

        if (KeyNum == 4)        //按键PB0控制窗户开关
        {
            delay_ms(20);
            if (KeyNum == 4)
            {
                state7++;
                if (state7 > 1)
                {
                    state7 = 0;
                }
            }
        }

        if (state7 == 0)
        {
            k3 = 0;

        }
        if (state7 == 1)
        {
            k3 = 1;
        }




        if (k1 == 1)
        {
            switch (state4)
            {
            case 0:
                PWM_SetCompare1(100);    //全灭
                PWM_SetCompare2(100);

                break;
            case 1:
                PWM_SetCompare1(0);    //暖光
                PWM_SetCompare2(100);
                break;
            case 2:
                PWM_SetCompare1(100);    //白光
                PWM_SetCompare2(0);
                break;
            case 3:
                PWM_SetCompare1(0);    //全亮
                PWM_SetCompare2(0);
                break;
            default:
                break;
            }
        }
        else
        {
            PWM_SetCompare1(100);    //全灭
            PWM_SetCompare2(100);
        }

        if (k2 == 1)
        {
            switch (state4)
            {
            case 0:
                GPIO_SetBits(GPIOA, GPIO_Pin_6);                        //PB.5 输出高
                GPIO_SetBits(GPIOA, GPIO_Pin_7);

                break;
            case 1:
                GPIO_ResetBits(GPIOA, GPIO_Pin_6);                      //PB.5 输出高
                GPIO_SetBits(GPIOA, GPIO_Pin_7);
                break;
            case 2:
                GPIO_SetBits(GPIOA, GPIO_Pin_6);                        //PB.5 输出高
                GPIO_ResetBits(GPIOA, GPIO_Pin_7);
                break;
            case 3:
                GPIO_ResetBits(GPIOA, GPIO_Pin_6);                      //PB.5 输出高
                GPIO_ResetBits(GPIOA, GPIO_Pin_7);
                break;
            default:
                break;
            }
        }
        else
        {
            GPIO_SetBits(GPIOA, GPIO_Pin_6);                        //PB.5 输出高
            GPIO_SetBits(GPIOA, GPIO_Pin_7);
        }
        if (k3 == 1)
        {
            switch (state4)
            {
            case 0:
                GPIO_SetBits(GPIOB, GPIO_Pin_0);                        //PB.5 输出高
                GPIO_SetBits(GPIOB, GPIO_Pin_1);

                break;
            case 1:
                GPIO_ResetBits(GPIOB, GPIO_Pin_0);                      //PB.5 输出高
                GPIO_SetBits(GPIOB, GPIO_Pin_1);
                break;
            case 2:
                GPIO_SetBits(GPIOB, GPIO_Pin_0);                        //PB.5 输出高
                GPIO_ResetBits(GPIOB, GPIO_Pin_1);
                break;
            case 3:
                GPIO_ResetBits(GPIOB, GPIO_Pin_0);                      //PB.5 输出高
                GPIO_ResetBits(GPIOB, GPIO_Pin_1);
                break;
            default:
                break;
            }
        }
        else
        {
            GPIO_SetBits(GPIOB, GPIO_Pin_0);                        //PB.5 输出高
            GPIO_SetBits(GPIOB, GPIO_Pin_1);
        }
    }
    else
    {
        GPIO_SetBits(GPIOB, GPIO_Pin_0);                        //PB.5 输出高
        GPIO_SetBits(GPIOB, GPIO_Pin_1);
        GPIO_SetBits(GPIOA, GPIO_Pin_6);                        //PB.5 输出高
        GPIO_SetBits(GPIOA, GPIO_Pin_7);
        PWM_SetCompare1(100);    //全灭
        PWM_SetCompare2(100);
    }

}




void YuYingMode()   //先说小杰唤醒,然后说打开窗户和关闭窗户
{
    if (Serial2_RxFlag == 1)        //串口接收到数据包的标志位,若是收到数据包,会置1
    {
        if (strcmp(Serial2_RxPacket, "WD_OFF") == 0)
        {
            GPIO_SetBits(GPIOB, GPIO_Pin_0);                        //PB.5 输出高
            GPIO_SetBits(GPIOB, GPIO_Pin_1);
        }
        else if (strcmp(Serial2_RxPacket, "WD_ON") == 0)
        {
            GPIO_ResetBits(GPIOB, GPIO_Pin_0);                      //PB.5 输出高
            GPIO_ResetBits(GPIOB, GPIO_Pin_1);
        }
        else if (strcmp(Serial2_RxPacket, "WDN_ON") == 0)
        {
            GPIO_ResetBits(GPIOB, GPIO_Pin_0);                      //PB.5 输出高
            GPIO_SetBits(GPIOB, GPIO_Pin_1);
        }
        else if (strcmp(Serial2_RxPacket, "WDB_ON") == 0)
        {
            GPIO_SetBits(GPIOB, GPIO_Pin_0);                        //PB.5 输出高
            GPIO_ResetBits(GPIOB, GPIO_Pin_1);
        }

        if (strcmp(Serial2_RxPacket, "KD_OFF") == 0)
        {
            PWM_SetCompare1(100);    //全灭
            PWM_SetCompare2(100);
        }
        else if (strcmp(Serial2_RxPacket, "KD_ON") == 0)
        {
            PWM_SetCompare1(0);    //全亮
            PWM_SetCompare2(0);
        }
        else if (strcmp(Serial2_RxPacket, "KDN_ON") == 0)
        {
            PWM_SetCompare1(100);    //白光
            PWM_SetCompare2(0);
        }
        else if (strcmp(Serial2_RxPacket, "KDB_ON") == 0)
        {
            PWM_SetCompare1(0);    //全亮
            PWM_SetCompare2(0);
        }

        if (strcmp(Serial2_RxPacket, "CD_OFF") == 0)
        {
            GPIO_SetBits(GPIOA, GPIO_Pin_6);                        //PB.5 输出高
            GPIO_SetBits(GPIOA, GPIO_Pin_7);
        }
        else if (strcmp(Serial2_RxPacket, "CD_ON") == 0)
        {
            GPIO_ResetBits(GPIOA, GPIO_Pin_6);                        //PB.5 输出高
            GPIO_ResetBits(GPIOA, GPIO_Pin_7);
        }
        else if (strcmp(Serial2_RxPacket, "CDN_ON") == 0)
        {
            GPIO_ResetBits(GPIOA, GPIO_Pin_6);                      //PB.5 输出高
            GPIO_SetBits(GPIOA, GPIO_Pin_7);
        }
        else if (strcmp(Serial2_RxPacket, "CDB_ON") == 0)
        {
            GPIO_SetBits(GPIOA, GPIO_Pin_6);                        //PB.5 输出高
            GPIO_ResetBits(GPIOA, GPIO_Pin_7);
        }
        Serial2_RxFlag = 0; //将标志位清零,不清零就接收不到下一个数据包了
    }
}
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    delay_init();      //延时函数初始化

    LED_Init();            //初始化与LED连接的硬件接口
    Buzzer_Init();             //下面为外设初始化
    OLED_Init();
    Key_Init();
    AD_Init();
    Serial_Init();   //串口1初始化
    MyRTC_Init();
    PWM_Init();
    PWM1_Init();  //PWM初始化
    Serial2_Init();   //串口2初始化(语音识别模块)


    OLED_ShowChinese(2, 1, 53);
    OLED_ShowChinese(2, 2, 54);
    OLED_ShowString(2, 5, ":");

    OLED_ShowChinese(2, 6, 75);
    OLED_ShowChinese(2, 7, 76);
    OLED_ShowString(2, 15, ":");

    OLED_ShowChinese(3, 1, 69);
    OLED_ShowString(3, 3, ":");

    OLED_ShowChinese(3, 4, 71);
    OLED_ShowString(3, 9, ":");

    OLED_ShowChinese(3, 7, 73);
    OLED_ShowString(3, 15, ":");


    OLED_ShowChinese(4, 1, 67);
    OLED_ShowChinese(4, 2, 68);
    OLED_ShowString(4, 5, ":");

    OLED_ShowString(1, 5, "XX:XX:XX");
    while (1)
    {
        MyRTC_ReadTime();    //读取时间(每一个页面都有时间显示)
        OLED_ShowNum(1, 5, MyRTC_Time[3], 2);    //时
        OLED_ShowNum(1, 8, MyRTC_Time[4], 2);    //分
        OLED_ShowNum(1, 11, MyRTC_Time[5], 2);   //秒
        OLED_ShowNum(4, 6, GuangYu1, 2);
        OLED_ShowNum(4, 9, GuangYu2, 2);
        OLED_ShowNum(4, 12, GuangYu3, 2);
        OLED_ShowNum(4, 15, GuangYu4, 2);
        OLED_ShowNum(3, 4, k1, 1);
        OLED_ShowNum(3, 10, k2, 1);
        OLED_ShowNum(3, 16, k3, 1);
        if (t % 10 == 0)
        {
            AD4 = AD_GetValue(ADC_Channel_5);    //光敏传感器     PA4
            if (AD4 > 4000)AD4 = 4000;
            bufe[2] = (u8)(100 - (AD4 / 40));
            OLED_ShowNum(2, 6, bufe[2], 2);
            OLED_ShowString(2, 8, "%");

            if (bufe[2] < GuangYu1)  state4 = 4;
            else if (bufe[2] < GuangYu2)  state4 = 3;
            else if (bufe[2] < GuangYu3)  state4 = 2;
            else if (bufe[2] < GuangYu4)  state4 = 1;
            else if (bufe[2] < 100)  state4 = 0;
        }
        t++;

        value = BODY_HW_GetData();

        if (value != pre_value)
        {
            OLED_ShowNum(2, 16, value, 1);
        }

        pre_value = value;

        KeyNum = Key_GetNum();

        if (KeyNum == 1)
        {
            delay_ms(20);
            if (KeyNum == 1)
            {
                state++;
                if (state > 2)
                {
                    state = 0;
                }
            }
        }
        if (state == 0)    //自动模式
        {
            OLED_ShowChinese(1, 7, 51);
            OLED_ShowChinese(1, 8, 52);
            zhidong();
        }
        if (state == 1)    //手动模式
        {
            OLED_ShowChinese(1, 7, 18);
            OLED_ShowChinese(1, 8, 52);
            shoudong();
        }
        if (state == 2)    //语音模式
        {
            OLED_ShowChinese(1, 7, 57);
            OLED_ShowChinese(1, 8, 58);
            YuYingMode();
        }
    }
}

7、总结

本文介绍了一种基于STM32的智能台灯设计方案。系统采用STM32单片机为核心,结合OLED显示屏、光敏传感器、人体热释电传感器、语音识别模块、三路LED灯(客厅/厨房/卧室)和蓝牙模块,实现多功能智能控制。系统支持三种控制模式:手动模式(按键/蓝牙APP控制)、语音模式(&quot;小智&quot;唤醒词)和自动模式(根据人体检测和环境光照自动调节灯光)。硬件设计包括传感器数据采集、灯光控制、语音交互等模块,软件采用模块化编程,主程序通过状态机实现模式切换和功能控制。该设计实现了家居照明的智能化管理,具有


网站公告

今日签到

点亮在社区的每一天
去签到