基于STM32单片机的智能家居窗户窗帘控制系统红外遥控proteus仿真原理图PCB

这篇具有很好参考价值的文章主要介绍了基于STM32单片机的智能家居窗户窗帘控制系统红外遥控proteus仿真原理图PCB。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

功能:
0.本系统采用STM32F103RCT6作为单片机
1.LCD1602液晶实时显示当前时间/窗帘状态/光照强度
2.支持手动按键/定时/光强检测三种模式控制窗帘
3.'设置’键进入设置界面
4.默认状态下’确定’键可切换模式
5.设置界面’确定’为确定
6.支持掉电保存
7.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:
基于STM32单片机的智能家居窗户窗帘控制系统红外遥控proteus仿真原理图PCB

PCB :
基于STM32单片机的智能家居窗户窗帘控制系统红外遥控proteus仿真原理图PCB

主程序:

/*************************************************************
                        智能窗帘

补充说明:
***************************************************************/
#include "reg52.h"
#include "LCD1602.h"
#include "DS1302.h"
#include "28BYJ48.h"
#include "eeprom52.h"
#include "tlc0832.h"
#include "infrared.h"
#include "delay.h"

#define uchar unsigned char //宏定义
#define uint unsigned int

/*******************引脚定义*********************/
sbit KEY_MODE    = P3^3;   //设置键
sbit KEY_ADD     = P3^4;   //加值键
sbit KEY_SUB     = P3^6;   //减值键
sbit KEY_ENTER   = P3^5;   //确定键
sbit BUZZER      = P2^0;   //蜂鸣器

sbit SW1      = P1^3;   //全开 限位开关
/*******************变量定义*********************/
uchar light_up = 80;
uchar light_down = 30; //存储光强上、下限值
uchar set_f = 0;            //设置选择标记,=0非设置,=1设置年,=2设置月,=3设置日,=4设置时,=5设置分,=6设置秒
                            //              =7设置定时-时,=8设置定时-分,=9设置定时-开关,=10设置窗帘打开/关闭
                            //				=11设置光强上限,=12设置光强下限,=13设置校准窗帘位置

