智能家居控制系统

一、摘要

智能家居作为家庭信息化的实现方式,已经成为社会信息化发展的重要组成部分,物联网其巨大的应用前景,是智能家居产业发展过程中一个比较现实的突破口,对智能家居的产业发展具有重大意义。本文基于容易实现,方便操作,贴近使用的设计理念,设计的智能家居控制系统是以 STC89C52 单片机为主控器件,通过按键和红外通讯模块进行数据交换。主控器件为核心,通过键盘输入和修改门禁密码、关锁,以及人工控制灯和风扇的开关;通过红外通讯远程开锁和人工开关风扇;用传感器和时钟模块获取温度和时间,并利用 LCD1602 液晶屏显示温度时间以及输入密码的‘*’和修改的密码。

二、题目要求

基于物联网的智能家居控制系统。

可涉及到的部分核心元器件:51 单片机、运算放大器、稳压管、电位器、电阻电容(不限)、继电器、二/三极管、数码管、轻触按键、IC 插座、双列直插、红外接收器,计数芯片、数码管显示芯片、GPS 定位模块、GSM 通信模块、新型太阳能电池板、高精度视频识别摄像头、语音识别与存储模块、LED 显示模块。

三、方案说明

以 STC89C52 为主控芯片,以矩阵键盘输入密码,以独立按键确认、清除、进入修改密码界面和锁门(关密码锁),输入密码错误 3 次以后进行蜂鸣器报警,并锁定键盘,只能用红外遥控开锁;修改密码后会用 EEPROM 进行保存;以矩阵键盘和红外遥控共同人工控制灯和风扇的开关,用 DS1302 时钟芯片进行计时,用 DS18B20 数字温度传感器获取温度,当温度和时间达到设定的值时,会自动开启风扇和灯,智能开启的灯和风扇是可自动调节的,风扇的转速会比人工开启的稍慢,而灯会根据光强自动调节亮度,其中风扇使用 ULN2003 直流电机驱动模块控制,灯光的调节是通过 PCF8591 数模转换模块和光敏电阻控制。开密码所后,会显示当前温度时间和是否开启灯和风扇;显示部分使用的是 LCD1602 液晶,红外接收用的是 HS0038 红外接收模块。

四、软硬件设计

4.1 主控电路部分:

4.2 功能电路部分:

4.2.1 红外通讯:

利用单片机 P3.2IO 口接收红外数据。

红外模块代码:

由于这里代码都有例程,所以仅贴出.h 部分。

# ifndef__INFRARED_H
# define__INFRARED_H
# include"Sys.h"
voidinit();//对红外通讯所使用到的外部中断0和定时器0初始化
voidIRcordpro();//把提取的33次脉宽解码NEC协议
# endif

4.2.2 DS18B20:

利用单片机 P2.2IO 口控制其收发数据。

DS18B20 模块代码:

由于这里代码都有例程,所以仅贴出.h 部分。

# ifndef__DS18B20_H
# define__DS18B20_H
# include"Sys.h"
sbitds=P2^2;
voiddsInit();//单总线初始化时序
voiddsWait();//延时37.95us等待18B20发回存在信号
bitreadBit();//读一位数据
unsignedcharreadByte();//读一个字节数据
voidwriteByte(unsignedchardat);//写一个字节数据
voidsendChangeCmd();//发送温度转换命令
voidsendReadCmd();//发送读命令
intgetTmpValue();//获取温度
voiddisplayTemp(intv);//用LCD1602显示温度
# endif

4.2.3 DS1302:

DS1302 模块代码:

由于这里代码都有例程,所以仅贴出.h 部分。

# ifndef__DS1302_H
# define__DS1302_H
# include"Sys.h"
sbitTSCLK=P1^0;//时钟
sbitTIO=P1^1;//数据
sbitTRST=P1^2;//使能
# defineMAIN_Fosc11059200UL//宏定义主时钟HZ
# defineDS1302_W_ADDR0x80//写时钟日历寄存器起始地址
# defineDS1302_R_ADDR0x81//读时钟日历寄存器起始地址
voidSet_DS1302_Time(ucharaddr);//设置时间
voidRead_DS1302_Time(ucharaddr);//读取时间
ucharDat_Chg_BCD(uchardat);//10进制数据转BCD
ucharBCD_Chg_Dat(uchardat);//BCD转10进制数据
# endif

4.2.4 LCD1602:

LCD1602 模块代码:

这里对例程代码进行了扩充,所以放出完整代码。

