基于物联网的智能家居控制系统【100010619】
智能家居控制系统
一、摘要
智能家居作为家庭信息化的实现方式,已经成为社会信息化发展的重要组成部分,物联网其巨大的应用前景,是智能家居产业发展过程中一个比较现实的突破口,对智能家居的产业发展具有重大意义。本文基于容易实现,方便操作,贴近使用的设计理念,设计的智能家居控制系统是以 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】相关推荐
- (毕业设计资料)基于STM32的物联网WiFi智能家居控制系统
092[电路方案]基于STM32的物联网WiFi智能家居控制系统 功能: 1.可以检测环境中温湿度,气压,一氧化碳,空气质量,烟雾浓度和光照强度. 2.将测量的值显示在屏幕上,数据上报机智云平台可以通 ...
- 基于ESP32的智能家居控制系统-微信小程序
一. 课题研究意义.现状及应用分析 1.1课题研究意义及现状 目前,科学技术发展十分迅速,其渗透到各行各业以及生活的方方面面,室内设计和高科技结合便出现了"智能家居".所谓智能家居 ...
- 基于物联网的智能家居系统设计(课设)
基于物联网的智能家居系统设计(课设) 摘 要 一.概述 二.系统分析 三.系统设计 四.系统实现 1.硬件实现 2.软件实现 五.结论与心得 六.参考文献 摘 要 科技的快速发展给人们的生活带来了 ...
- STM32的oneNet物联网远程智能家居控制系统-思路分享
设计了一款基于OneNET的物联网智能家居系统,用于家庭的智能控制系统.系统采用意法半导体公司的STM32F103C8T6作为控制单片机,果云科技的GA6作为物联网通信的载体.中国移动的OneNET作 ...
- 基于物联网的智能家居
基于物联网的智能家居 摘要:随着科学技术的飞速发展和生活水平的提高,人们对智能生活的需求也在不断增加.智能家庭的自动化是社会信息发展的重要组成部分,同时从个人.公共服务和政府的需要出发,在物联网给智能 ...
- java智能家居_基于JAVA的智能家居控制系统的设计(毕业设计).doc
基于JAVA的智能家居控制系统的设计(毕业设计) 基于JAVA的智能家居系统的设计--信息控制子系统 PAGE 4 目 录 TOC \o "1-3" \h \z \u HYPERL ...
- 基于微信的智能家居控制系统的设计与实现
基于微信的智能家居控制系统的设计与实现 目 录 1 绪论 6 1.1 课题研究的背景 6 1.2 智能家居系统的研究现状和发展前景 6 1.3 课题研究的意义 7 1.4 设计的研究内容 8 2 相关 ...
- 基于java智能家居,基于JAVA的智能家居控制系统的设计(信息控制端的设计)-论文二稿...
基于JAVA的智能家居控制系统的设计(信息控制端的设计)-论文二稿 PINGDINGSHAN UNIVERSITY毕业论文 (设计 )题 目:基于 JAVA 的智能家居控制系 统的设计(信息控制端的设 ...
- android 智能家居 pdf,基于Android的智能家居控制系统的设计探究.pdf
设计与研发 2015.10 基于Android的智能家居控制系统的设计研究 马洪轩 (中南大学,湖南长沙,410012) 摘要:随着科学技术的发展,各种电器和家具控制的智能化是目前市场流行起来.人们生 ...
最新文章
- R语言ggplot2可视化:将dataframe和数据列名称传递给函数通过函数进行ggplot2可视化输出
- 社交网络图挖掘5--图的邻居性质
- 使命召唤手游新的狙击枪,升级之后堪比巴雷特?会玩的就是
- Java重写、super关键字、继承中的构造方法
- HTTP访问一个网站的过程详解
- citrix POC环境准备
- kibana-7.15.2 中文简体
- 靠谱测试人员需要具备专业技术能力
- 使用Python抓取网页信息
- 好友助力功能php开发,微开讲_帮助中心
- 49. PHP 页面静态化(2)
- [模板制作技巧3]控制每页显示组的数目
- Ubuntu 18.04 安装NVIDIA显卡驱动教程
- r语言Isfit_应用统计学与R语言实现学习笔记(七)——拟合优度检验
- 安服/渗透测试面试题(2)
- 淘宝客?CPS技术是怎么实现的?
- 9530 blackberry 上网
- RT-Preempt笔记
- JavaScript头像上传器的实现
- java向手机号发送短信验证码