这是我的设计,全原创。附件是完整程序
内容:
本课题基于单片机技术, 研究一典型的智能家居系统设计. 系统拟采用控制器,监控器和控制终端的框架结构, 主要设计对家居中的时间、温度、湿度和光照等信息的检测, 以及照明系统, 窗帘和家用电器的自动控制. 具体设计要求如下:
1)温度以及室外湿度,PM2.5的自动监测与显示.
2)照明系统的自动控制与手动控制, 如离开家时关闭所有照明.
3)窗帘与窗户的自动控制与手动控制,如睡眠时自动关闭窗帘, 当室外湿度和PM2.5超出预警值时自动关闭窗户.
4)实现窗帘窗户以及家用电器的远程控制.
电路原理图如下:
单片机源程序如下:
- #include <REGX52.H>
- #include "LCd1602.h"
- #include "dht11.c"
- #include "eeprom52.h"
- #include "hong_wai.h"
- sbit key1=P2^3;
- sbit key2=P3^1;
- sbit key3=P3^3;
- sbit key4=P3^4;
- sbit key5=P3^5;
- sbit key6=P3^6;
- sbit key7=P3^7;
- sbit LED=P2^4;
- sbit RSD=P2^2;
- sbit light=P2^1;
-
- bit key1_flag=0;
- bit key2_flag=0;
- bit key3_flag=0;
- bit key4_flag=0;
- bit key5_flag=0;
- bit key6_flag=0;
- bit key7_flag=0;
- uchar sec=0;
- uchar sec1=0;
- uchar rh_h=0;
- uchar ms=0;
- uchar state=0;
- bit mode =0; //mode 是控制电机的 自动手动标志位
- bit mode1=0; //mode1是控制灯的 自动手动标志位
- bit s0;
- bit star_stop=1;
- uchar UART_Upload[9]; // Upload上传 accord主动
- uint pm_rateH,pm_rateL,pm_particle,pm_density,pm_URV;//低脉冲率高位。低脉冲率低位, 比率,颗粒,浓度 PM_URV pm上限值
- uchar accord=0;
- uchar fz[]= //正转数据
- {
- 0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09
- };
- uchar zz[]= //反转数据
- {
- 0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01
- };
- uchar loop=0;
- uint DJ_dat=0;
- void memory()
- { ///pm_URV
- SectorErase(0x2000);
- byte_write(0x2000,rh_h);
- byte_write(0x2001,pm_URV/256);
- byte_write(0x2002,pm_URV%256);
- }
- void read_memory()
- {
- rh_h=byte_read(0x2000);
- pm_URV=byte_read(0x2001)*256+byte_read(0x2002);
- if(rh_h>99||pm_URV>9999)
- {
- rh_h=30;
- pm_URV=500;
- }
- }
- void display_dispose()
- {
- if(state==0) // U8RH_data_H U8T_data_H
- {
- LCD1602_write(0,0x80);
- LCD1602_writebyte("R:");
- LCD1602_write(1,0x30+U8RH_data_H/10);
- LCD1602_write(1,0x30+U8RH_data_H%10);
- LCD1602_writebyte("% ");
-
- LCD1602_writebyte("T:");
- LCD1602_write(1,0x30+U8T_data_H/10);
- LCD1602_write(1,0x30+U8T_data_H%10);
- LCD1602_write(1,0xdf);
- LCD1602_writebyte("C ");
- if(mode1) LCD1602_writebyte("A ");
- else LCD1602_writebyte("M ");
- if(mode) LCD1602_writebyte("A ");
- else LCD1602_writebyte("M ");
-
- LCD1602_write(0,0xC0);
- LCD1602_writebyte("P:"); //pm_density
- LCD1602_write(1,0x30+pm_density/1000%10);
- LCD1602_write(1,0x30+pm_density/100%10);
- LCD1602_write(1,0x30+pm_density/10%10);
- LCD1602_writebyte(".");
- LCD1602_write(1,0x30+pm_density%10);
- LCD1602_writebyte("ug/m3 ");
- if(LED==0) LCD1602_writebyte("K ");
- else LCD1602_writebyte("G ");
- if(star_stop==0) LCD1602_writebyte("K ");
- else LCD1602_writebyte("G ");
-
- }
- else
- {
- LCD1602_write(0,0x80);
- LCD1602_writebyte("RH_H:");
- if(state==1&&s0) LCD1602_writebyte(" ");
- else
- {
- LCD1602_write(1,0x30+rh_h/10);
- LCD1602_write(1,0x30+rh_h%10);
- }
- LCD1602_writebyte("% ");
- LCD1602_write(0,0xC0);
- LCD1602_writebyte("PM2.5:"); //pm_density
- if(state==2&&s0) LCD1602_writebyte(" ");
- else
- {
- LCD1602_write(1,0x30+pm_URV/1000%10);
- LCD1602_write(1,0x30+pm_URV/100%10);
- LCD1602_write(1,0x30+pm_URV/10%10);
- LCD1602_writebyte(".");
- LCD1602_write(1,0x30+pm_URV%10);
- }
- LCD1602_writebyte("ug/m3 ");
- }
- }
- void key()
- {
- if(!key1||ircode[2]==0x0c)
- { ircode[2]=0;
- if(key1_flag)
- {
- key1_flag=0;
- state=(state+1)%3;
- }
- }
- else
- {
- if(ircode[2]!=0x0c) key1_flag=1;
- }
-
- if(!key2||ircode[2]==0x18)
- { ircode[2]=0;
- if(key2_flag)
- {
- key2_flag=0;
- if(state==1)
- {
- if(rh_h<99) rh_h++;
- memory();
- }
- else if(state==2)
- {
- if(pm_URV<9999) pm_URV++;
- memory();
- }
- }
- if(sec==0)
- {
- if(state==1)
- {
- if(rh_h<99) rh_h++;
- memory();
- }
- else if(state==2)
- {
- if(pm_URV<9999) pm_URV++;
- memory();
- }
- }
- }
- else
- {
- if(ircode[2]!=0x18)
- {
- key2_flag=1;
- sec=2;
- }
- }
-
-
- if(!key3||ircode[2]==0x5E)
- { ircode[2]=0;
- if(key3_flag)
- {
- key3_flag=0;
- if(state==1)
- {
- if(rh_h>0) rh_h--;
- memory();
- }
- else if(state==2)
- {
- if(pm_URV>0) pm_URV--;
- memory();
- }
- }
- if(sec1==0)
- {
- if(state==1)
- {
- if(rh_h>0) rh_h--;
- memory();
- }
- else if(state==2)
- {
- if(pm_URV>0) pm_URV--;
- memory();
- }
- }
- }
- else
- {
- if(ircode[2]!=0x5E)
- {
- key3_flag=1;
- sec1=2;
- }
- }
-
- if(!key4||ircode[2]==0x08)
- { ircode[2]=0;
- if(key4_flag)
- {
- key4_flag=0;
- mode1=~mode1;
- LED=1;
- }
- }
- else
- {
- if(ircode[2]!=0x08)
- {
- key4_flag=1;
- }
- }
- if(!key5||ircode[2]==0x1C)
- { ircode[2]=0;
- if(key5_flag)
- {
- key5_flag=0;
- mode=~mode;
- }
- }
- else
- {
- if(ircode[2]!=0x1C)
- {
- key5_flag=1;
- }
- }
-
- if(!key6||ircode[2]==0x5A)
- { ircode[2]=0;
- if(key6_flag)
- {
- key6_flag=0;
- if(mode1==0)
- {
- LED=~LED;
- }
- }
- }
- else
- {
- if(ircode[2]!=0x5A)
- {
- key6_flag=1;
- }
- }
- if(!key7||ircode[2]==0x42)
- { ircode[2]=0;
- if(key7_flag)
- {
- key7_flag=0;
- if(mode==0)
- {
- star_stop=~star_stop;
- }
- }
- }
- else
- {
- if(ircode[2]!=0x42)
- {
- key7_flag=1;
- }
- }
-
-
- }
- void interrupt_int()
- {
- EX0=1; //打开外部中断0
- IT0=1; //设置为边沿触发
-
- TMOD=0x12; //设置定时器0工作模式2 8位自动重装 256
- TH0=0;
- TL0=0; //装入初值
- ET0=1; //打开定时器中断
- TH1=0x3C;
- TL1=0xb0; //装入初值
- ET1=1; //打开定时器中断
- EA=1; //打开总中断开关
- TR0=1; //打开定时器,开始计时
- TR1=1;
- }
- void UART_Init(void)
- {
- T2CON = 0x34;
- RCAP2H = 0xFF;
- RCAP2L = 0xDC;
- TH2 = 0xFF;
- TL2 = 0xDC;
- TR2 = 1;
- SCON = 0x50;
- ES = 1;
- }
- void mode_dispose() //mode 是控制电机的 mode1是控制灯的自动手动标志
- {
- if(mode1) //mode1==0 手动 mode1==1 自动
- {
- if(light)
- {
- if(RSD)
- {
- LED=0;
- }
- else LED=1;
- }
- else LED=1;
- }
- if(mode) //mode1==0 手动 mode1==1 自动
- {
- if(light==0)
- {
- if((rh_h<U8RH_data_H)||(pm_URV<pm_density)) star_stop=0;
- else star_stop=1;
- }
- else star_stop=1;
- }
- if(DJ_dat==0) loop=0;
- while(DJ_dat<520&&star_stop==0)
- {
- P1=P1&0xf0|zz[loop];
- loop=(loop+1)%8;
- if(loop==0) DJ_dat++;
- LCD1602_delay(100);
- }
- while(DJ_dat!=0&&star_stop==1)
- {
- P1=P1&0xf0|fz[loop];
- loop=(loop+1)%8;
-
- if(loop==0) DJ_dat--;
- LCD1602_delay(100);
- }
-
- P1=0x00;
-
-
- }
- void main()
- {
- LCD1602_cls();
- interrupt_int();
- UART_Init();
- read_memory();
- while(1)
- {
- mode_dispose();
- display_dispose();
-
- }
- }
- void int0() interrupt 0
- {
- if(starflag)
- {
- if(irtime>32) //引导码时间除以0.256,是31.多毫秒
- {
- bitnum=0; //此时确定接收到引导码,清零变量,接收数据
- }
- irdata[bitnum]=irtime; //将数据接收送入irdata
- irtime=0; //每接收一位数据,清零一次,使下次接受的数据准确
- bitnum++; //数组变量增加
- if(bitnum==33) //当变量增加到33时,说明一帧数据接收完毕
- {
- bitnum=0; //清零数组变量
- irreceok=1; //接收完一帧数据标志位
-
- }
- }
- else
- {
- starflag=1; //为接收一帧数据的第一位做准备
- irtime=0; //清零定时变量
- }
-
-
-
-
- }
- void time0() interrupt 1
- {
- irtime++; //因为是模式2,那么变量每加一一次,就是定时了256um,也就是0.256毫秒
- }
- void time1() interrupt 3
- {
- TH1=0x3C;
- TL1=0xb0;
- ms++;
- key();
- ir_ok();
- if(ms%10==0) s0=~s0;
- if(ms>=20)
- { RH();
- ms=0;
- if(sec!=0)sec--;
- if(sec1!=0)sec1--;
- }
- }
- void uart () interrupt 4
- {
- uchar temp_pM;
- if(RI==1)
- {
- RI=0;
- UART_Upload[accord]=SBUF; //串口接收一个数据
- accord++;
- if(UART_Upload[0]!=0xff) //判断接收到的第一个数据为oxff 数据错误 数组指针清零
- {
- accord=0;
- }
- if(UART_Upload[1]!=0x18)//判断接收到的第2个为0x18 数据错误 数组指针清零
- {
- accord=0;
- }
- if(accord>8) //九个数据为一组
- {
- accord=0; //接收完一组数据的标志,置0 校验
- }
- if(accord==0) //接收一组数据后进行一次校验和
- { //校验7为数据位的和取反加一等于校验值
- if((UART_Upload[0]==0xff)&&(UART_Upload[1]=0x18)&&(UART_Upload[2]==0x00))//判断前三位数据是否正确 是进行校验
- {
- temp_pM=~(UART_Upload[1]+UART_Upload[2]+UART_Upload[3]+UART_Upload[4]+UART_Upload[5]+UART_Upload[6]+UART_Upload[7])+1; //校验和
- if(temp_pM=UART_Upload[8])
- {
- pm_rateH=UART_Upload[3];
- pm_rateL=UART_Upload[4];
- pm_density=(UART_Upload[3]*100+UART_Upload[4])*1.014705; //浓度数据处理 数据扩大了十倍
- /*我们绘出一个检验报告,比如在345ug/m3的情况下,zph01输出占空比34%。我们理论认为在0-34%对应的0-345ug/m3。他们是 线性比例关系*/
- }
- }
-
- }
- }
- }
复制代码
全部程序51hei下载地址:
xtr.c.zip
(35.08 KB, 下载次数: 143)
|