1.   #ifndef __LCD1602_H
2.  #define __LCD1602_H
3.  #include "Sys.h"
4.  #define LCD1602_DB  P0      //data bus 数据总线
5.  sbit LCD1602_RS = P3^5;
6.  sbit LCD1602_RW = P3^6;
7.  sbit LCD1602_EN = P3^4;
8.  void Read_Busy();           //忙检测函数,判断bit7是0,允许执行;1禁止
9.  void Lcd1602_Write_Cmd(unsigned char cmd);     //写命令
10. void Lcd1602_Write_Data(unsigned char dat);   //写数据
11. void LcdSetCursor(unsigned char x,unsigned char y);   //设置坐标
12. void DisplayOneChar (uchar X,uchar Y,uchar DData); // 写一个字节
13. void DisplayOneStr (uchar X,uchar Y,uchar DData);//显示一个字节字符
14. void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);     //显示字符串
15. void InitLcd1602();              //1602初始化
16. #endif
1.   #include "Sys.h"
2.  void Read_Busy()           //忙检测函数,判断bit7是0,允许执行;1禁止
3.  {
4.      unsigned char sta;      //
5.      LCD1602_DB = 0xff;
6.      LCD1602_RS = 0;
7.      LCD1602_RW = 1;
8.      do
9.      {
10.         LCD1602_EN = 1;
11.         sta = LCD1602_DB;
12.         LCD1602_EN = 0;    //使能,用完就拉低,释放总线
13.     }while(sta & 0x80);
14. }
15. void Lcd1602_Write_Cmd(unsigned char cmd)     //写命令
16. {
17.     Read_Busy();
18.     LCD1602_RS = 0;
19.     LCD1602_RW = 0;
20.     LCD1602_DB = cmd;
21.     LCD1602_EN = 1;
22.     LCD1602_EN = 0;
23. }
24. void Lcd1602_Write_Data(unsigned char dat)   //写数据
25. {
26.       Read_Busy();
27.       LCD1602_RS = 1;
28.       LCD1602_RW = 0;
29.       LCD1602_DB = dat;
30.       LCD1602_EN = 1;
31.       LCD1602_EN = 0;
32. }
33. void LcdSetCursor(unsigned char x,unsigned char y)  //设置坐标
34. {
35.     unsigned char addr;
36.     if(y == 0)
37.         addr = 0x00 + x;
38.     else
39.         addr = 0x40 + x;
40.
41.     Lcd1602_Write_Cmd(addr|0x80);
42. }
43. void DisplayOneChar (uchar X,uchar Y,uchar DData)//显示一个字节数据
44. {
45.  if(Y) X|=0X40;   //Y=1显示第二行,Y=0显示第一行
46.  X|=0X80;
47.  Lcd1602_Write_Cmd(X); //X用来选择哪一位
48.  Lcd1602_Write_Data(DData); //DData用来写数据
49. }
50. //显示一个字节字符
51. void DisplayOneStr (uchar X,uchar Y,uchar DData)
52. {
53.     DisplayOneChar (X++,Y,DData/16 + '0');
54.     DisplayOneChar (X,Y,DData%16 + '0');
55. }
56. void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)     //显示字符串
57. {
58.     LcdSetCursor(x,y);      //当前字符的坐标
59.     while(*str != '\0')
60.     {
61.         Lcd1602_Write_Data(*str++);
62.     }
63. }
64. void InitLcd1602()              //1602初始化
65. {
66.     Lcd1602_Write_Cmd(0x38);    //打开,5*8,8位数据
67.     Lcd1602_Write_Cmd(0x0c);
68.     Lcd1602_Write_Cmd(0x06);
69.     Lcd1602_Write_Cmd(0x01);    //清屏
70. }

4.2.5 ULN2003:

ULN2003 可直接驱动继电器等负载,所以我们用来驱动风扇电机,否则电机直接接在单片机 IO 口是不转的,ULN2003 内部是 7 个独立的非门电路。

ULN2003 模块代码:

由于这里代码都有例程,所以仅贴出.h 部分。

# ifndef__ULN2003_H
# define__ULN2003_H
# include"Sys.h"
sbit_4IN=P2^7;
# endif

4.2.6 IIC 及 EEPROM(使用 IIC 协议交换数据):

利用单片机 P2.0 和 P2.1 分别作为通信的数据线和时钟线。

由于这里代码都有例程,所以仅贴出.h 部分。

# ifndef__IIC_H
# define__IIC_H
# include"Sys.h"
# defineAT24C02_ADDR0xa0//AT24C02地址
/*I2CIO口定义*/
sbitSDA=P2^0;
sbitSCL=P2^1;
voidI2C_init();//I2C初始化
voidI2C_Start();/*I2C起始信号*/
voidI2C_Stop();/*I2C终止信号*/
voidMaster_ACK(biti);/*主机发送应答*/
bitTest_ACK();/*检测从机应答*/
voidI2C_send_byte(ucharbyte);/*发送一个字节*/
ucharI2C_read_byte();/*I2C读一字节*/
bitI2C_TransmitData(ucharADDR,ucharDAT);//I2C发送数据
ucharI2C_ReceiveData(ucharADDR);//I2C接收数据
# endif

4.2.7 PCF8591(使用 IIC 通信协议交换数据):

利用单片机 P2.0 和 P2.1 分别作为通信的数据线和时钟线。

PCF8591 模块代码:

由于这里代码都有例程,所以仅贴出.h 部分。

