這是我的設計,全原創。附件是完整程序
內容:
本課題基于單片機技術, 研究一典型的智能家居系統設計. 系統擬采用控制器,監控器和控制終端的框架結構, 主要設計對家居中的時間、溫度、濕度和光照等信息的檢測, 以及照明系統, 窗簾和家用電器的自動控制. 具體設計要求如下:
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)
2020-5-26 20:37 上傳
點擊文件名下載附件
|