unsigned char dis[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
uchar num;   //计数变量
uchar ds[4] = {8, 30, 16, 20}; //定时控制开时、分、控制关时、分

uchar mode = 0; //模式标记。=0手动,=1定时,=2光控
uchar light;    //存储光强

uint moto_num = 0;                                        //记录窗帘位置
uchar motor_state = 0;                                     //窗帘状态,=0已经关闭,=1处于运转过程中,=2已经打开
bit moto_f = 0;                                           //标记当前控制状态,=0控制关,=1控制开
uchar code display_mode[3][3] = {"SD\0", "DS\0", "GK\0"}; //显示模式

void WriteData(void)
{
    SectorErase(0x2000);    //擦除扇区
    WriteByte(0x2000, ds[0]);  //写入【定时时间】数据保存
    WriteByte(0x2001, ds[1]); //写入【定时时间】数据保存存
    WriteByte(0x2002, ds[2]); //写入【定时时间】数据保存存
    WriteByte(0x2003, ds[3]); //写入【定时时间】数据保存存
    WriteByte(0x2004, light_up); //写入【光强上限值】数据保存
    WriteByte(0x2005, light_down); //写入【光强下限值】数据保存
    WriteByte(0x2006, mode); //写入【模式】数据保存
}

void ReadData(void)
{
    ds[0] = ReadByte(0x2000);      //读取存储的【定时时间】数据
    ds[1] = ReadByte(0x2001);      //读取存储的【定时时间】数据
    ds[2] = ReadByte(0x2002);      //读取存储的【定时时间】数据
    ds[3] = ReadByte(0x2003);      //读取存储的【定时时间】数据
    light_up = ReadByte(0x2004);   //读取存储的【光强上限值】数据
    light_down = ReadByte(0x2005); //读取存储的【光强下限值】数据
    mode = ReadByte(0x2006);       //读取存储的【模式】数据
}

/********************************************************
函数名称:void display(void)
函数作用:正常显示日期、时间、光强等函数
参数说明:
********************************************************/
void display(void)
{
    uint t[3];

    //显示时间
    LCD_DispOneChar(0, 1, dis[time[2] / 10]); //显示时【0:表示第1列,2:表示第2行,所有关于显示都一样】
    LCD_DispOneChar(1, 1, dis[time[2] % 10]);
    LCD_DispOneChar(2, 1, ':');
    LCD_DispOneChar(3, 1, dis[time[1] / 10]); //显示分【3:表示第4列,2:表示第2行,所有关于显示都一样】
    LCD_DispOneChar(4, 1, dis[time[1] % 10]);
    LCD_DispOneChar(5, 1, ':');
    LCD_DispOneChar(6, 1, dis[time[0] / 10]); //显示秒
    LCD_DispOneChar(7, 1, dis[time[0] % 10]);

    //显示日期
    LCD_DispOneChar(0, 0, dis[time[6] / 10]); //显示年
    LCD_DispOneChar(1, 0, dis[time[6] % 10]);
    LCD_DispOneChar(2, 0, '/');
    LCD_DispOneChar(3, 0, dis[time[4] / 10]); //显示月
    LCD_DispOneChar(4, 0, dis[time[4] % 10]);
    LCD_DispOneChar(5, 0, '/');
    LCD_DispOneChar(6, 0, dis[time[3] / 10]); //显示日
    LCD_DispOneChar(7, 0, dis[time[3] % 10]);

    //显示模式
    LCD_DispStr(9, 0, display_mode[mode]);

    //显示光强
    if (light > 99)
        LCD_DispOneChar(12, 0, dis[light / 100]);
    else
        LCD_DispOneChar(12, 0, ' ');
    LCD_DispOneChar(13, 0, dis[light % 100 / 10]);
    LCD_DispOneChar(14, 0, dis[light % 10]);
    LCD_DispOneChar(15, 0, '%');

    //光强控制
    if (mode == 2) //光控模式
    {
        if ((light >= light_up || light < light_down)) //判断实际光强是否【大于等于上限 或 小于下限值】、当前处于打开状态
        {
            moto_f = 0;     //标记当前控制窗帘关闭
            motor_state = 1; //标记窗帘处于运转过程中
        }
        else if ((light < light_up && light >= light_down)) //判断实际光强是否【大于等于下限值 并且 小于上限】、当前处于关闭状态
        {
            moto_f = 1;     //标记当前控制窗帘打开
            motor_state = 1; //标记窗帘处于运转过程中
        }
    }
    else if (mode == 1) //定时模式
    {
        t[0] = time[2] * 60 + time[1]; //当前时间
        t[1] = ds[0] * 60 + ds[1];     //窗帘开启时间点
        t[2] = ds[2] * 60 + ds[3];     //窗帘关闭时间点

        if (t[1] < t[2]) //0时 --> t[1] --> t[2] --> 24时
        {
            if (t[0] >= t[1] && t[0] <= t[2])
                moto_f = 1; //标记当前需要打开窗帘
            else
                moto_f = 0; //标记当前需要关闭窗帘
        }
        else //0时 --> t[2] --> t[1] --> 24时
        {
            if (t[0] >= t[1] || t[0] <= t[2])
                moto_f = 1; //标记当前需要打开窗帘
            else
                moto_f = 0; //标记当前需要关闭窗帘
        }
        motor_state = 1; //标记窗帘处于运转过程中
    }

    if (moto_f == 0 && motor_state != 0 && SW1 != 0) //控制关闭窗帘
    {
        if (moto_num == 0) //控制次数减到0时,表示窗户已经关闭完成
        {
            BYJ48 = BYJ48 & 0xf0; //关闭步进电机
            motor_state = 0;    //标记窗帘处于关闭状态
            LCD_DispStr(10, 1, "ZT:OFF");
        }
        else
        {
            motor_z();  //步进电机正转
            moto_num--; //控制次数-1
            LCD_DispStr(10, 1, "-->OFF");
        }
    }
    else if (moto_f == 1 && motor_state != 2 && SW1 != 0) //控制打开窗帘
    {
        if (moto_num >= 192) //控制次数加到192时,表示窗户已经打开完成
        {
            BYJ48 = BYJ48 & 0xf0; //关闭步进电机
            motor_state = 2;    //标记窗帘处于打开状态
            LCD_DispStr(10, 1, "ZT:ON ");
        }
        else
        {
            motor_f();  //步进电机反转
            moto_num++; //控制次数+1
            LCD_DispStr(10, 1, "-->ON ");
        }
    }
    else //窗户处于停止状态
    {
        BYJ48 = BYJ48 & 0xf0; //关闭步进电机
        if (motor_state == 0)
            LCD_DispStr(10, 1, "ZT:OFF");
        else if (motor_state == 2)
            LCD_DispStr(10, 1, "ZT:ON ");
    }
}
/********************************************************
函数名称:void display2(void)
函数作用:显示调整日期、时间函数
参数说明:
********************************************************/
void display2()
{
    num++;

    LCD_DispStr(1, 0, "Date:");
    LCD_DispStr(1, 1, "Time:");

    if (num % 2 == 0) //偶数次显示,奇数次不显示。这样就会有闪烁效果,可以清楚看到当前设置的是哪个值
    {
        LCD_DispOneChar(6, 0, dis[time[6] / 10]); //显示年
        LCD_DispOneChar(7, 0, dis[time[6] % 10]);
        LCD_DispOneChar(8, 0, '/');
        LCD_DispOneChar(9, 0, dis[time[4] / 10]); //显示月
        LCD_DispOneChar(10, 0, dis[time[4] % 10]);
        LCD_DispOneChar(11, 0, '/');
        LCD_DispOneChar(12, 0, dis[time[3] / 10]); //显示日
        LCD_DispOneChar(13, 0, dis[time[3] % 10]);

        LCD_DispOneChar(6, 1, dis[time[2] / 10]); //显示时
        LCD_DispOneChar(7, 1, dis[time[2] % 10]);
        LCD_DispOneChar(8, 1, ':');
        LCD_DispOneChar(9, 1, dis[time[1] / 10]); //显示分
        LCD_DispOneChar(10, 1, dis[time[1] % 10]);
        LCD_DispOneChar(11, 1, ':');
        LCD_DispOneChar(12, 1, dis[time[0] / 10]); //显示秒
        LCD_DispOneChar(13, 1, dis[time[0] % 10]);
    }
    else //奇数次不显示
    {
        switch (set_f) //根据当前设置的内容,对应位置闪烁
        {
        case 1:
            LCD_DispStr(6, 0, "  ");
            break;
        case 2:
            LCD_DispStr(9, 0, "  ");
            break;
        case 3:
            LCD_DispStr(12, 0, "  ");
            break;
        case 4:
            LCD_DispStr(6, 1, "  ");
            break;
        case 5:
            LCD_DispStr(9, 1, "  ");
            break;
        case 6:
            LCD_DispStr(12, 1, "  ");
            break;
        default:
            break;
        }
    }
}
/********************************************************
函数名称:void display3(void)
函数作用:显示调整定时时间函数
参数说明:
********************************************************/
void display3()
{
    num++;
    LCD_DispStr(0, 0, "Sets timer time:");
    LCD_DispStr(7, 1, "--");
    if (num % 2 == 0) //偶数次显示,奇数次不显示。这样就会有闪烁效果,可以清楚看到当前设置的是哪个值
    {
        LCD_DispOneChar(1, 1, dis[ds[0] / 10]); //显示定时开-时
        LCD_DispOneChar(2, 1, dis[ds[0] % 10]);
        LCD_DispOneChar(3, 1, ':');
        LCD_DispOneChar(4, 1, dis[ds[1] / 10]); //显示定时开-分
        LCD_DispOneChar(5, 1, dis[ds[1] % 10]);

        LCD_DispOneChar(10, 1, dis[ds[2] / 10]); //显示定时关-时
        LCD_DispOneChar(11, 1, dis[ds[2] % 10]);
        LCD_DispOneChar(12, 1, ':');
        LCD_DispOneChar(13, 1, dis[ds[3] / 10]); //显示定时关-分
        LCD_DispOneChar(14, 1, dis[ds[3] % 10]);
    }
    else //奇数次不显示
    {
        switch (set_f) //根据当前设置的内容,对应位置闪烁
        {
        case 7:
            LCD_DispStr(1, 1, "  ");
            break;
        case 8:
            LCD_DispStr(4, 1, "  ");
            break;
        case 9:
            LCD_DispStr(10, 1, "  ");
            break;
        case 10:
            LCD_DispStr(13, 1, "  ");
            break;
        default:
            break;
        }
    }
}
/********************************************************
函数名称:void display4(void)
函数作用:显示调整光强控制函数
参数说明:
********************************************************/
void display4(void)
{
    num++;

    LCD_DispStr(0, 0, "Light_Up  :");
    LCD_DispStr(0, 1, "Light_Down:");
    LCD_DispOneChar(15, 0, '%');
    LCD_DispOneChar(15, 1, '%');
    if (num % 2 == 0) //偶数次显示,奇数次不显示。这样就会有闪烁效果,可以清楚看到当前设置的是哪个值
    {
        LCD_DispOneChar(12, 0, dis[light_up / 100]); //显示光强上限值
        LCD_DispOneChar(13, 0, dis[light_up % 100 / 10]);
        LCD_DispOneChar(14, 0, dis[light_up % 10]);

        LCD_DispOneChar(12, 1, dis[light_down / 100]); //显示光强下限值
        LCD_DispOneChar(13, 1, dis[light_down % 100 / 10]);
        LCD_DispOneChar(14, 1, dis[light_down % 10]);
    }
    else //奇数次不显示
    {
        switch (set_f) //根据当前设置的内容,对应位置闪烁
        {
        case 11:
            LCD_DispStr(12, 0, "   ");
            break;
        case 12:
            LCD_DispStr(12, 1, "   ");
            break;
        default:
            break;
        }
    }
}
/********************************************************
函数名称:void KeyScan(void)
函数作用:按键查询处理函数
参数说明:
********************************************************/
void KeyScan(void)
{
    //设置键
    if (hw_data == 'B' || KEY_MODE == 0) //按键按下
    {
        DelayMs(50);                        //延时消抖
        if (hw_data == 'B' || KEY_MODE == 0) //再次确认按键按下
        {
            BUZZER = 0;
            DelayMs(130);
            BUZZER = 1;
            BYJ48 = BYJ48 & 0xf0; //关闭步进电机
            if (set_f == 6)    //日期、时间校准完
            {
                LCD_Clear(); //清除屏幕显示
                DelayMs(4);;        //延时等待全部清除完毕
                set_f = 13;              //跳到校准窗帘状态
            }
            else if (set_f == 0) //进入设置先清除屏幕,显示设置部分
            {
                Write_DS1302(WRITE_PROTECT, 0X00); //禁止DS1302写保护
                LCD_Clear();          //清除屏幕显示
                DelayMs(4);;                 //延时等待全部清除完毕
                switch (mode)                     //根据对应的模式,设置对应的参数
                {
                case 0:
                    set_f = 1;
                    break; //手动模式
                case 1:
                    set_f = 7;
                    break; //定时模式
                case 2:
                    set_f = 11;
                    break; //光控模式
                default:
                    break;
                }
            }
            else if (set_f == 10 || set_f == 12) //进入设置日期时间
            {
                LCD_Clear(); //清除屏幕显示
                DelayMs(4);;        //延时等待全部清除完毕
                set_f = 1;               //进入校准时间
            }
            else
                set_f++; //设置变量+1
            if (set_f > 12)
            {
                set_f = 0; //重置设置变量

                Write_DS1302(WRITE_MINUTE, (time[1] / 10) * 16 + time[1] % 10); //将设置好的时间写入DS1302
                Write_DS1302(WRITE_SECOND, (time[0] / 10) * 16 + time[0] % 10);

                WriteData();

                LCD_Clear(); //清除屏幕显示
                DelayMs(4);;        //延时等待全部清除完毕
            }
        }
        while (!KEY_MODE)
            ; //等待按键松开
    }
    //确定
    if (hw_data == '|' || KEY_ENTER == 0) //按键按下
    {
        DelayMs(50);                                        //延时消抖
        if ((hw_data == '|' || KEY_ENTER == 0) && set_f != 0) //再次确认按键按下
        {
            BUZZER = 0;
            DelayMs(130);
            BUZZER = 1;
            if (set_f < 7)
            {
                Write_DS1302(WRITE_MINUTE, (time[1] / 10) * 16 + time[1] % 10); //将设置好的时间写入DS1302
                Write_DS1302(WRITE_SECOND, (time[0] / 10) * 16 + time[0] % 10);
            }
            set_f = 0; //重置设置变量

            WriteData();

            LCD_Clear(); //清除屏幕显示
            DelayMs(4);;        //延时等待全部清除完毕
        }
        else if (KEY_ENTER == 0 && set_f == 0) //切换模式
        {
            mode++;              //模式变量+1
            if (mode >= 3)       //最大3个模式
                mode = 0;        //重新回到第1个模式
            if (motor_state == 1) //如果处于运转过程中
            {
                if (moto_f == 0) //控制步进电机关闭
                    motor_state = 0;
                else //控制步进电机打开
                    motor_state = 2;
            }
            WriteData();
        }
        while (!KEY_ENTER)
            ; //等待按键松开
    } 作者:极寒钛科技 https://www.bilibili.com/read/cv20281890 出处:bilibili

实物演示视频:
https://www.bilibili.com/video/BV1PV4y1L7nH/文章来源地址https://www.toymoban.com/news/detail-505757.html

到了这里,关于基于STM32单片机的智能家居窗户窗帘控制系统红外遥控proteus仿真原理图PCB的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包