作者:落葉風的作品
先看下硬件設計,使用的是單片機STC12C5A60S2,共有8路輸入,其中4路是隔離的,低電平為開,輸出也是8路,4個繼電器,4個可控硅,為了簡化可控硅的控制電路,采用5V的隔離電源隔開,有6個開關,開關1-5分別對應的4個可控硅及1個繼電器輸出,開關6是用于顯示翻頁及設置用,短按為翻頁,長按為進入當前頁的設置,再短按為改變設置項目,再長按為保存設置,開關5當處于設置時,就為調整參數,如不處于設置狀態時,為繼電器1控制。繼電器2設置有一組定時開關功能,是采用觸發方式的。顯示用0.96寸的OLED顯示器,溫度濕度用DHT11模塊。帶有無線遙控功能,控制開關1-4,由于是測試板,所以輸入輸出元件沒有裝齊,只裝部份進行測試,但單片機及手機軟件并沒偷工減料,所想到的都寫上去了,但由于沒實際環境中使用過,可能有BUG。
0.jpg (33.05 KB, 下載次數: 70)
下載附件
2018-9-2 18:13 上傳
必須為開源者落葉風大神點贊,這技術絕對牛哄哄。
捕獲.PNG (17.24 KB, 下載次數: 76)
下載附件
2018-9-2 14:51 上傳
電路原理圖如下:
0.png (44.73 KB, 下載次數: 66)
下載附件
2018-9-2 18:13 上傳
制作出來的pcb實物圖如下:
0.jpg (40.22 KB, 下載次數: 68)
下載附件
2018-9-2 18:14 上傳
手機軟件方面,是第一次寫手機軟件,自己有用中文編程軟件易語言寫過小軟件,所以看了幾天易安卓的教程,就寫這手機軟件,由于還不熟悉這編程軟件,特別是它的數組操作搞不清楚,所以手機軟件源代碼上基本上是變量以文本型為主,軟件的基本功能齊全,有顯示控制窗口口、設置窗口及定時設置窗,能直接操作控制單片機的開關及參數的修改。
當手機軟件正常開啟后,會把手機當前時間發送個授時命令給單片機,根據單片機設置情況,進行授時操作。
OLED顯示屏用來顯示一些數據,和進行相關設置顯示。
0.png (288.98 KB, 下載次數: 65)
下載附件
2018-9-2 18:15 上傳
藍牙轉串口模塊,是HC-06從機藍牙模塊,已用命令把它的波特率改為19200。采用引線引出來,方便測試。
0.png (153.22 KB, 下載次數: 81)
下載附件
2018-9-2 18:15 上傳
315無線模塊
0.png (190.12 KB, 下載次數: 63)
下載附件
2018-9-2 18:17 上傳
單片機源程序如下:
- //藍牙房間控制器
- //編寫時間為2015-6-2
- //時鐘用22.1M,cpu用STC12C5A60
- #include <STC12C5A60S2.h>
- #include <intrins.h>
- unsigned char oldkey,keyval,pagevol,bbtemp;
- unsigned int keyjixu ,jisu,tempxidu;
- bit BBkongvol,readtimekong,time05s,dingkong,timeauto,rscRSkong;
- unsigned char t_sec,t_min,t_hour,t_1224ji;
- unsigned char timetao,settao,RSzhuantai2,recRSjisu;
- unsigned char dingon_hour,dingon_min,dingoff_hour,dingoff_min;
- unsigned char recRSvol[6];
- extern void OLED_Init(void);
- extern void OLED_Clear(void);
- extern void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no);
- extern void OLED_ShowString(unsigned char x,unsigned char y, unsigned char *p);
- extern void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr);
- extern void OLED_32X16(unsigned char x,unsigned char y,unsigned char c);
- //外部引用DS1302子程序
- extern void write_time(unsigned char temp1,temp2);
- extern unsigned char read_time(unsigned char hangmu);
- extern void DS1302ini();
- sbit KEY1=P1^0;
- sbit KEY2=P1^1;
- sbit KEY3=P1^4;
- sbit KEY4=P1^5;
- sbit KEY5=P1^6;
- sbit KEY6=P1^7;
- sbit BB=P4^7;
- sbit OUT1=P2^7;
- sbit OUT2=P2^6;
- sbit OUT3=P2^5;
- sbit OUT4=P2^4;
- sbit OUT5=P2^3;
- sbit OUT6=P2^2;
- sbit OUT7=P2^1;
- sbit OUT8=P2^0;
- sbit DHT11DA=P3^6;
- void delay(unsigned int t) //長延時程序,延時t毫秒,STC 1T單片機11.0592M晶振I值為648,22.1I值為1298,12MI值為705。
- {
- unsigned int i;
- while(t--)
- {
- for(i=1298;i>0;i--);
- }
- }
-
- void delay10us() //延時10us,STC 1T單片機11.0592M晶振J值為23,22。1MJ值為51。
- {
- unsigned char j;
- for(j=51;j>0;j--);
- }
- //======================EEPROW偏程==============================
- //寫字節時,可以將原有數據中的1改為0,無法將0改為1,只能使用擦除命令將0改為1
- //應注意,擦除命令會將整個扇區擦除
- //由于擦除會將整個扇區擦除,為了方便寫,所以這里用第二扇區存第一屏的狀態,
- //第三扇區存定時1的5個時間,每個時間有啟用、開時間、關時間、星期(8b)
- //第四扇區存定時6-10,第5扇區存溫度值,
- // 第二扇區地址0x0200-0x03ff,0x0400-0x05ff,0x0600-0x07ff,0x0800-0x09ff.
- void IAPIDLE()
- {
- IAP_CMD = 0; //關閉令,保護
- IAP_CONTR = 0; //關EEPROM,保護
- IAP_TRIG = 0;
- IAP_ADDRL = 0; //設置讀取地址的低字節,地址改變才需要設置
- IAP_ADDRH = 0X80; //設置讀取地址的高字節,地址改變才需要設置
- }
- unsigned char readEEP(unsigned int adddata)
- { //讀取
- unsigned char eerdata;
- IAP_CONTR=0X83;//設置等待時間,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前導1表示許檔IAP
- IAP_CMD = 1; //讀取值1,寫取2,擦除取3,擦除時按所在字節整個扇區攛除
- IAP_ADDRL = adddata; //設置讀取地址的低字節,地址改變才需要設置
- IAP_ADDRH = adddata>>8; //設置讀取地址的高字節,地址改變才需要設置
- IAP_TRIG = 0x5A; //先送5A
- IAP_TRIG = 0xA5; //先送5A再送A5立即觸發
- _nop_();
- eerdata=IAP_DATA;
- IAPIDLE();
- return eerdata;
- }
- void writeEEP(unsigned int adddata, unsigned char eerdata)
- {//寫入
- IAP_CONTR=0X83;//設置等待時間,
- IAP_CMD = 2; //讀取值1,寫取2,擦除取3,擦除時按所在字節整個扇區攛除
- IAP_ADDRL = adddata; //設置讀取地址的低字節,地址改變才需要設置
- IAP_ADDRH = adddata>>8; //設置讀取地址的高字節,地址改變才需要設置
- IAP_DATA= eerdata;//傳入數據
- IAP_TRIG = 0x5A; //先送5A
- IAP_TRIG = 0xA5; //先送5A再送A5立即觸發
- _nop_();
- IAPIDLE();
- }
- void eraseEEP(unsigned int adddata)
- { //擦除
- IAP_CONTR=0X83;//設置等待時間,
- IAP_CMD = 3; //讀取值1,寫取2,擦除取3,擦除時按所在字節整個扇區攛除
- IAP_ADDRL = adddata; //設置讀取地址的低字節,地址改變才需要設置
- IAP_ADDRH = adddata>>8; //設置讀取地址的高字節,地址改變才需要設置
- IAP_TRIG = 0x5A; //先送5A
- IAP_TRIG = 0xA5; //先送5A再送A5立即觸發
- _nop_();
- IAPIDLE();
- }
- void writeDAT()
- {
- eraseEEP(0x0200);
- writeEEP(0x0200, dingkong);//定時狀態
- writeEEP(0x0201, dingon_hour); // 開時
- writeEEP(0x0202, dingon_min);//開分
- writeEEP(0x0203, dingoff_hour);//關時
- writeEEP(0x0204, dingoff_min);//關分
- writeEEP(0x0205, BBkongvol);//按鍵不發聲
- writeEEP(0x0206, timeauto);//自動校時
- }
- void timedisp() //時間提取。這里只讀時分秒及星期,時采用24小時制。
- {
- unsigned char i,j,times,timeg;
- i =read_time(0x84);//讀時,這里還要判斷是24小時制還是12小時制。
- if(i>=0x80)
- { //12小時
- //只是小時的數值是最后5位為小時值,所以時的取法先置高3位為0,再除法及求余法。
-
- times=(i&0x1f)/16;//取高4位的數值給十分。
- timeg=i%16;//取低4位數值,把高4位置0。
- t_hour=times*10+timeg;
- j=i<<2;
- if(j>=0x80)
- {
- t_1224ji=1;//12小時制,0為24小時制。
- if(t_hour!=12){t_hour=t_hour+12;}//轉為24小時,方便計算。
- }
- else
- {
- t_1224ji=1; //2為上午。
- if(t_hour==12)t_hour=0;//轉為24小時,方便計算。
- }
- }
- else
- { //24小時
- times=i/16;//取高4位的數值給十分。
- timeg=i%16;//取低4位數值,把高4位置0。
- t_hour=times*10+timeg;
- t_1224ji=0;//24小時制
- }
- i=read_time(0x82);//讀分
- times=i/16;
- timeg=i%16;
- t_min=times*10+timeg;
- i =read_time(0x80);//讀秒
- times=i/16;
- timeg=i%16;
- t_sec=times*10+timeg;//算出當前秒數。
-
- }
- void disppage0(bit xaxin)
- {//當為0時,全屏更新,為1只刷新部份
- unsigned int kaka;
-
- if(xaxin==0)
- {
- OLED_Clear();
- // 藍牙房間控制
- OLED_ShowCHinese(16,0,0);
- OLED_ShowCHinese(32,0,1);
- OLED_ShowCHinese(48,0,2);
- OLED_ShowCHinese(64,0,3);
- OLED_ShowCHinese(80,0,4);
- OLED_ShowCHinese(96,0,5);
- }
- //18:55:23 36C 75%
- if(timetao==1&&time05s!=0)
- {
- OLED_ShowChar(0,2,13);
- OLED_ShowChar(8,2,13);
- }
- else
- {
- OLED_ShowChar(0,2,t_hour/10);
- OLED_ShowChar(8,2,t_hour%10);
- }
- if(time05s!=0&&timetao==0)
- {
- OLED_ShowChar(16,2,13);
- OLED_ShowChar(40,2,13);
- }
- else
- {
- OLED_ShowChar(16,2,10);
- OLED_ShowChar(40,2,10);
- }
- if(timetao==2&&time05s!=0)
- {
- OLED_ShowChar(24,2,13);
- OLED_ShowChar(32,2,13);
- }
- else
- {
- OLED_ShowChar(24,2,t_min/10);
- OLED_ShowChar(32,2,t_min%10);
- }
- if(timetao==3&&time05s!=0)
- {
- OLED_ShowChar(48,2,13);
- OLED_ShowChar(56,2,13);
- }
- else
- {
- OLED_ShowChar(48,2,t_sec/10);
- OLED_ShowChar(56,2,t_sec%10);
- }
- kaka=tempxidu%256;
- OLED_ShowChar(72,2,kaka/10);
- OLED_ShowChar(80,2,kaka%10);
- OLED_ShowChar(88,2,11);
- kaka=tempxidu/256;
- OLED_ShowChar(104,2,kaka/10);
- OLED_ShowChar(112,2,kaka%10);
- OLED_ShowChar(120,2,12);
- //開關狀態
- //讀P0值,低電平為開,
- if((P0&0x01)==0)
- {
- OLED_ShowCHinese(0,4,7);
- }
- else
- {
- OLED_ShowCHinese(0,4,15);
- }
- if((P0&0x02)==0)
- {
- OLED_ShowCHinese(16,4,8);
- }
- else
- {
- OLED_ShowCHinese(16,4,16);
- }
- if((P0&0x04)==0)
- {
- OLED_ShowCHinese(32,4,9);
- }
- else
- {
- OLED_ShowCHinese(32,4,17);
- }
- if((P0&0x08)==0)
- {
- OLED_ShowCHinese(48,4,10);
- }
- else
- {
- OLED_ShowCHinese(48,4,18);
- }
- if((P0&0x10)==0)
- {
- OLED_ShowCHinese(64,4,11);
- }
- else
- {
- OLED_ShowCHinese(64,4,19);
- }
- if((P0&0x20)==0)
- {
- OLED_ShowCHinese(80,4,12);
- }
- else
- {
- OLED_ShowCHinese(80,4,20);
- }
- if((P0&0x40)==0)
- {
- OLED_ShowCHinese(96,4,13);
- }
- else
- {
- OLED_ShowCHinese(96,4,21);
- }
- if((P0&0x80)==0)
- {
- OLED_ShowCHinese(112,4,14);
- }
- else
- {
- OLED_ShowCHinese(112,4,22);
- }
- //燈及插座工作狀態
- if(OUT1==0)
- {//低電平為開
- OLED_ShowCHinese(0,6,27);
- }
- else
- {
- OLED_ShowCHinese(0,6,23);
- }
- if(OUT2==0)
- {//低電平為開
- OLED_ShowCHinese(16,6,28);
- }
- else
- {
- OLED_ShowCHinese(16,6,24);
- }
- if(OUT3==0)
- {//低電平為開
- OLED_ShowCHinese(32,6,29);
- }
- else
- {
- OLED_ShowCHinese(32,6,25);
- }
- if(OUT4==0)
- {//低電平為開
- OLED_ShowCHinese(48,6,30);
- }
- else
- {
- OLED_ShowCHinese(48,6,26);
- }
- if(OUT5==0)
- {//低電平為開
- OLED_ShowCHinese(64,6,35);
- }
- else
- {
- OLED_ShowCHinese(64,6,31);
- }
- if(OUT6==0)
- {//低電平為開
- OLED_ShowCHinese(80,6,36);
- }
- else
- {
- OLED_ShowCHinese(80,6,32);
- }
- if(OUT7==0)
- {//低電平為開
- OLED_ShowCHinese(96,6,37);
- }
- else
- {
- OLED_ShowCHinese(96,6,33);
- }
- if(OUT8==0)
- {//低電平為開
- OLED_ShowCHinese(112,6,38);
- }
- else
- {
- OLED_ShowCHinese(112,6,34);
- }
- }
- void disppage1(bit xaxin)
- {//當為0時,全屏更新,為1只刷新部份
- if(xaxin==0)
- {
- OLED_Clear();
- //插座2定時設置
- OLED_ShowCHinese(0,0,41);
- OLED_ShowCHinese(16,0,42);
- OLED_ShowChar(32,0,2);
- OLED_ShowCHinese(40,0,43);
- OLED_ShowCHinese(56,0,44);
- OLED_ShowCHinese(72,0,45);
- OLED_ShowCHinese(88,0,46);
- }
- //選中 22:10-23:55
- if(settao==1&&time05s!=0)
- {
- OLED_ShowCHinese(0,2,6);
- }
- else
- {
- if(dingkong==0)
- {//當為0時不定時
- OLED_ShowCHinese(0,2,40);
- }
- else
- {
- OLED_ShowCHinese(0,2,39);
- }
- }
- if(settao==2&&time05s!=0)
- {
- OLED_ShowChar(16,2,13);
- OLED_ShowChar(24,2,13);
- }
- else
- {
- OLED_ShowChar(16,2,dingon_hour/10);
- OLED_ShowChar(24,2,dingon_hour%10);
- }
- OLED_ShowChar(32,2,10);
- if(settao==3&&time05s!=0)
- {
- OLED_ShowChar(40,2,13);
- OLED_ShowChar(48,2,13);
- }
- else
- {
- OLED_ShowChar(40,2,dingon_min/10);
- OLED_ShowChar(48,2,dingon_min%10);
- }
- OLED_ShowChar(56,2,14);
- if(settao==4&&time05s!=0)
- {
- OLED_ShowChar(64,2,13);
- OLED_ShowChar(72,2,13);
- }
- else
- {
- OLED_ShowChar(64,2,dingoff_hour/10);
- OLED_ShowChar(72,2,dingoff_hour%10);
- }
- OLED_ShowChar(80,2,10);
- if(settao==5&&time05s!=0)
- {
- OLED_ShowChar(88,2,13);
- OLED_ShowChar(96,2,13);
- }
- else
- {
- OLED_ShowChar(88,2,dingoff_min/10);
- OLED_ShowChar(96,2,dingoff_min%10);
- }
-
- //不選中 按鍵發聲
- if(settao==6&&time05s!=0)
- {
- OLED_ShowCHinese(0,4,6);
- }
- else
- {
- if(BBkongvol==0)
- {
- OLED_ShowCHinese(0,4,40);
- }
- else
- {
- OLED_ShowCHinese(0,4,39);
- }
- }
- if(xaxin==0)
- {
- OLED_ShowCHinese(16,4,47);
- OLED_ShowCHinese(32,4,48);
- OLED_ShowCHinese(48,4,52);
- OLED_ShowCHinese(64,4,53);
- //OLED_ShowCHinese(80,4,53);
- }
- //不選中 自動效時
- if(settao==7&&time05s!=0)
- {
- OLED_ShowCHinese(0,6,6);
- }
- else
- {
- if(timeauto==0)
- {
- OLED_ShowCHinese(0,6,40);
- }
- else
- {
- OLED_ShowCHinese(0,6,39);
- }
- }
- if(xaxin==0)
- {
- OLED_ShowCHinese(16,6,49);
- OLED_ShowCHinese(32,6,50);
- OLED_ShowCHinese(48,6,54);
- OLED_ShowCHinese(64,6,55);
- }
- }
- //***********************鍵盤掃描子程序。******************
- //*********************************************************
- unsigned char keyboard()//鍵盤掃描
- {
- unsigned char keyboardj;
- keyboardj=0;
- if(KEY1==0)
- {
- delay(10);
- if(KEY1==0)
- {
- keyboardj=1;
- }
- }
- if(KEY2==0)
- {
- delay(10);
- if(KEY2==0)
- {
- keyboardj=2;
- }
- }
- if(KEY3==0)
- {
- delay(10);
- if(KEY3==0)
- {
- keyboardj=3;
- }
- }
- if(KEY4==0)
- {
- delay(10);
- if(KEY4==0)
- {
- keyboardj=4;
- }
- }
- if(KEY5==0)
- {
- delay(10);
- if(KEY5==0)
- {
- keyboardj=5;
- }
- }
- if(KEY6==0)
- {
- delay(10);
- if(KEY6==0)
- {
- keyboardj=6;
- }
- }
- return keyboardj;
- }
- //************鍵盤控制子程序***************
- //K2短按為開電源,關機顯----,正常顯鉻鐵實際溫度,長按為調鉻鐵溫度,最后個C閃,表示調溫,再長按為存儲并退出調溫。
- //K3K1分別為向上向下,短按為慢速增加減少,長按為快速。調節范圍為200-480度。
- //******************************************
- void keydisphong()//主要功能是
- {
- unsigned char keyyy;
- keyyy=keyboard();
- if (keyyy!=oldkey)
- {
- if(keyyy==0)//
- {
- if(keyjixu>0)
- {
- if(keyjixu<80)
- {
-
- if(oldkey==6)
- {
- keyval=6;
- }
- if(oldkey==5)
- {
- keyval=5;
- }
- }
- else
- {
- //keyval=11;
- keyjixu=0;
- }
- }
- else
- {
- keyval=0;
- keyjixu=0;
- }
- }
- if(keyyy==1)
- {
- if(OUT1==0)
- {
- OUT1=1;
- }
- else
- {
- OUT1=0;
- }
-
- }
- if(keyyy==2)
- {
- if(OUT2==0)
- {
- OUT2=1;
- }
- else
- {
- OUT2=0;
- }
- }
- if(keyyy==3)
- {
- if(OUT3==0)
- {
- OUT3=1;
- }
- else
- {
- OUT3=0;
- }
- }
- if(keyyy==4)
- {
- if(OUT4==0)
- {
- OUT4=1;
- }
- else
- {
- OUT4=0;
- }
- }
- if(keyyy!=0)
- {
- //刷新
- if(pagevol==0&&keyval!=6)disppage0(1);
- if(BBkongvol==1)
- {//當BB可以發聲,就
- BB=1;//發響聲。
- bbtemp=15;//
- }
- }
- }
- oldkey=keyyy;
- if(keyyy==5)//
- {
- keyjixu++;
- if(keyjixu>=80)
- {
- if((keyjixu%6)==0)
- {
- keyval=15;
- }
- }
- }
- if(keyyy==6)//
- {
- keyjixu++;
- if(keyjixu==80)keyval=16;
- }
-
- //鍵盤處理完成。
- //以下為功能子程序
- if(keyval==5)
- {
- keyval=0;//這步必須的,清鍵值。
- keyjixu=0;//清計數值,這兩步是必要的。
- if(timetao==0&&settao==0)
- {
- //當不處于調整時,就控電器5
- if(OUT5==0)
- {
- OUT5=1;
- }
- else
- {
- OUT5=0;
- }
- }
- else
- {
- if(pagevol==0)
- {
- if(timetao==1)
- {//調時
- t_hour++;
- if(t_hour>23)t_hour=0;
- OLED_ShowChar(0,2,t_hour/10);
- OLED_ShowChar(8,2,t_hour%10);
- }
- if(timetao==2)
- {//調分
- t_min++;
- if(t_min>59)t_min=0;
- OLED_ShowChar(24,2,t_min/10);
- OLED_ShowChar(32,2,t_min%10);
- }
- if(timetao==3)
- {//調秒
- t_sec++;
- if(t_sec>59)t_sec=0;
- OLED_ShowChar(48,2,t_sec/10);
- OLED_ShowChar(56,2,t_sec%10);
- }
-
- }
- else
- {
- if(settao==1)
- {//調定時
- if(dingkong==0)
- {
- dingkong=1;
- }
- else
- {
- dingkong=0;
- }
- }
- if(settao==2)
- {//調開時
- dingon_hour++;
- if(dingon_hour>23)dingon_hour=0;
- OLED_ShowChar(16,2,dingon_hour/10);
- OLED_ShowChar(24,2,dingon_hour%10);
- }
- if(settao==3)
- {//調開分
- dingon_min++;
- if(dingon_min>59)dingon_min=0;
- OLED_ShowChar(40,2,dingon_min/10);
- OLED_ShowChar(48,2,dingon_min%10);
- }
- if(settao==4)
- {//調關時
- dingoff_hour++;
- if(dingoff_hour>23)dingoff_hour=0;
- OLED_ShowChar(64,2,dingoff_hour/10);
- OLED_ShowChar(72,2,dingoff_hour%10);
- }
- if(settao==5)
- {//調關分
- dingoff_min++;
- if(dingoff_min>59)dingoff_min=0;
- OLED_ShowChar(88,2,dingoff_min/10);
- OLED_ShowChar(96,2,dingoff_min%10);
- }
- if(settao==6)
- {//調發聲
- if(BBkongvol==0)
- {
- BBkongvol=1;
- }
- else
- {
- BBkongvol=0;
- }
- }
- if(settao==7)
- {//調自動校時
- if(timeauto==0)
- {
- timeauto=1;
- }
- else
- {
- timeauto=0;
- }
- }
- }
-
- }
- }
- if(keyval==6)
- {
- keyval=0;//這步必須的,清鍵值。
- keyjixu=0;//清計數值,這兩步是必要的。
- if(timetao==0&&settao==0)
- {
- if(pagevol==0)
- {
- pagevol=1;
- disppage1(0);
- }
- else
- {
- pagevol=0;
- disppage0(0);
- }
- }
- else
- {
- if(pagevol==0)
- {
- timetao++;
- if(timetao==4)
- {
- timetao=1;
-
- }
- }
- else
- {
- settao++;
- if(settao==8)
- {
- settao=1;
-
- }
- }
- }
- }
- if(keyval==15)
- {
- keyval=0;//這步必須的,清鍵值。
- //keyjixu=0;//清計數值,這兩步是必要的。
- if(pagevol==0)
- {
- if(timetao==1)
- {//調時
- t_hour++;
- if(t_hour>23)t_hour=0;
- OLED_ShowChar(0,2,t_hour/10);
- OLED_ShowChar(8,2,t_hour%10);
- }
- if(timetao==2)
- {//調分
- t_min++;
- if(t_min>59)t_min=0;
- OLED_ShowChar(24,2,t_min/10);
- OLED_ShowChar(32,2,t_min%10);
- }
- if(timetao==3)
- {//調秒
- t_sec++;
- if(t_sec>59)t_sec=0;
- OLED_ShowChar(48,2,t_sec/10);
- OLED_ShowChar(56,2,t_sec%10);
- }
-
- }
- else
- {
- if(settao==2)
- {//調開時
- dingon_hour++;
- if(dingon_hour>23)dingon_hour=0;
- OLED_ShowChar(16,2,dingon_hour/10);
- OLED_ShowChar(24,2,dingon_hour%10);
- }
- if(settao==3)
- {//調開分
- dingon_min++;
- if(dingon_min>59)dingon_min=0;
- OLED_ShowChar(40,2,dingon_min/10);
- OLED_ShowChar(48,2,dingon_min%10);
- }
- if(settao==4)
- {//調關時
- dingoff_hour++;
- if(dingoff_hour>23)dingoff_hour=0;
- OLED_ShowChar(64,2,dingoff_hour/10);
- OLED_ShowChar(72,2,dingoff_hour%10);
- }
- if(settao==5)
- {//調關分
- dingoff_min++;
- if(dingoff_min>59)dingoff_min=0;
- OLED_ShowChar(88,2,dingoff_min/10);
- OLED_ShowChar(96,2,dingoff_min%10);
- }
-
- }
- }
- if(keyval==16)
- {//長按進入設置及退出設置
- keyval=0;//這步必須的,清鍵值。
- //keyjixu=0;//清計數值,這兩步是必要的。
- if(pagevol==0)
- {
- if(timetao==0)
- {
- timetao=1;
- }
- else
- {//保存數據
- timetao=0;
- write_time(0X84,(t_hour/10)*16+t_hour%10);//時
- write_time(0X82,(t_min/10)*16+t_min%10);//寫分
- write_time(0X80,(t_sec/10)*16+t_sec%10);//寫秒
- }
- }
- else
- {
- if(settao==0)
- {
- settao=1;
- }
- else
- {//保存數據
- settao=0;
- writeDAT();
- }
- }
- }
-
- }
- void dingtimekong()
- {//定時控制,采用觸發式。每0.5S比較一次
- if(dingkong==1)
- {
- if(dingon_hour==t_hour&&dingon_min==t_min)OUT6=0;
- if(dingoff_hour==t_hour&&dingoff_min==t_min)OUT6=1;
- }
- }
- unsigned char DHT11readbit()
- {
- unsigned char i,temp,dataDHT,caoxi;
- for(i=0;i<8;i++)
- {
- //數據時序先低電平50us,再高電平,當26-28us為0、70us為1。
- caoxi=2;
- while((!DHT11DA)&&caoxi++);//檢測50us低電平是否過去。
- delay10us();delay10us();delay10us();//延時30us,再判斷,如還是高電平就數據為1,如低電平為0。
- temp=0; //先置0
- if(DHT11DA)temp=1; //超過30us還是高電平的就置1。
- caoxi=2;
- while((DHT11DA)&&caoxi++);//如還是高電平就等它為低電平,如超時就跳出循環.
- //超時則跳出for循環
- if(caoxi==1)break;
- //合成數據
- dataDHT<<=1;
- dataDHT|=temp;
- }
- return(dataDHT);
- }
- unsigned int DHT11read() //由于返回的溫度及濕度只有2個8b,所以用個16b的來存貯,前8位為濕度,后8位為溫度。
- {
- unsigned char temp1,temp2,temp3,temp4,temp5,caoxi;
- unsigned int DHTdata ;
- //主機拉低大于18ms
- DHT11DA=0;
- delay(20);
- DHT11DA=1;
- //主機放開總線,由上拉電阻拉高 主機延時20us-40us.
- delay10us();delay10us();delay10us();delay10us();
- //判斷從機是否有低電平響應信號 如不響應則跳出,響應則向下讀數。
- if(DHT11DA==0)
- {
- caoxi=2;//初始化超時值,對于22M晶振為175us,主要是防止DHT不動作引起程序進入死循環,超時就跳出來。
- while((!DHT11DA)&&caoxi++);
- //判斷從機是否發出 80us 的高電平,如發出則進入數據接收狀態
- caoxi=2;
- while((DHT11DA)&&caoxi++);
- //數據接收狀態
- temp1=DHT11readbit();
- temp2=DHT11readbit();
- temp3=DHT11readbit();
- temp4=DHT11readbit();
- temp5=DHT11readbit();
- //數據校驗
- DHT11DA=1;
- if(temp5=(temp1+temp2+temp3+temp4)) //如校對正確就組合數據,并返回。
- {
- DHTdata=temp1*256+temp3;
- }
- else
- {
- DHTdata=0;//當數據不正確時,就送0值,當然這一步看情況來決定是否用它。
- }
- }
- return(DHTdata); //返回數據
- }
- void rs2232tx(unsigned char txdata)//串口2發送程序
- {
- S2BUF=txdata;//把數據傳給串口寄存器SBUF。
- while(!(S2CON & 0x02));//檢測是否發完。
- //S2TI=0;//重置初值。
- S2CON=S2CON & 0xfd;
- }
- void senddata()
- {//串口數據發送,命令格式EF,EE,P0(低7位開關狀態),P2(低7位輸出狀態),P0P2第8位(主要是防止與引導碼沖突),溫度,濕度,定時狀態,開時,開分,關時,關分,FF 不進行校驗數據。
- //為方便手機編程,傳送的數據用BCD碼
- unsigned char kkkkk,hhhh;
- rs2232tx(0xef);
- rs2232tx(0xee);
- rs2232tx(P0&0x7f);
- rs2232tx(P2&0x7f);
- kkkkk=0;
- if((P0&0x80)!=0)
- {
- kkkkk=kkkkk+2;
- }
- if((P2&0x80)!=0)
- {
- kkkkk=kkkkk+1;
- }
- rs2232tx(kkkkk);
- kkkkk=tempxidu%256;
- hhhh=(kkkkk/10)*16+kkkkk%10;
- rs2232tx(hhhh);
- kkkkk=tempxidu/256;
- hhhh=(kkkkk/10)*16+kkkkk%10;
- rs2232tx(hhhh);
- rs2232tx(dingkong);
- kkkkk=dingon_hour;
- hhhh=(kkkkk/10)*16+kkkkk%10;
- rs2232tx(hhhh);
- kkkkk=dingon_min;
- hhhh=(kkkkk/10)*16+kkkkk%10;
- rs2232tx(hhhh);
- kkkkk=dingoff_hour;
- hhhh=(kkkkk/10)*16+kkkkk%10;
- rs2232tx(hhhh);
- kkkkk=dingoff_min;
- hhhh=(kkkkk/10)*16+kkkkk%10;
- rs2232tx(hhhh);
- rs2232tx(0xff);
- }
- void rscRSkongji()
- {//串口數據接收后處理子程序
- //開關控制 命令 01 受控值,00,00,00,00
- //校時控制 命令 02 時 分 秒 00 00
- //定時控制 命令 03 受控值 開時 開分 關時 關分
- if(rscRSkong==1)
- {//收到處理的數據
-
- switch(recRSvol[0])
- {
- case 1:
- if((recRSvol[1]&0x01)!=0)
- {//當手機開關1按下
- if(OUT1==0)
- {
- OUT1=1;
- }
- else
- {
- OUT1=0;
- }
- }
- if((recRSvol[1]&0x02)!=0)
- {//當手機開關1按下
- if(OUT2==0)
- {
- OUT2=1;
- }
- else
- {
- OUT2=0;
- }
- }
- if((recRSvol[1]&0x04)!=0)
- {//當手機開關1按下
- if(OUT3==0)
- {
- OUT3=1;
- }
- else
- {
- OUT3=0;
- }
- }
- if((recRSvol[1]&0x08)!=0)
- {//當手機開關1按下
- if(OUT4==0)
- {
- OUT4=1;
- }
- else
- {
- OUT4=0;
- }
- }
- if((recRSvol[1]&0x10)!=0)
- {//當手機開關1按下
- if(OUT5==0)
- {
- OUT5=1;
- }
- else
- {
- OUT5=0;
- }
- }
- if((recRSvol[1]&0x20)!=0)
- {//當手機開關1按下
- if(OUT6==0)
- {
- OUT6=1;
- }
- else
- {
- OUT6=0;
- }
- }
- if((recRSvol[1]&0x40)!=0)
- {//當手機開關1按下
- if(OUT7==0)
- {
- OUT7=1;
- }
- else
- {
- OUT7=0;
- }
- }
- if((recRSvol[1]&0x80)!=0)
- {//當手機開關1按下
- if(OUT8==0)
- {
- OUT8=1;
- }
- else
- {
- OUT8=0;
- }
- }
- break;
- case 2:
- //手機自動校時,當手機建立連接時,如需自動校時,就啟用。這是在串口中斷程序內執行。
- if(timeauto==1)
- {
- write_time(0X84,(recRSvol[1]/10)*16+recRSvol[1]%10);//時
- write_time(0X82,(recRSvol[2]/10)*16+recRSvol[2]%10);//寫分
- write_time(0X80,(recRSvol[3]/10)*16+recRSvol[3]%10);//寫秒
- }
- break;
- case 3: //需BCD碼轉16進
- dingkong=recRSvol[1];
- dingon_hour=(recRSvol[2]/16)*10+recRSvol[2]%16;
- dingon_min=(recRSvol[3]/16)*10+recRSvol[3]%16;
- dingoff_hour=(recRSvol[4]/16)*10+recRSvol[4]%16;
- dingoff_min=(recRSvol[5]/16)*10+recRSvol[5]%16;
- writeDAT();
- break;
- default: break;
- }
-
- rscRSkong=0;
- }
-
- }
- void sysintEEP()
- {
- dingkong=readEEP(0x0200);//定時狀態
- dingon_hour=readEEP(0x0201); // 開時
-
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (11.53 KB, 下載次數: 73)
下載附件
2018-9-2 18:18 上傳
0.png (37.86 KB, 下載次數: 84)
下載附件
2018-9-2 18:18 上傳
所有資料51hei提供下載:
藍牙手機控制的懶人專用智能房間控制器設計資料.rar
(1.11 MB, 下載次數: 249)
2018-9-2 14:51 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|