# ifndef__PCF8591_H
# define__PCF8591_H
# include"Sys.h"
# definePCF8591_ADDR0x90//PCF8591地址
# defineDACOUT_EN0x40//DAC输出使能
bitDAC_OUT(ucharDAT);//DAC输出
bitADC_Read(ucharCON);//读AD数据
# endif

4.2.8 蜂鸣器:

利用单片机 P2.3IO 口控制蜂鸣器,低电平响,高电平不响。代码过于简单,不再单独展出。

4.2.9 矩阵键盘和独立键盘:

使用 P3IO 口,此次使用的单片机的 LCD1602 也是用 P3,所以相冲突,故对例程代码进行了修改。

1.   #ifndef __KEY_H
2.  #define __KEY_H
3.  #include "Sys.h"
4.  uchar KeyScan();    //带返回值的子函数
5.  #endif
1.   #include "Sys.h"
2.  void delay(uint z)
3.  {
4.      uint x,y;
5.      for(x = z; x > 0; x--)
6.          for(y = 114; y > 0 ; y--);
7.  }
8.  //将例程中按键扫描修改,先扫描行,再扫描列,不然会与LCD1602冲突
9.  uchar KeyScan() //带返回值的子函数
10. {
11.     uchar KeyValue=22;
12.     P3 = 0x0f;//判断哪一行被按下
13.     if(P3 != 0x0f)
14.     {
15.         delay(5);//软件消抖
16.         if( P3 != 0x0f)
17.         {
18.             switch(P3)
19.             {
20.                 case 0x0e:  KeyValue = 0;   break;
21.                 case 0x0d:  KeyValue = 4;   break;
22.                 case 0x0b:  KeyValue = 8;   break;
23.                 case 0x07:  KeyValue = 12;  break;
24.             }
25.             P3 = 0xf0;//判断哪一列被按下
26.             switch(P3)
27.             {
28.                 case 0xe0:  KeyValue = KeyValue;    break;
29.                 case 0xd0:  KeyValue += 1;  break;
30.                 case 0xb0:  KeyValue += 2;  break;
31.                 case 0x70:  KeyValue += 3;  break;
32.             }
33.             while(P3 != 0xf0);//松手检测
34.         }
35.     }
36.     P3 = 0xff;//判断独立按键
37.     if(P3 != 0xff)
38.     {
39.         delay(5);//软件消抖
40.         if( P3 != 0xff)
41.         {
42.             switch(P3)
43.             {
44.                 case 0xfe:  KeyValue = 16;  break;
45.                 case 0xfd:  KeyValue = 17;  break;
46.                 case 0xfb:  KeyValue = 18;  break;
47.                 case 0xf7:  KeyValue = 19;  break;
48.             }
49.             while(P3 != 0xff);//松手检测
50.         }
51.     }
52.     if(KeyValue!=22&&(KeyValue>9&&KeyValue<16))//a~f,+39
53.     {
54.         KeyValue+=39;
55.     }
56.     return KeyValue;
57. }

4.3 主要头文件:

采用多文件的方法编程,利于阅读、修改和移植,将所有头文件放于 Sys 中,每个.c 中仅需加入 Sys.h 头文件。

# ifndef__SYS_H
# define__SYS_H
# defineucharunsignedchar
# defineuintunsignedint
# defineLightOn255
# defineLightOff0
# defineFanOn1
# defineFanOff0
# defineHuman1
# defineMachine0
# include<reg52.h>
# include"Delay.h"
# include"Key.h"
# include"InfraRed.h"
# include"Secret.h"
# include<intrins.h>
# include"LCD1602.h"
# include<string.h>
# include"DS18B20.h"
# include<math.h>
# include"DS1302.h"
# include"IIC.h"
# include"PCF8591.h"
# include"ULN2003.h"
sbitDUAN=P2^6;
sbitWEI=P2^7;
sbitBeep=P2^3;
# endif

4.4 功能模块调用以及主要逻辑部分:

4.4.1 Secret.h、Secret.c:

