- 家有惡貓,任性跋扈;
- 貪吃貪睡,屎尿巨臭;
- 爪力強勁,刨砂瘋狂;
- 貓砂四濺,塵土飛揚;
- 娘子過敏,噴嚏不止;
- 吾心痛焉,技以治之;
本設計用到的元器件:
1.STC12C5068AD為主控;
2.DS1302為時鐘IC;
3.TD1030衛星定位授時模塊授時;
4.TM1637模塊用于顯示時間;
5.E18-D80NK型光電開關為觸發開關;
6.輔以土壤濕度監測模塊監測砂盆附近花盆里的土壤濕度;
7.對外輸出包括兩路低電平有效的繼電器模塊(控制風扇、水泵的開關)、蜂鳴器、指示燈等。
實現的主要功能:
1.在惡貓進入砂盆后出發光電開關輸出維持低電平,打開風扇開始通風除塵;
2.當惡貓大小便完畢離開砂盆,光電開關輸出恢復高電平,使用單片機PCA模塊的觸發捕獲功能捕獲上升沿跳變,風扇延時開啟2min后關閉;
3.每隔1h自動打開風扇2min通風除味;
4.每天早上07:10打開水泵30s向花盆噴水(潤濕植物表層);
5.當土壤濕度模塊檢測到土壤濕度過低,啟動水泵澆水;
6.每天早上7:00及晚上19:00自動打開衛星定位授時模塊校準時間。
電路原理圖如下:
原理圖.jpg (83.04 KB, 下載次數: 77)
下載附件
簡單原理圖
2018-8-27 06:18 上傳
部分單片機程序:
- #include "STC12C56XX.H"
- #include "intrins.h"
- #include "TM1637.h"
- #include "DS1302.h"
- /*定義各個端口*/
- sbit GPS_EN=P2^4; //定義GPS模塊使能端口
- sbit LED=P2^5; //定義GPS_LED開關端口
- sbit FAN=P2^6; //定義風機信號端口(繼電器驅動)
- sbit PUMP=P2^7; //定義水泵信號端口(繼電器驅動)
- sbit SPK=P3^7; //定義蜂鳴器信號端口
- sbit SD=P1^0; //定義土壤濕度信號端口(數字信號)
- sbit GPS_RST=P1^4; //GPS手動對時按鍵
- sbit SW=P3^5; //定義觸發端口,低電平有效,一并捕獲上升沿觸發
- sbit EPCAI=IE^6; //PCA模塊和LVD監測中斷允許位(在頭文件中為EPCA_LVD)
- /*定義各個變量、數組及標志位*/
- unsigned char hour,min,sec,hourr,minr,secr,hour1,hour2,min1,min2;//小時,分鐘,秒鐘,小時收到,分鐘收到,秒鐘收到,小時十位,小時個位,分鐘十位,分鐘個位
- bit rev_start,rev_stop; //串口接收開始標志位,接收停止標志位
- bit flagT,flag_PCA; //計時標志位,PCA觸發標志位
- unsigned int t50ms; //定時變量
- unsigned char buf[80]; //接收到GPS數據存儲到該數組
- void delayms(unsigned int xms)//ms延時函數
- {
- unsigned int i,j;
- for(i=0; i<xms; i++)
- for(j=0; j<500; j++);
- }
-
- void USART_Init() //串口及定時器0,1初始化
- {
- TMOD=0x21; //定時器1工作在方式2,8位自動重裝,定時器0工作在模式1
- SCON = 0x50; //使用串行工作方式1,10位異步收發8位數據,波特率可變(由T1的溢出率控制)
- TH1 = TL1=0xFD; //9600波特率的初值
- // TH1 = TL1=0xFA; //4800波特率的初值
- ES = 1; //開串口中斷
- TR1 = 1; //允許T1計數
- TH0 = 0x3C; //裝定時器0初值,TH0=(65535-50000)/256,TL0=(65535-50000)%256
- TL0 = 0xB0; //50ms中斷一次
- ET0 = 1; //開T0中斷
- TR0 = 1; //允許T0計數
- EA=1; //開總中斷
- }
- void PCA_Init() //PCA初始化,關于計數部分的配置可注釋掉,這里只用到了捕獲模式
- {
- CCON=0; //初始化PCA控制寄存器,PCA定時器停止運行,清零CF標志位,清零所有模式中斷標志位
- CL=0; //重置PCA計數器
- CH=0;
- CMOD=0x00; //設置PCA計數器時鐘源為Fosc/12,禁止PCA計數器溢出中斷
- // CCAPM1=0x31; //PCA模塊1工作在16位捕獲模式,跳變觸發
- CCAPM1=0x21; //PCA模塊1工作在16位捕獲模式,上升沿觸發
- CR=1; //PCA計數器啟動
- EPCAI=1; //開PCA中斷
- EA=1; //開總中斷
- }
- /* NMEA0183協議中最簡定位信息GNRMC數據格式 */
- /* $GNRMC,203741.00,A,3636.39993,N,12011.80057,E,0.023,,270718,,,A,V*19 */
- /* 定位成功的GNRMC數據格式,串口調試模擬發送時務必要有換行標志"\n"符提示接收停止 */
- /* $GNRMC,,V,,,,,,,,,,N,V*37 */
- /* 無信號時的GNRMC數據,即無效定位/授時數據,此時Write_time函數將從','和'V'中取值,所以需要判斷定位/授時數據的有效性 */
- void Write_time()//將GPS授時數據取值轉換并寫入DS1302
- {
- if((rev_stop==1)&&(buf[0]=='R')&&(buf[2]=='C')&&(buf[4]!=','))//如果接收到GPRMC,從'R'開始接受計數,當buf[4]!=','時,授時數據有效,否則無效
- {
- ES=0; //關閉串口中斷
- hourr= (buf [4]-0x30)* 16+ buf[5] -0x30; //取hour數值HEX
- minr= (buf [6]-0x30)* 16+ buf[7]-0x30; //取min數值HEX
- secr= (buf[8]-0x30)* 16+ buf[9]-0x30; //取sec數值HEX
- hourr= hourr / 16 * 10 + hourr % 16; //HEX-DEC
- hourr= (hourr+8) % 24; //UTC Time換算成北京時間,+8h
- hourr=hourr/10*16+hourr%10; //DEC-HEX
- set_time(secr,minr,hourr); //授時數據寫入DS1302
- ES=1; //開啟串口中斷
- rev_stop=0; //接收停止標志位清零
- }
-
- }
- void Read_time() //從DS1302中讀取時間數據
- {
- hour= ds1302_read(0x85); //小時
- min = ds1302_read(0x83); //分鐘
- sec = ds1302_read(0x81); //秒鐘
- }
- void jisuan(void) //根據接收到的授時數據取值
- {
- hour1=hour/16; //取hour十位
- hour2=hour%16; //取hour個位
- min1=min/16; //取min十位
- min2=min%16; //取min個位
- if (sec%2==0) //判斷sec奇偶
- {
- hour2=hour2+10; //":"閃爍,間隔1s,亮1s,滅1s
- }
- }
- void da() //長鳴一聲,代表整點報時及動作開啟
- {
- SPK=1;
- delayms(2000);
- SPK=0;
- }
- void daa() //短鳴一聲,用于GPS授時時的聲音提示
- {
- SPK=0;
- delayms(1000);
- SPK=1;
- delayms(1000);
- SPK=0;
- }
- void didi() //短鳴兩聲,代表動作結束
- {
- SPK=1;
- delayms(500);
- SPK=0;
- delayms(300);
- SPK=1;
- delayms(500);
- SPK=0;
- }
- void shan() //GPS模塊上的LED閃爍
- {
- LED=0;
- delayms(1000);
- LED=1;
- delayms(1000);
- LED=0;
- }
- void Out(void) //定時輸出
- {
- if((min==0x30)&&(sec==0x00)) {da();} //每隔1h(xxh30m00s時),蜂鳴器長鳴一聲
- else if(((min>=0x30)&&(min<0x32))||(SW==0)) {FAN=0;} //風機啟動2min(xxh30m00s-xxh32m00s),如果光電開關被觸發且維持低電平,維持風機啟動
- else if((min==0x32)&&(sec==0x00)) {FAN=1;didi();} //2min后(xxh32m00s時),關閉風機,蜂鳴器短鳴兩聲
- else if((min==0x00)&&(sec==0x00)) {da();} //每個整點(xxh00m00s時),蜂鳴器長鳴一聲,整點報時
- else if((hour==0x07)&&(min==0x10)&&(sec==0x00)) {da();} //每天早上07h10m00s,蜂鳴器長鳴一聲
- else if((hour==0x07)&&(min==0x10)&&(sec<0x30)&&(sec>=0x00)) {PUMP=0;} //水泵啟動30s(07h10m00s-07h10m30s)
- else if((hour==0x07)&&(min==0x10)&&(sec==0x30)) {PUMP=1;didi();} //30s后(07h10m30s時),關閉水泵,蜂鳴器短鳴兩聲
- else if(SD==1) {PUMP=0;} //如果土壤濕度低于設定值,開啟水泵澆水
- // else if(SW==0) {FAN=0;} //如果光電開關被觸發且維持低電平,維持風機啟動
- else {FAN=PUMP=1;SPK=0;}
- }
- void chufa() //PCA觸發定時執行
- {
- if(flag_PCA==1) //被觸發
- {
- FAN=0; //開啟風機
- if(flagT==1) //定時滿2min
- {
- FAN=1; //關閉風機
- flagT=0; //清零定時標志位
- flag_PCA=0;//清零觸發標志位
- }
- }
- }
- void main()
- {
- P2M0=0x00;
- P2M1=0xf0; //P24-P27強推挽輸出
- P3M0=0x20;
- P3M1=0x80; //P37強推挽輸出,P35高阻輸入
- FAN=PUMP=SW=1; //關閉風機、水泵,觸發端口置高
- SPK=0; //關閉蜂鳴器
- GPS_EN=0; //關閉GPS模塊
- LED=1; //開啟GPS模塊上的LED
- GPS_RST=1; //GPS手動對時按鍵端口置高
- PCA_Init(); //PCA初始化
- USART_Init(); //串口及定時器0初始化
- while(1)
- {
- if(((hour==0x07)&&(min==0x00))||((hour==0x19)&&(min==0x00))||(GPS_RST==0)) //每天(07:00、19:00)定時打開GPS校準時間再關掉,對時持續1min,也可手動觸發校準
- {GPS_EN=1;shan();daa();ES=1;} //使能GPS模塊,LED閃爍,蜂鳴器鳴響,開啟串口中斷
- else
- {GPS_EN=0;LED=0;ES=0;} //關閉GPS模塊,LED關閉,關閉串口中斷
- Write_time(); //向DS1302中寫入時間
- Read_time(); //讀取DS1302中的時間數據
- Out(); //輸出
- chufa(); //PCA觸發執行延時
- jisuan(); //接收時間數據并取值
- xsled(hour1,hour2,min1,min2); //顯示時間
- }
- }
- void Uart_Receive(void) interrupt 4 //串口中斷,接收GNRMC授時數據
- {
- unsigned char ch,num; //定義接收字符、數組計數變量
- ES = 0; //關閉串口
- if (RI) //如果接收完成則進入
- {
- ch=SBUF; //從串口緩沖寄存器中取值
- if(ch=='R') //如果收到字符'R',便開始接收
- {
- rev_start=1; //接收開始標志位置1
- rev_stop =0; //接收停止標志置0
- }
- if(rev_start==1) //標志位為1,開始接收
- {
- buf[num++]=ch; //字符存到數組中
- if (ch=='\n') //如果接收到換行
- {
- buf[num]='\n';
- rev_start=0; //接收開始標志位置0
- rev_stop=1; //接收停止標志位置1
- num=0; //計數置0
- }
- }
- }
- RI = 0; //RI清0,重新接收
- ES = 1; //串口1中斷允許
- }
- void TIM0(void) interrupt 1 //定時器0中斷函數
- {
- TH0 = 0x3C; //重裝初值
- TL0 = 0xB0;
- if(flag_PCA==1) //如果觸發
- {
- t50ms++; //開始計時
- if(t50ms>=2400) //計時滿2min時,實際測試約2min10sec
- {
- t50ms=0; //清零計時變量
- flagT=1; //計時標志位置1
- }
- }
- }
- void PCA_isr() interrupt 6 //PCA捕獲模式中斷函數
- {
- CCF1=0; //清零中斷標志位
- flag_PCA=1; //觸發執行標志位
- }
復制代碼
全部資料51hei下載地址:
GPS授時.zip
(54.18 KB, 下載次數: 19)
2018-8-27 06:22 上傳
點擊文件名下載附件
程序 下載積分: 黑幣 -5
|