采用STC89C52作為主控芯片,ADC0804采集模擬信號作為花園土壤濕度,DS18B20采集溫度,LCD1602顯示溫濕度;
當溫度低于下限值,啟動水泵進行澆水;
當溫度高于上限值,停止水泵。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
hello.jpg (1.46 MB, 下載次數: 80)
下載附件
2018-6-6 23:38 上傳
0.png (50.75 KB, 下載次數: 77)
下載附件
2018-6-7 01:20 上傳
單片機源程序如下:
- #include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
- #include<intrins.h>
- #include<stdio.h>
- #include "18b20.h"
- #include "delay.h"
- #include "key.h"
- #define uint unsigned int
- #define uchar unsigned char
- #define ZERO 4.5 //濕度傳感器放空氣中的電壓值 對應濕度0%
- #define FULL 0.45 //濕度傳感器放水中的電壓值 對應濕度100%
- float k,b;//計算濕度用斜率
- sbit RS = P2^5; //定義LCD1602端口
- sbit RW = P2^6;
- sbit EN = P2^7;
- #define DataPort P0
- sbit CS = P2^0; //定義ADC0832端口
- sbit CLK = P2^1;
- sbit DIO = P2^2;
- sbit MOETOR = P3^6;//水泵控制端口
- #define RS_CLR RS=0
- #define RS_SET RS=1
- #define RW_CLR RW=0
- #define RW_SET RW=1
- #define EN_CLR EN=0
- #define EN_SET EN=1
- float d; //實時濕度值
- int RH=50; //濕度上限
- int RL=20; //濕度下限
- unsigned char KeyValue; //返回按鍵值
- int temp;
- float temperature; //溫度值
- char displaytemp[16];//定義顯示區域臨時存儲數組
- /*------------------------------------------------
- 判忙函數
- ------------------------------------------------*/
- bit LCD_Check_Busy(void)
- {
- unsigned char LCD_Status;
- RS = 0;
- RW = 1;
- EN = 1;
- DelayMs(1);
- LCD_Status = P0;
- EN = 0;
- return LCD_Status;
- }
- /*------------------------------------------------
- 寫入命令函數
- ------------------------------------------------*/
- void LCD_Write_Com(unsigned char com)
- {
- while((LCD_Check_Busy()&0x80)==0x80);
- RS = 0;
- RW = 0;
- EN = 0;
- P0 = com;
- EN = 1;
- DelayMs(1);
- EN = 0;
- }
- /*------------------------------------------------
- 寫入數據函數
- ------------------------------------------------*/
- void LCD_Write_Data(unsigned char Data)
- {
- while((LCD_Check_Busy()&0x80)==0x80);
- RS = 1;
- RW = 0;
- EN = 0;
- P0 = Data;
- EN = 1;
- DelayMs(1);
- EN = 0;
- }
- /*------------------------------------------------
- 清屏函數
- ------------------------------------------------*/
- void LCD_Clear(void)
- {
- LCD_Write_Com(0x01);
- DelayMs(5);
- }
- /*------------------------------------------------
- 寫入字符串函數
- ------------------------------------------------*/
- void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
- {
- if (y == 0)
- {
- LCD_Write_Com(0x80 + x); //表示第一行
- }
- else
- {
- LCD_Write_Com(0xC0 + x); //表示第二行
- }
- while (*s)
- {
- LCD_Write_Data( *s);
- s ++;
- }
- }
- /*------------------------------------------------
- 寫入字符函數
- ------------------------------------------------*/
- void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
- {
- if (y == 0)
- {
- LCD_Write_Com(0x80 + x);
- }
- else
- {
- LCD_Write_Com(0xC0 + x);
- }
- LCD_Write_Data( Data);
- }
- /*------------------------------------------------
- 初始化函數
- ------------------------------------------------*/
- void LCD_Init(void)
- {
- LCD_Write_Com(0x38); /*顯示模式設置*/
- DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- LCD_Write_Com(0x38);
- DelayMs(5);
- //LCD_Write_Com(0x08); /*顯示關閉*/
- LCD_Write_Com(0x01); /*顯示清屏*/
- DelayMs(5);
- LCD_Write_Com(0x06); /*顯示光標移動設置*/
- DelayMs(5);
- LCD_Write_Com(0x0C); /*顯示開及光標設置*/
- DelayMs(5);
- }
-
- unsigned char Get_AD_Result() //讀取AD值
- {
- uchar i,dat1=0,dat2=0;
- CS = 0;
- CLK = 0;
- DIO = 1; _nop_(); _nop_();
- CLK = 1; _nop_(); _nop_();
- CLK = 0;DIO = 1; _nop_(); _nop_();
- CLK = 1; _nop_(); _nop_();
- CLK = 0;DIO = 1; _nop_(); _nop_();
- CLK = 1;DIO = 1; _nop_(); _nop_();
- CLK = 0;DIO = 1; _nop_(); _nop_();
- for(i=0;i<8;i++)
- {
- CLK = 1; _nop_(); _nop_();
- CLK = 0; _nop_(); _nop_();
- dat1 = dat1 << 1 | DIO;
- }
- for(i=0;i<8;i++)
- {
- dat2 = dat2 << ((uchar)(DIO)<<i);
- CLK = 1; _nop_(); _nop_();
- CLK = 0; _nop_(); _nop_();
- }
- CS = 1;
- return dat1; //== dat2) ? dat1:0;
- }
- /*------------------------------------------------
- 主函數
- ------------------------------------------------*/
- void main(void)
- {
-
- LCD_Init();
- DelayMs(10);
- //Init_Timer0();
- MOETOR =0; //默認水泵關閉
- while (1)
- {
- KeyValue=KeyScan();
- if(KeyValue!=0)//如果有鍵按下
- {
- Keyprocessing(KeyValue); //鍵值處理
- }
-
- temp=ReadTemperature(); //讀取溫度值
- temperature=(float)temp*0.0625;
- sprintf(displaytemp,"T =%3.1f",temperature);//
- LCD_Write_String(0,0,displaytemp);// 顯示溫度值
- d = Get_AD_Result()*5/255; //計算電壓值
- k = 100/(FULL-ZERO); //根據空氣中和水中的電壓值列函數y=kx+b 計算 k b
- b = 0-ZERO*k;
- d = k*d+b; //計算實際的濕度值
- if(d<0) d=0;
- if(d>100) d=100;
- //d = k*d+b;
- sprintf(displaytemp,"R =%3.1f",d);//
- LCD_Write_String(8,0,displaytemp);// 顯示濕度
- sprintf(displaytemp,"RH=%2d",RH);//
- LCD_Write_String(0,1,displaytemp);// 顯示濕度上限
- sprintf(displaytemp,"RL=%2d",RL);//
- LCD_Write_String(10,1,displaytemp);// 顯示濕度下限
- if(d<RL) MOETOR =1; //低于下限 開水泵
- if(d>RH) MOETOR =0; //高于上限 關水泵
- DelayMs(300);
-
- }
- }
復制代碼
所有資料51hei提供下載:
程序.zip
(138.29 KB, 下載次數: 87)
2018-6-6 23:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|