# ifndef__SECRET_H
# define__SECRET_H
# include"Sys.h"
# defineLockOff1
# defineLockOn0
voidKeyAction();
intmake_sure();
ucharchangesecret();
# endif
1.   #include "Sys.h"
2.  #include <string.h>
3.
4.
5.  uchar password_original[5]={1,2,3,4,5};//原密码
6.  uchar temp_password[5]={0,0,0,0,0};
7.
8.
9.  uchar chance=3;
10. uchar Lock=LockOn;
11. uint Beeptime;
12.
13. extern uchar choosemode;
14.
15. void KeyAction()
16. {
17.     uchar Input=22;
18.     static uchar keyWei=0;
19.
20.     Input=KeyScan();
21.     if(Input!=22&&keyWei<5&&Input!=16&&Input!=17&&Input!=18&&Input!=19)
22.     {
23.         temp_password[keyWei]=Input;
24.         DisplayOneChar(6+keyWei,1,'*');
25.         keyWei++;
26.     }
27.     if(Input==16)//密码确认
28.     {
29.         keyWei=0;
30.         if(make_sure()==0)//输入错误
31.         {
32.             LcdShowStr(6,1,"     ");
33.             chance--;
34.             Beeptime=0;
35.         }
36.         else//输入正确
37.         {
38.             keyWei=0;
39.             choosemode=1;
40.             chance=3;
41.             Lock=LockOff;
42.         }
43.     }
44.     if(Input==17)//清除
45.     {
46.         uchar i=0;
47.         keyWei=0;
48.         Lcd1602_Write_Cmd(0x80);
49.         for(i=0;i<5;i++)
50.         {
51.             LcdShowStr(6,1,"     ");
52.             temp_password[i]=0;
53.         }
54.     }
55. }
56.
57. int make_sure()
58. {
59.     unsigned char i=0;
60.     for(i;i<5;i++)
61.     {
62.         if(temp_password[i]!=password_original[i])
63.         {
64.             return 0;
65.         }
66.     }
67.     return 1;
68. }
69.
70. uchar changesecret()
71. {
72.     uchar Input=22;
73.     static uchar keyWei=0;
74.     Input=KeyScan();
75.     if(Input!=22&&keyWei<5&&Input!=16&&Input!=17&&Input!=18&&Input!=19)
76.     {
77.         temp_password[keyWei]=Input;
78.         DisplayOneChar(11+keyWei,1,Input+'0');
79.         keyWei++;
80.     }
81.     if(Input==16&&keyWei==5)
82.     {
83.         uchar i;
84.         keyWei=0;
85.         strcpy(password_original,temp_password);
86.         for(i=0;i<5;i++)
87.         {
88.             temp_password[i]=0;
89.         }
90.         Lcd1602_Write_Cmd(0x01);
91.         for(i=1;i<6;i++)
92.         {
93.             I2C_TransmitData(i,password_original[i-1]);
94.             Delayms(5);
95.         }
96.         LcdShowStr(0,0,"Changed.");
97.         Delayms(3000);
98.         Lcd1602_Write_Cmd(0x01);
99.         choosemode=1;
100.            return 1;
101.        }
102.        if(Input==17)
103.        {
104.            uchar i=0;
105.            keyWei=0;
106.            Lcd1602_Write_Cmd(0x01);
107.            for(i=0;i<5;i++)
108.            {
109.                temp_password[i]=0;
110.            }
111.        }
112.        return 0;
113.    }

main.c

