仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
所用到的知识点: 1、8位共阴极数码管 2、4x4矩阵键盘 3、液晶显示屏LCD1602 4、大型液晶显示屏 LCD12864 5、实时时钟芯片 DS1302 6、数模转换芯片 ADC0832 7、利用I2C进行的数模转换芯片 PCF8591 8、温度传感器 DS18B20 9、压力传感器 MAX4115 10、光敏电阻 LDR 11、电机驱动电路 12、三态输出移位缓存器 74HC595 13、外部中断及定时器 14、双机通讯 15、片机与上位机通讯 COMPIM
使用说明: 1、用户输入正确的密码,打开门禁之后,LED屏进入欢迎界面, 居室内各电器自动启动; 2、密码键盘支持删除、清空、提示功能; 3、上方的LED屏实时显示万年历,包括年月日,周,时分秒; 4、下方的LED屏实时显示各传感器检测到的状态, 第一行依次显示当前的温度、烟雾浓度、光照强度; 5、当温度高于40时,将会自动打开风扇, 而当温度高于50度时,将会自动报警; 6、当居室内光照强度太低时,自动打开照明系统, 当居室内光照强度太高时,自动关上窗帘; 7、当室内烟雾浓度,超过20,自动鸣笛报警,警报灯闪烁; 8、用户也可以手动打开或者关上窗帘; 9、家居系统里装有体重秤,可以随时测量体重; 10、网络模块将最新的温度、光照强度、烟雾浓度发送到上位机;
一、首先,进入系统会显示欢迎界面,并输入密码; 密码输入错误:会显示“请重新输入” 密码输入正确,会显示“”欢迎”
二、密码输入正确之后 上面的LED显示当前的时间。下面的LED实时显示各传感器检测到的状态,第一行依次显示当前的温度、烟雾浓度、光照强度;如果是温度、光照强度,第二行会显示“worming”+数字,超过这个数字会自动报警;如果是光照强度。第二行会显示“NOMNAL”,”TOO HIGH”,”TOO LOW”,分别表示正常,太高,太低。
三、温度传感器模块,及烟雾检测模块 超过40度时,风扇慢慢打开。 超过50度时,自动报警。 烟雾浓度超过20时,自动报警。
四、光照强度检测装置 光照太低时,自动打开照明系统 光照太高时。自动关上窗帘 另外,窗帘也可以手动打开、关闭。
五、体重秤模块 检测到当前温度,并显示出来。 六、上位机 因为单片机有了双机通信,甲机已经接受了乙机的数据,没有办法再接收上位机发送的数据,所以上位机只做了接收功能。 单片机每秒一次,把当前的温度,烟雾、光强数据发送到上位机。
单片机源程序如下:
- #include "main.h"
- #include "ADC0832.h"
- #include "DS18B20.h"
- #include "LCD1602.h"
- #include "74HC595.h"
- #include "PCF8591.h"
- void main()
- {
- time_init();
- fan=0;
- Pcf8591SendByte(0); //使用通道0
- wendu=get_wendu();
- Init1602(); //调用初始化显示函数
- LCD_Write_String(0,4,"WELCOME TO");
- LCD_Write_String(1,2,"My Smart Home");
- while(1)
- {
- if(flag==1)
- break;
- };
- TR0=1;
- wendu=get_wendu(); //初始化时调用温度读取函数 防止开机85°C
-
- guangqiang=getGuangqiang(); //读取光照值
- yanwu=getYanwu(); //读取天然气值*/
-
-
- PW1 = 1;
- PW2 = 1;
-
- Puts_to_SerialPort("温度 烟雾 光强\r\n");
- while(1)
- {
- tizhong = Pcf8591ReadByte()/2;
- SendTo595(table[tizhong/10]+(table[tizhong%10]<<4));
- delay1ms(1);
- times++;
- if(times==300)
- {
- times=0;
- }
- if(times<=100)
- {
- if(times==1)
- write_com(0x01);//清屏
- LCD_Write_String(0,0,"WenDu:");
- LCD_Write_Char(0,10,wendu/10,2) ;
- write_data('.');
- LCD_Write_Char(0,13,wendu%10,1) ;
-
- LCD_Write_String(1,0,"Worming:");
- LCD_Write_Char(1,10,set_wdHH,2) ;
- }
- else if(times>100&×<=200)
- {
- if(times==101)
- write_com(0x01);//清屏
- LCD_Write_String(0,0,"YanWu:");
- LCD_Write_Char(0,11,yanwu,2) ;
- LCD_Write_String(1,0,"Worming:");
- LCD_Write_Char(1,10,set_yanwu,2) ;
- }
- else if(times>200)
- {
- if(times==201)
- write_com(0x01);//清屏
- LCD_Write_String(0,0,"GuangZhao:");
- LCD_Write_Char(0,11,guangqiang,2) ;
- if(guangqiang>=set_lightL&&guangqiang<=set_lightH)
- LCD_Write_String(1,5,"NORMAL");
- else if(guangqiang<=set_lightL)
- LCD_Write_String(1,5,"TOO LOW");
- else
- LCD_Write_String(1,5,"TOO HIGH");
- }
- }
- }
- void delay(uchar i)
- {
- for(i;i>0;i--);
- }
- void delay_ms(uint cnt)
- {
- unsigned int x;
- for( ; cnt>0; cnt--)
- {
- for(x=500; x>0; x--);
- }
- }
- void delay1ms(int n)
- {
- unsigned char i;
- for(i=124*n;i>0;i--); //延时124*8+10=1002us
- }
- void Putc_to_SerialPort(uchar c)
- {
- SBUF=c;
- while(TI==0);
- TI=0;
- }
- void Puts_to_SerialPort(uchar *s)
- {
- while(*s!='\0')
- {
- Putc_to_SerialPort(*s);
- s++;
- WDdelay(5);
- }
- }
- /*************定时器0初始化程序***************/
- void time_init()
- {
- TMOD=0X21; //定时器0、工作方式1 ,T2工作方式2
- TH0=(65536-1000)/256;
- TL0=(65536-1000)%256;
- EA=1; //开总中断
- ET0=1; //开定时器0中断
- TR0=0; //允许定时器0定时
- SCON=0x50; //串口模式1,允许接收
- PCON=0x00; //波特率不倍增
- TH1=0xfd;
- TL1=0xfd;
- TI=RI=0;
- TR1=1;
- ES=1;
-
- EX0=1;
- IT0=1;
- IP=0x02;
- }
- void check()
- {
- if(wendu/10>=set_wdH)
- fan=1;
- else
- fan=0;
- if(guangqiang<=set_lightL)
- DENG=0;
- else
- DENG=1;
-
- if(yanwu>=set_yanwu||wendu/10>=set_wdHH&&wendu/10<=60)
- {
- speaker=0;
- BaoJing=!BaoJing;
- }
- else
- speaker=BaoJing=1;
- if(guangqiang>=set_lightH&&is_cl==1)
- {
- PW1=1;
- PW2=0;
- delay_ms(1000);
- PW1=1;
- PW2=1;
- is_cl=0;
- }
- if(guangqiang<=set_lightH)
- is_cl=1;
- }
- void time0_inter() interrupt 1
- {
- TH0 = (65536-1000)/256;
- TL0 = (65536-1000)%256; // 50ms 12M
-
-
-
- count++;
- if(count>80)
- {
- count = 0;
- ctimes++;
- wendu=get_wendu();
- guangqiang=getGuangqiang();
- yanwu=getYanwu();
- check();
- tizhong = Pcf8591ReadByte()/2;
- }
- if(ctimes==15)
- {
- ctimes=0;
- Putc_to_SerialPort(' ');
- Putc_to_SerialPort(wendu/100+'0');
- Putc_to_SerialPort(wendu/10%10+'0');
- Puts_to_SerialPort(" ");
- Putc_to_SerialPort(yanwu/10+'0');
- Putc_to_SerialPort(yanwu%10+'0');
- Puts_to_SerialPort(" ");
- Putc_to_SerialPort(guangqiang/10+'0');
- Putc_to_SerialPort(guangqiang%10+'0');
- Puts_to_SerialPort("\r\n");
- }
-
- }
- void inter_0() interrupt 0
- {
- PW1 = 1;
- PW2 = 1;
- if(KEY1==0){
- delay(10);
- while(!KEY1);
- //电机逆时针转动,模拟窗帘打开
- PW1 = 1;
- PW2 = 0;
- delay_ms(1000);
- //电机停止转动,窗帘打开完成
- PW1 = 1;
- PW2 = 1;
- }
- if(KEY2==0){
- delay(10);
- while(!KEY2);
- //电机顺时针转动,模拟窗帘关闭
- PW1 = 0;
- PW2 = 1;
- delay_ms(1000);
- //电机停止转动,窗帘关闭完成
- PW1 = 1;
- PW2 = 1;
- }
- KEY1=1;
- KEY2=1;
- }
- void Serial_INT() interrupt 4
- {
- if(RI)
- {
- RI=0;
- if(SBUF==1)
- {
- flag=1;
- }
- }
- }
-
复制代码
Keil5代码与Proteus8.8仿真下载:
智能家居.zip
(553.03 KB, 下载次数: 253)
|