花卉自動澆水系統仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
QQ截圖20180527085033.jpg (132.01 KB, 下載次數: 65)
下載附件
2018-5-27 08:50 上傳
0.png (13.64 KB, 下載次數: 40)
下載附件
2018-5-27 16:57 上傳
我的畢業設計,自動澆水系統的仿真程序,是基于單片機的
單片機源碼如下:
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit Key_Min=P3^5;
- sbit Key_Add=P3^6;
- sbit Key_Set=P3^7;
- sbit Key_Mode=P1^0;
- sbit Key_Low=P1^2;
- sbit Key_High=P1^3;
- sbit led1=P3^2; //綠燈,澆水狀態,與繼電器同步
- sbit led2=P3^3; //黃燈,水位上限
- sbit led3=P3^4; //紅燈,水位下限
- //------------繼電器引腳-------------------
- sbit JD=P2^1;
- sbit sw=P1^6;
- sbit BEEP=P2^0;
- uchar HumTab=0; //溫度澆水時上下限切換的標志,記錄是上一個狀態,0是缺少,1是盛水。
- sbit rs=P2^5; //命令/數據選擇
- sbit rw=P2^6; //讀寫口
- sbit e=P2^7; //鎖存控制
- sbit DQ = P1^5;
- bit DS18B20_IS_OK = 1; //DS18B20 正常標志
- uchar Temp_Value[]={0x00,0x00}; //讀到的溫度值
- #define NOP() _nop_() /* 定義空指令 */
- #define _Nop() _nop_() /*定義空指令*/
- uchar ThresholdL=20; //濕度閥值下限,低于這個值就開始澆水;
- uchar ThresholdH=50; //濕度閥值上限,澆水超過這個值就停止澆水
- uchar code df_Table[]={ 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9 };
- uchar Display_Digit[]={0,0,0,0};
- uchar CurrentT = 0;
- float time=0.0;
- long distance=0.0;
- int num=0,num1=0;
- //**************************************************************************************************
- //延時函數
- //**************************************************************************************************
- void delay(uint time) //int型數據為16位,所以最大值為65535
- {
- uint i,j; //定義變量i,j,用于循環語句
- for(i=0;i<time;i++) //for循環,循環50*time次
- for(j=0;j<100;j++); //for循環,循環50次
- }
- void Delay1(uint x) //延時 2
- {
- while(x--);
- }
- //**************************************************************************************************
- //向LCD寫一命令
- //**************************************************************************************************
- void wcode(uchar t)
- {
- rs=0; // 寫的是命令
- rw=0; // 寫狀態
- e=1; //使能
- P0=t; //寫入命令
- delay(20); //等待寫入,如果時間太短,會導致液晶無法顯示
- e=0; //數據的鎖定
- }
- //**************************************************************************************************
- //向LCD寫一數據
- //**************************************************************************************************
- void wdata(uchar t)
- {
- rs=1; // 寫的是數據
- rw=0; // 寫狀態
- e=1; //使能
- P0=t; //寫入數據
- delay(20); //等待寫入,如果時間太短,會導致液晶無法顯示
- e=0; //數據的鎖定
- }
- //**************************************************************************************************
- //LCD顯示第一行
- //**************************************************************************************************
- void xian1(uchar *dis)
- {
- uchar i;
- wcode(0x80); //設置第一行顯示地址
- for(i=0;i<16;i++) //循環16次,寫完1行
- {
- wdata(dis[ i]); //寫入該行數據[ i]
- }
- }
- //**************************************************************************************************
- //LCD顯示第二行
- //**************************************************************************************************
- void xian2(uchar *str)
- {
- uchar i;
- wcode(0xc0); //設置第二行顯示地址
- for(i=0;i<16;i++) //循環16次,寫完1行
- {
- wdata(str[ i]); //寫入該行數據[ i]
- }
- }
- //**************************************************************************************************
- //LCD 初始化
- //**************************************************************************************************
- void InitLCD()
- {
- wcode(0x01); //清屏
- wcode(0x06); //輸入方式控制,增量光標不移位
- wcode(0x0c); //顯示開關控制
- wcode(0x38); //功能設定:設置16x2顯示,5x7顯示,8位數據接口
- }
- /*********************************************************/
- // 液晶光標定位函數
- /*********************************************************/
- void LcdGotoXY(uchar line,uchar column)
- {
- if(line==1) // 第一行
- wcode(0x80+column-1);
- if(line==2) // 第二行
- wcode(0xC0+column-1);
- }
- /*********************************************************/
- // 液晶輸出數字
- /*********************************************************/
- void LcdPrintNum(uchar num)
- {
- wdata(num/10%10+0x30);
- wdata(num%10+0x30);
- }
- void delay100us(void) //誤差 0us
- {
- unsigned char a,b;
- for(b=19;b>0;b--)
- for(a=1;a>0;a--);
- }
- uchar Init_DS18B20() //初始化(或者說復位) DS18B20
- {
- uchar status;
- DQ = 1;
- Delay1(8);
- DQ = 0;
- Delay1(90);
- DQ = 1;
- Delay1(8);
- status=DQ;Delay1(100);
- DQ = 1;
- return status;
- }
- uchar ReadOneByte() //從 DS18B20 讀一字節數據
- {
- uchar i,dat=0;
- DQ = 1;
- _nop_();
- for(i=0;i<8;i++)
- {
- DQ = 0;
- dat >>= 1;
- DQ = 1;
- _nop_();
- _nop_();
- if(DQ)
- dat |= 0X80;
- Delay1(30);
- DQ = 1;
- }
- return dat;
- }
- void WriteOneByte(uchar dat) //從 DS18B20 寫一字節數據
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DQ = 0;
- DQ = dat& 0x01;
- Delay1(5);
- DQ = 1;
- dat >>= 1;
- }
- }
- void Read_Temperature() //從 DS18B20 讀取溫度值
- {
- if(Init_DS18B20()==1) //DS18B20 故障
- DS18B20_IS_OK=0;
- else
- {
- WriteOneByte(0xcc); //跳過序列號命令
- WriteOneByte(0x44); //啟動溫度轉換命令
- Init_DS18B20(); //復位 DS18B20 ( 每一次讀寫之前都要對 DS18B20 進行復位操作)
- WriteOneByte(0xcc); //跳過序列號命令
- WriteOneByte(0xbe); //讀取溫度寄存器
- Temp_Value[0] = ReadOneByte(); //讀取溫度低 8 位(先讀低字節,再讀高字節,)
- Temp_Value[1] = ReadOneByte();//讀取溫度高 8 位 (每次只能讀一個字節)
- DS18B20_IS_OK=1; //DS18B20 正常
- }
- }
- void Display_Temperature() //在 1602LCD 上顯示當前溫度
- {
-
- uchar t = 150, ng = 0; //延時值與負數標志
- if((Temp_Value[1]&0xf8)==0xf8) //高字節高 5 位如果全為 1,則為負數,為負數時取反
- { //加 1,并設置負數標志為 1
- Temp_Value[1] = ~Temp_Value[1];
- Temp_Value[0] = ~Temp_Value[0]+1;
- if(Temp_Value[0]==0x00) //若低字節進位,則高字節加 1
- Temp_Value[1]++;
- ng = 1; //設置負數標志為 1
- }
- Display_Digit[0] = df_Table[Temp_Value[0]&0x0f]; //查表得到溫度小數部分
- //獲取溫度整數部分(低字節低 4 位清零,高 4 位右移 4 位) +(高字節高 5 位清零,
- //低三位左移 4 位)
- CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4);
- //將溫度整數部分分解為 3 位待顯示數字
- Display_Digit[3] = CurrentT/100;
- Display_Digit[2] = CurrentT%100/10;
- Display_Digit[1] = CurrentT%10;
- //刷新 LCD 緩沖 //加字符 0 是為了將待數字轉化為字符顯示
- LcdGotoXY(2,3);
- wdata(Display_Digit[2]+'0');
- wdata(Display_Digit[1]+'0');
- wdata('.');
- wdata(Display_Digit[0]+'0');
- }
- void delay10ms(void) //誤差 -0.000000000001us
- {
- unsigned char a,b,c;
- for(c=7;c>0;c--)
- for(b=168;b>0;b--)
- for(a=22;a>0;a--);
- }
- void WateringIntelligence() //智能控制模式
- {
- //--------------設置濕度上下限函數----
- {
- JD=1;
- wcode(0x0f); // 顯示光標,并閃爍
- //delay10ms();
- while(Key_Set==0); // 等待按鍵釋放
- //delay10ms();
- wcode(0x01); // 清屏
- xian1("Humidity Set "); // 顯示 "Humidity Set" (第一行)
- xian2(" - %RH "); // 顯示“ - %RH ” (第二行)
- LcdGotoXY(2,5);
- LcdPrintNum(HumiLowTemp);
- LcdGotoXY(2,8);
- LcdPrintNum(HumiHigTemp);
- LcdGotoXY(2,6);
- /*****濕度下限值設置******************************************
- ------------------------------------------------------------*/
- while(Key_Set!=0)
- {
- if(Key_Min==0) // 濕度下限值 減
- {
- HumiLowTemp--;
- if(HumiLowTemp<0)
- HumiLowTemp=0;
- LcdGotoXY(2,5); // 顯示濕度下限值
- LcdPrintNum(HumiLowTemp);
- LcdGotoXY(2,6);
- delay(500);
- }
- if(Key_Add==0) // 濕度下限值 加
- {
- HumiLowTemp++;
- if(HumiLowTemp==100)
- HumiLowTemp=99;
- LcdGotoXY(2,5); // 顯示濕度下限值
- LcdPrintNum(HumiLowTemp);
- LcdGotoXY(2,6);
- delay(500);
- }
- }
- //delay10ms();
- while(Key_Set==0); // 等待按鍵釋放
- //delay10ms();
- LcdGotoXY(2,9);
- while(Key_Set!=0) // 如果按鍵1按下,那么跳到下一級設置,否則是濕度上限值的大小設置
- {
- if(Key_Min==0) // 濕度上限值 減
- {
- HumiHigTemp--;
- if(HumiHigTemp<0)
- HumiHigTemp=0;
- LcdGotoXY(2,8); // 顯示濕度上限值
- LcdPrintNum(HumiHigTemp);
- LcdGotoXY(2,9);
- delay(500);
- }
- if(Key_Add==0) // 濕度上限值 加
- {
- HumiHigTemp++;
- if(HumiHigTemp==100)
- HumiHigTemp=99;
- LcdGotoXY(2,8); // 顯示度上限值
- LcdPrintNum(HumiHigTemp);
- LcdGotoXY(2,9);
- delay(500);
- }
- }
- //delay10ms();
- while(Key_Set==0); // 等待按鍵釋放
- //delay10ms();
- wcode(0x0c);
-
- ThresholdL=HumiLowTemp; // 更新濕度下限報警值
- ThresholdH=HumiHigTemp; // 更新濕度上限報警
-
- InitLCD(); //初始化1602
- xian1("Watering System "); //顯示第一行
- xian2("T: C H: %RH "); //顯示第二行
- LcdGotoXY(2,5);
- wdata(0xdf);
-
- }
- if(sw==0) //當前溫度低于閾值下限,澆水
- {
- JD=0;
- led1=0;
- HumTab=0;
- LcdGotoXY(2,10);
- LcdPrintNum(19);
-
- }
- else //當前溫度高于閾值上限,停止澆水
- {
- JD=1;
- led1=1;
- HumTab=1;
- LcdGotoXY(2,10);
- LcdPrintNum(53);
- }
- }
- //水位檢測函數
- void CheckWaterLevel()
- {
- if(Key_Low==1&&Key_High==1)//高低水位都沒水
- {
- led3=0; //下水位,快沒水了
- led2=1;
- BEEP=0; //蜂鳴器報警
- }
- else if(Key_Low==0&&Key_High==0)//低水位有水,高水位有水,水滿了
- {
- led3=1;
- led2=0;
- BEEP=0;
- }
- else
- {
- led3=1;
- led2=1;
- BEEP=1;
- }
- }
- void main()
- {
- InitLCD(); //初始化1602
- xian1("Watering System ");
- xian2("T: C H: %RH "); //顯示第二行
- LcdGotoXY(2,5);
- wdata(0xdf);
- while(1) //進入死循環,防止看門狗復位
- {
- //key1deal();
- Read_Temperature();
- Display_Temperature();
- CheckWaterLevel();
- WateringIntelligence();
- delay(1000);
- }
- }
復制代碼
全部資料51hei下載地址:
花卉自動澆水.rar
(76.03 KB, 下載次數: 159)
2018-5-27 08:53 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|