1.   //由于红外和独立、矩阵键盘都是用的P3(红外P3.2),所以当开锁后使用红外,然后关锁后,第一次输入密码会在后面一点
2.
3.  #include "Sys.h"
4.  int temp=0;//接收到的温度值,有正负,用于判断
5.  extern uchar password_original[5];//原密码
6.  extern uchar IRcord[4]; //储存解码后的4个字节数据,用户码,用户码,数据码,数据反码
7.  extern uchar IRdata[33];//包含起始码在内的33位数据
8.  extern uchar Lock;
9.  extern uchar chance;
10. extern uint Beeptime;
11. uchar choosemode=0;
12. extern bit IRpro_ok;    //解码后4个字节数据接收完成标志位
13. extern bit IRok;//33位数据接收完成标志位
14. extern uchar TimeData[7];
15. uchar readflag=0;//是否读取温度和时间
16. extern uchar AD_Value;  //存储AD转换回的数字量
17. extern unsigned char pwm_motor_val;//左右电机占空比值,越小快
18. extern unsigned char pwm_t;//周期
19. extern unsigned char datas[5];//温度值
20. uchar LightControl=Machine;
21. //等于Human:人为控制,LightHuman有效,LightMachine失效,等于Machine:智能控制,LightMachine失效,LightMachine有效
22. uchar LightHuman=LightOff;
23. uchar LightMachine=LightOff;
24.
25. uchar FanControl=Machine;
26. //等于Human:人为控制,LightHuman有效,LightMachine失效,等于Machine:智能控制,LightMachine失效,LightMachine有效
27. uchar FanHuman=FanOff;
28. uchar FanMachine=FanOff;
29.
30. void choose(uchar i);
31. //void openstring();
32. void Timer1Init();
33. sbit LED1= P1^0;   //读取AD的值是否成功(亮成功,灭失败)
34. sbit LED2= P1^1;   //DAC成功输出(亮成功,灭失败)
35. void main()
36. {
37.
38.     uchar i=0;
39.     Timer1Init();
40.     InitLcd1602();
41.     I2C_init();
42. //  while(1)//测试光敏电阻和DA输出
43. //  {
44. //
45. //      if (ADC_Read(0x00)) LED1 = 0;   else    LED1 = 1;
46. //      AD_Value=LightOff;
47. //      if (DAC_OUT(AD_Value))  LED2 = 0;   else    LED2 = 1;
48. //      DisplayOneChar(0,0,AD_Value);
49. //      Delayms(5);
50. //  }
51.
52. //  for(i=1;i<6;i++)//用于写第一次的密码到EEPROM
53. //  {
54. //      I2C_TransmitData(i,password_original[i-1]);
55. //      Delayms(5);
56. //  }
57.
58.     Delayms(5);
59.     for(i=1;i<6;i++)
60.     {
61.         password_original[i-1]=I2C_ReceiveData(i);//从EEPROM读取密码,一次一位,一共5次
62.         Delayms(5);
63.     }
64.     init();//红外线定时器0和外部中断0初始化
65.     DUAN=0;
66.     WEI=0;
67.
68.     Set_DS1302_Time(DS1302_W_ADDR); //先写入时钟日历寄存器起始地址再设置时钟日历初值
69.     while(1)
70.     {
71.         choose(choosemode);
72.     }
73. }
74.
75. void choose(uchar i)
76. {
77.
78.     uchar Input=22;
79.     switch(i)
80.     {
81.         case 0://*******************************************************已关门,输入密码
82.             Lcd1602_Write_Cmd(0x01);//清除上一次所显示的模式的内容
83.             LcdShowStr(0,0,"Input secret.");
84.             while(1)
85.             {
86.                 if(IRok)
87.                 {
88.                     IRcordpro();//根据脉宽解码出4个字节数据
89.                     IRok=0;//清零脉宽检查完成标志位等待下一次脉宽检查
90.                     if(IRpro_ok)//判断是否解码完成
91.                     {
92.                         if(IRcord[2]==0x45)//开锁
93.                         {
94.                             Lock=LockOff;
95.                             choosemode=1;
96.                         }
97.                         else if(IRcord[2]==0x0c)//开灯
98.                         {
99.                             LightControl=Human;
100.                                LightHuman=LightOn;
101.                            }
102.                            else if(IRcord[2]==0x18)//关灯
103.                            {
104.                                LightControl=Human;
105.                                LightHuman=LightOff;
106.                            }
107.                            else if(IRcord[2]==0x5e)//智能灯
108.                            {
109.                                LightControl=Machine;
110.                                LightHuman=LightOff;
111.                            }
112.                            else if(IRcord[2]==0x08)//开风扇
113.                            {
114.                                FanControl=Human;
115.                                FanHuman=FanOn;
116.                            }
117.                            else if(IRcord[2]==0x1c)//关风扇
118.                            {
119.                                FanControl=Human;
120.                                FanHuman=FanOff;
121.                            }
122.                            else if(IRcord[2]==0x5a)//智能风扇
123.                            {
124.                                FanControl=Machine;
125.                                FanHuman=FanOff;
126.                            }
127.                            IRpro_ok=0;//清零解码完成标志位
128.                        }
129.                    }
130.                    if(LightControl==Human)
131.                    {
132.                        AD_Value=LightHuman;
133.                    }
134.                    else if(LightControl==Machine)
135.                    {
136.                        AD_Value=LightOff;
137.                    }
138.                    DAC_OUT(AD_Value);
139.
140.                    if(chance>0)
141.                    {
142.                        LcdShowStr(0,1,"Input:");
143.                        DisplayOneChar(15,0,chance+'0');
144.                        KeyAction();
145.                    }
146.                    else
147.                    {
148.                        LcdShowStr(0,0,"Only Inred open!");
149.                        LcdShowStr(0,1,"      ");
150.
151.
152.                        if(Beeptime==0)
153.                        {
154.                            Beep=0;//蜂鸣器报警
155.                        }
156.                        if(Beep==0)
157.                        {
158.                            Beeptime++;
159.                            if(Beeptime>100)
160.                                Beep=1;//蜂鸣器停止
161.                        }
162.                    }
163.                    if(Lock==LockOff)
164.                    {
165.                        InitLcd1602();
166.                        break;
167.                    }
168.                }
169.                break;
170.            case 1://**********************************************************已开门,显示温度时间
171.    //          Timer1Init();
172.    //      ET1=1;
173.    //      TR1=1;
174.                while(1)
175.                {
176.
177.                    Input=22;
178.    //              openstring();
179.                    Input=KeyScan();
180.                    if(IRok)
181.                    {
182.                        IRcordpro();//根据脉宽解码出4个字节数据
183.                        IRok=0;//清零脉宽检查完成标志位等待下一次脉宽检查
184.                        if(IRpro_ok)//判断是否解码完成
185.                        {
186.                            if(IRcord[2]==0x0c)
187.                            {
188.                                LightControl=Human;
189.                                LightHuman=LightOn;
190.                            }
191.                            else if(IRcord[2]==0x18)
192.                            {
193.                                LightControl=Human;
194.                                LightHuman=LightOff;
195.                            }
196.                            else if(IRcord[2]==0x5e)
197.                            {
198.                                LightControl=Machine;
199.                                LightHuman=LightOff;
200.                            }
201.                            else if(IRcord[2]==0x08)//开风扇
202.                            {
203.                                FanControl=Human;
204.                                FanHuman=FanOn;
205.                            }
206.                            else if(IRcord[2]==0x1c)//关风扇
207.                            {
208.                                FanControl=Human;
209.                                FanHuman=FanOff;
210.                            }
211.                            else if(IRcord[2]==0x5a)//智能灯
212.                            {
213.                                FanControl=Machine;
214.                                FanHuman=FanOff;
215.                            }
216.                            else if(IRcord[2]==0x47)
217.                            {
218.                                choosemode=0;
219.                                chance=3;
220.                                Lock=LockOn;
221.                                ET1=0;TR1=0;
222.                                LightControl=Machine;
223.                                AD_Value=LightOff;
224.                                break;
225.                            }
226.                            IRpro_ok=0;//清零解码完成标志位
227.                        }
228.                    }
229.                    if(readflag==1)//达到1秒进行读取温度、日期和时间
230.                    {
231.                        readflag=0;
232.                        //温度显示
233.                        temp=getTmpValue();
234.                        displayTemp(temp);
235.                        sendChangeCmd();//温度转换,给下一次用
236.    //                  DisplayOneChar(13,1,'*');
237.
238.                        //时间显示
239.                        Read_DS1302_Time(DS1302_R_ADDR); //先写入时钟日历寄存器起始地址再读出时钟日历写入到TimeData数组中
240.                        DisplayOneStr (8,0,TimeData[6]); //年
241.                        DisplayOneChar (10,0,'-');       //-
242.                        DisplayOneStr (11,0,TimeData[4]); //月
243.                        DisplayOneChar (13,0,'-');       //-
244.                        DisplayOneStr (14,0,TimeData[3]);//日
245.
246.                        DisplayOneStr (0,1,TimeData[2]); //时
247.                        DisplayOneChar (2,1,':');        //:
248.                        DisplayOneStr (3,1,TimeData[1]); //分
249.                        DisplayOneChar (5,1,':');        //:
250.                        DisplayOneStr (6,1,TimeData[0]);//秒
251.
252.    //                  DisplayOneChar(10,1,'o');
253.                    }
254.                    if(Input==0)//开灯
255.                    {
256.                        LightControl=Human;
257.                        LightHuman=LightOn;
258.                    }
259.                    else if(Input==1)//关灯
260.                    {
261.                        LightControl=Human;
262.                        LightHuman=LightOff;
263.                    }
264.                    else if(Input==2)//智能灯
265.                    {
266.                        LightControl=Machine;
267.                        LightHuman=LightOff;
268.                    }
269.                    else if(Input==4)//开风扇
270.                    {
271.                        FanControl=Human;
272.                        FanHuman=FanOn;
273.                    }
274.                    else if(Input==5)//关风扇
275.                    {
276.                        FanControl=Human;
277.                        FanHuman=FanOff;
278.                    }
279.                    else if(Input==6)//智能风扇
280.                    {
281.                        FanControl=Machine;
282.                        FanHuman=FanOff;
283.                    }
284.
285.                    if(LightControl==Human)
286.                    {
287.                        AD_Value=LightHuman;
288.                    }
289.                    else if(LightControl==Machine)
290.                    {
291.                        uchar Hour;
292.                        ADC_Read(0x00);
293.                        Hour=BCD_Chg_Dat(TimeData[2]);
294.                        if(!(Hour>20&&Hour<23))
295.                        {
296.                            AD_Value=LightOff;
297.                        }
298.                    }
299.                    DAC_OUT(AD_Value);
300.                    if(Input==18)//修改密码
301.                    {
302.                        choosemode=2;
303.                        Lcd1602_Write_Cmd(0x01);
304.    //                  ET1=0;
305.    //                  TR1=0;
306.                        break;
307.                    }
308.
309.                    else if(Input==19)//关锁(门)
310.                    {
311.                        choosemode=0;
312.                        chance=3;
313.                        Lock=LockOn;
314.    //                  ET1=0;
315.    //                  TR1=0;
316.                        LightControl=Machine;
317.                        FanControl=Machine;
318.                        AD_Value=LightOff;
319.                        _4IN=FanOff;
320.                        break;
321.                    }
322.                    if(_4IN==FanOn)
323.                    {
324.                        DisplayOneChar(13,1,'*');
325.                    }
326.                    else if(_4IN==FanOff)
327.                    {
328.                        DisplayOneChar(13,1,' ');
329.                    }
330.                    if(AD_Value!=LightOff)
331.                    {
332.                        DisplayOneChar(10,1,'o');
333.                    }
334.                    else
335.                    {
336.                        DisplayOneChar(10,1,' ');
337.                    }
338.                }
339.                break;
340.            case 2://**************************************************************修改密码
341.                Lcd1602_Write_Cmd(0x01);
342.                while(1)
343.                {
344.                    uchar change=0;
345.                    LcdShowStr(0,0,"Change secret.");
346.                    LcdShowStr(0,1,"New secret:");
347.                    change=changesecret();
348.                    if(change==1)
349.                    {
350.
351.                        break;
352.                    }
353.                }
354.                break;
355.        }
356.    }
357.    /*
358.    void openstring()
359.    {
360.    //  LcdShowStr(0,0,"Open");
361.        Delayms(1000); //温度转换时间需要750ms以上
362.        displayTemp(getTmpValue());
363.        sendChangeCmd();
364.        LcdShowStr(13,0,"Off");
365.    //  sendChangeCmd();
366.    //  Delayms(1000);
367.    //  displayTemp(getTmpValue);
368.
369.    }
370.    */
371.    void Timer1Init()
372.    {
373.        EA=1;
374.        ET1=1;
375.        TMOD|=0x10;
376.        TH1=(65536-50000)/256;
377.        TL1=(65536-50000)%256;
378.        TR1=1;
379.    }
380.
381.    void Timer1() interrupt 3
382.    {
383.        static timer1num=0;
384.
385.        TH1=(65536-50000)/256;
386.        TL1=(65536-50000)%256;
387.        timer1num++;
388.
389.    //  ET1=0;TR1=0;
390.        if(timer1num==20)
391.        {
392.            timer1num=0;
393.            readflag=1;
394.            /*
395.            //读取放在中断服务函数中会干扰定时器计时
396.            //温度显示
397.            displayTemp(getTmpValue());
398.            sendChangeCmd();
399.            DisplayOneChar(13,1,'*');
400.
401.            //时间显示
402.            Read_DS1302_Time(DS1302_R_ADDR); //先写入时钟日历寄存器起始地址再读出时钟日历写入到TimeData数组中
403.            DisplayOneStr (8,0,TimeData[6]); //年
404.            DisplayOneChar (10,0,'-');       //-
405.            DisplayOneStr (11,0,TimeData[4]); //月
406.            DisplayOneChar (13,0,'-');       //-
407.            DisplayOneStr (14,0,TimeData[3]);//日
408.
409.            DisplayOneStr (0,1,TimeData[2]); //时
410.            DisplayOneChar (2,1,':');        //:
411.            DisplayOneStr (3,1,TimeData[1]); //分
412.            DisplayOneChar (5,1,':');        //:
413.            DisplayOneStr (6,1,TimeData[0]);//秒
414.
415.            DisplayOneChar(10,1,'o');
416.            */
417.        }
418.    //  ET1=1;TR1=1;
419.
420.        pwm_t++;//风扇控制
421.        if(pwm_t == 255)
422.            FanMachine = FanOff;
423.        else if(pwm_t==pwm_motor_val)
424.            FanMachine = FanOn;
425.    //  _4IN=FanMachine;
426.        if(choosemode==0)
427.        {
428.            _4IN = FanHuman;
429.        }
430.        if(choosemode==1||choosemode==2)
431.        {
432.            if(FanControl==Machine)
433.            {
434.                if(temp>0&&datas[1]>=3&&datas[2]>=1)
435.                {
436.                    _4IN=FanMachine;
437.                }
438.                else
439.                    _4IN=FanOff;
440.            }
441.    //      else if(FanControl==Human)
442.    //      {
443.    //          _4IN=FanHuman;
444.    //      }
445.
446.        }
447.
448.        if(FanControl==Human)
449.        {
450.            _4IN=FanHuman;
451.        }
452.
453.    }

五、存在问题及解决方法

  • 键盘引脚和 LCD1602 键盘冲突。
    解决方法:先扫描行再扫描列。

  • 键盘引脚和红外接收模块引脚冲突。
    解决方法:更改电路图,更换红外接收所用引脚。

  • 直流电机驱动风扇不能慢速转动,如果不是全速转动而是慢速转动,将变成时停时转。

    原因:红外和 DS1302 以及 DS18B20 已经将定时器 0 和定时器 1 用完,而 52 单片机的定时器 2 过于复杂,故不尝试使用,所以导致直流电机驱动模块不能单独使用一个定时器调节转速(即 IO 口翻转频率),而与 DS18B20 和 DS1302 共同使用定时器 1,所以其频率过低。

    解决方法:使用其他定时器多的单片机,例如 stc12 和 stm32,或者学习使用 52 单片机的定时器 2。

六、总结

用过这次课程设计,学会了使用 Proteus 软件画电路图,熟练掌握了 51 单片机和各种功能模块的使用,如 DS18B20、DS1302、红外接收模块等,熟练掌握了绝大部分单片机通信协议,有 SPI、IIC、串行异步通信、并行通信,学会了根据时序图编写通信协议,同时也熟练掌握了多文件编程的方式,对已学习的 STM32 单片机有了更深刻的了解。通过在这次项目中解决自己和其他队伍的困难,使自己解决问题的能力进一步提升,在与同伴的交流合作中,了解到团队合作的重要作用。个人感觉 51 单片机是十分基础和简单的,这次项目的制作仅用了 3 天半就全部完成了,但越是基础的东西越该熟练地掌握,否则在进一步的学习中会愈发困难。

♻️ 资源

大小: 54.6MB
➡️ 资源下载:https://download.csdn.net/download/s1t16/87415719

基于物联网的智能家居控制系统【100010619】相关推荐

  1. (毕业设计资料)基于STM32的物联网WiFi智能家居控制系统

    092[电路方案]基于STM32的物联网WiFi智能家居控制系统 功能: 1.可以检测环境中温湿度,气压,一氧化碳,空气质量,烟雾浓度和光照强度. 2.将测量的值显示在屏幕上,数据上报机智云平台可以通 ...

  2. 基于ESP32的智能家居控制系统-微信小程序

    一. 课题研究意义.现状及应用分析 1.1课题研究意义及现状 目前,科学技术发展十分迅速,其渗透到各行各业以及生活的方方面面,室内设计和高科技结合便出现了"智能家居".所谓智能家居 ...

  3. 基于物联网的智能家居系统设计(课设)

    基于物联网的智能家居系统设计(课设) 摘 要 一.概述 二.系统分析 三.系统设计 四.系统实现 1.硬件实现 2.软件实现 五.结论与心得 六.参考文献 摘 要   科技的快速发展给人们的生活带来了 ...

  4. STM32的oneNet物联网远程智能家居控制系统-思路分享

    设计了一款基于OneNET的物联网智能家居系统,用于家庭的智能控制系统.系统采用意法半导体公司的STM32F103C8T6作为控制单片机,果云科技的GA6作为物联网通信的载体.中国移动的OneNET作 ...

  5. 基于物联网的智能家居

    基于物联网的智能家居 摘要:随着科学技术的飞速发展和生活水平的提高,人们对智能生活的需求也在不断增加.智能家庭的自动化是社会信息发展的重要组成部分,同时从个人.公共服务和政府的需要出发,在物联网给智能 ...

  6. java智能家居_基于JAVA的智能家居控制系统的设计(毕业设计).doc

    基于JAVA的智能家居控制系统的设计(毕业设计) 基于JAVA的智能家居系统的设计--信息控制子系统 PAGE 4 目 录 TOC \o "1-3" \h \z \u HYPERL ...

  7. 基于微信的智能家居控制系统的设计与实现

    基于微信的智能家居控制系统的设计与实现 目 录 1 绪论 6 1.1 课题研究的背景 6 1.2 智能家居系统的研究现状和发展前景 6 1.3 课题研究的意义 7 1.4 设计的研究内容 8 2 相关 ...

  8. 基于java智能家居,基于JAVA的智能家居控制系统的设计(信息控制端的设计)-论文二稿...

    基于JAVA的智能家居控制系统的设计(信息控制端的设计)-论文二稿 PINGDINGSHAN UNIVERSITY毕业论文 (设计 )题 目:基于 JAVA 的智能家居控制系 统的设计(信息控制端的设 ...

  9. android 智能家居 pdf,基于Android的智能家居控制系统的设计探究.pdf

    设计与研发 2015.10 基于Android的智能家居控制系统的设计研究 马洪轩 (中南大学,湖南长沙,410012) 摘要:随着科学技术的发展,各种电器和家具控制的智能化是目前市场流行起来.人们生 ...

最新文章

  1. R语言ggplot2可视化:将dataframe和数据列名称传递给函数通过函数进行ggplot2可视化输出
  2. 社交网络图挖掘5--图的邻居性质
  3. 使命召唤手游新的狙击枪,升级之后堪比巴雷特?会玩的就是
  4. Java重写、super关键字、继承中的构造方法
  5. HTTP访问一个网站的过程详解
  6. citrix POC环境准备
  7. kibana-7.15.2 中文简体
  8. 靠谱测试人员需要具备专业技术能力
  9. 使用Python抓取网页信息
  10. 好友助力功能php开发,微开讲_帮助中心
  11. 49. PHP 页面静态化(2)
  12. [模板制作技巧3]控制每页显示组的数目
  13. Ubuntu 18.04 安装NVIDIA显卡驱动教程
  14. r语言Isfit_应用统计学与R语言实现学习笔记(七)——拟合优度检验
  15. 安服/渗透测试面试题(2)
  16. 淘宝客?CPS技术是怎么实现的?
  17. 9530 blackberry 上网
  18. RT-Preempt笔记
  19. JavaScript头像上传器的实现
  20. java向手机号发送短信验证码

热门文章

  1. 电脑办公记事app软件哪个好用?
  2. 【Redis】Info 命令
  3. 神经网络和卷积神经网络,常用的卷积神经网络
  4. 纯代码RelativeLayout实现右上角布局
  5. 偏最小二乘法 Partial Least square
  6. OSChina 周日乱弹 ——编程的都是胖子多,瘦子少?
  7. UI自动化测试(二)浏览器操作及对元素的定位方法(xpath定位和css定位详解)
  8. nltk 同义词替换 单词拼写校正 制作伪原创文章
  9. 使用flume问题总结2——flume event的简单理解
  10. 第六十六篇:单目三维重建点云