找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4225|回复: 7
收起左侧

单片机花园自动浇灌系统仿真与源码资料

[复制链接]
ID:304785 发表于 2018-6-6 23:39 | 显示全部楼层 |阅读模式
采用STC89C52作为主控芯片,ADC0804采集模拟信号作为花园土壤湿度,DS18B20采集温度,LCD1602显示温湿度;

当温度低于下限值,启动水泵进行浇水;
当温度高于上限值,停止水泵。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
hello.jpg 0.png


单片机源程序如下:
  1. #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  2. #include<intrins.h>
  3. #include<stdio.h>
  4. #include "18b20.h"
  5. #include "delay.h"
  6. #include "key.h"

  7. #define  uint   unsigned int          
  8. #define  uchar  unsigned char

  9. #define  ZERO   4.5                //湿度传感器放空气中的电压值   对应湿度0%
  10. #define  FULL   0.45                //湿度传感器放水中的电压值         对应湿度100%

  11. float k,b;//计算湿度用斜率

  12. sbit RS = P2^5;   //定义LCD1602端口
  13. sbit RW = P2^6;
  14. sbit EN = P2^7;
  15. #define DataPort P0

  16. sbit CS  = P2^0; //定义ADC0832端口
  17. sbit CLK = P2^1;
  18. sbit DIO = P2^2;

  19. sbit MOETOR = P3^6;//水泵控制端口

  20. #define RS_CLR RS=0
  21. #define RS_SET RS=1

  22. #define RW_CLR RW=0
  23. #define RW_SET RW=1

  24. #define EN_CLR EN=0
  25. #define EN_SET EN=1

  26. float  d;  //实时湿度值
  27. int RH=50; //湿度上限
  28. int RL=20; //湿度下限

  29. unsigned char KeyValue;        //返回按键值

  30. int temp;
  31. float temperature;         //温度值
  32. char displaytemp[16];//定义显示区域临时存储数组


  33. /*------------------------------------------------
  34.               判忙函数
  35. ------------------------------------------------*/
  36. bit LCD_Check_Busy(void)
  37. {
  38.     unsigned char LCD_Status;
  39.         RS = 0;
  40.         RW = 1;
  41.         EN = 1;
  42.         DelayMs(1);
  43.            LCD_Status = P0;
  44.         EN = 0;
  45.         return LCD_Status;
  46. }
  47. /*------------------------------------------------
  48.               写入命令函数
  49. ------------------------------------------------*/
  50. void LCD_Write_Com(unsigned char com)
  51. {  
  52.     while((LCD_Check_Busy()&0x80)==0x80);
  53.         RS = 0;
  54.         RW = 0;
  55.         EN = 0;
  56.         P0 = com;
  57.         EN = 1;
  58.         DelayMs(1);
  59.         EN = 0;
  60. }
  61. /*------------------------------------------------
  62.               写入数据函数
  63. ------------------------------------------------*/
  64. void LCD_Write_Data(unsigned char Data)
  65. {
  66. while((LCD_Check_Busy()&0x80)==0x80);
  67.         RS = 1;
  68.         RW = 0;
  69.         EN = 0;
  70.         P0 = Data;
  71.         EN = 1;
  72.         DelayMs(1);
  73.         EN = 0;
  74. }

  75. /*------------------------------------------------
  76.                 清屏函数
  77. ------------------------------------------------*/
  78. void LCD_Clear(void)
  79. {
  80. LCD_Write_Com(0x01);
  81. DelayMs(5);
  82. }
  83. /*------------------------------------------------
  84.               写入字符串函数
  85. ------------------------------------------------*/
  86. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  87. {     
  88. if (y == 0)
  89.         {     
  90.          LCD_Write_Com(0x80 + x);     //表示第一行
  91.         }
  92. else
  93.         {      
  94.         LCD_Write_Com(0xC0 + x);      //表示第二行
  95.         }        
  96. while (*s)
  97.         {     
  98. LCD_Write_Data( *s);     
  99. s ++;     
  100.         }
  101. }
  102. /*------------------------------------------------
  103.               写入字符函数
  104. ------------------------------------------------*/
  105. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  106. {     
  107. if (y == 0)
  108.         {     
  109.         LCD_Write_Com(0x80 + x);     
  110.         }   
  111. else
  112.         {     
  113.         LCD_Write_Com(0xC0 + x);     
  114.         }        
  115. LCD_Write_Data( Data);  
  116. }
  117. /*------------------------------------------------
  118.               初始化函数
  119. ------------------------------------------------*/
  120. void LCD_Init(void)
  121. {
  122.    LCD_Write_Com(0x38);    /*显示模式设置*/
  123.    DelayMs(5);
  124.    LCD_Write_Com(0x38);
  125.    DelayMs(5);
  126.    LCD_Write_Com(0x38);
  127.    DelayMs(5);
  128.    LCD_Write_Com(0x38);
  129.    DelayMs(5);
  130.    //LCD_Write_Com(0x08);    /*显示关闭*/
  131.    LCD_Write_Com(0x01);    /*显示清屏*/
  132.    DelayMs(5);
  133.    LCD_Write_Com(0x06);    /*显示光标移动设置*/
  134.    DelayMs(5);
  135.    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  136.    DelayMs(5);
  137.    }



  138. unsigned char Get_AD_Result()        //读取AD值
  139. {
  140. uchar i,dat1=0,dat2=0;
  141.         CS  = 0;
  142.         CLK = 0;
  143.         DIO = 1; _nop_(); _nop_();
  144.         CLK = 1; _nop_(); _nop_();
  145.         CLK = 0;DIO = 1; _nop_(); _nop_();
  146.         CLK = 1; _nop_(); _nop_();
  147.         CLK = 0;DIO = 1; _nop_(); _nop_();
  148.         CLK = 1;DIO = 1; _nop_(); _nop_();
  149.         CLK = 0;DIO = 1; _nop_(); _nop_();
  150.         for(i=0;i<8;i++)
  151.         {
  152.                  CLK = 1; _nop_(); _nop_();
  153.                 CLK = 0; _nop_(); _nop_();
  154.                 dat1 = dat1 << 1 | DIO;       
  155.         }
  156.         for(i=0;i<8;i++)
  157.         {
  158.                  dat2 = dat2 << ((uchar)(DIO)<<i);
  159.                 CLK = 1; _nop_(); _nop_();
  160.                 CLK = 0; _nop_(); _nop_();
  161.         }
  162.         CS = 1;
  163.         return dat1; //== dat2) ? dat1:0;
  164. }

  165. /*------------------------------------------------
  166.                     主函数
  167. ------------------------------------------------*/
  168. void main(void)
  169. {

  170.        
  171.     LCD_Init();
  172.         DelayMs(10);
  173. //Init_Timer0();
  174.         MOETOR =0;        //默认水泵关闭

  175. while (1)
  176. {  
  177.       KeyValue=KeyScan();
  178.           if(KeyValue!=0)//如果有键按下
  179.           {       
  180.         Keyprocessing(KeyValue); //键值处理
  181.           }

  182.     temp=ReadTemperature();  //读取温度值
  183.     temperature=(float)temp*0.0625;
  184.     sprintf(displaytemp,"T =%3.1f",temperature);//
  185.     LCD_Write_String(0,0,displaytemp);// 显示温度值

  186.     d = Get_AD_Result()*5/255; //计算电压值
  187.         k = 100/(FULL-ZERO);           //根据空气中和水中的电压值列函数y=kx+b 计算 k b
  188.         b = 0-ZERO*k;
  189.         d = k*d+b;          //计算实际的湿度值
  190.         if(d<0)        d=0;
  191.         if(d>100) d=100;
  192.         //d = k*d+b;
  193.     sprintf(displaytemp,"R =%3.1f",d);//
  194.     LCD_Write_String(8,0,displaytemp);// 显示湿度


  195.     sprintf(displaytemp,"RH=%2d",RH);//
  196.     LCD_Write_String(0,1,displaytemp);// 显示湿度上限
  197.     sprintf(displaytemp,"RL=%2d",RL);//
  198.     LCD_Write_String(10,1,displaytemp);//        显示湿度下限

  199.         if(d<RL) MOETOR =1;          //低于下限 开水泵
  200.         if(d>RH) MOETOR =0;          //高于上限 关水泵

  201.     DelayMs(300);

  202. }
  203. }


复制代码

所有资料51hei提供下载:
程序.zip (138.29 KB, 下载次数: 87)
回复

使用道具 举报

ID:357735 发表于 2018-6-29 09:33 来自手机 | 显示全部楼层
警告,有三个改都改不掉
回复

使用道具 举报

ID:232619 发表于 2018-11-30 13:33 | 显示全部楼层
谢谢分享谢谢分享谢谢分享
回复

使用道具 举报

ID:442640 发表于 2018-12-9 14:27 | 显示全部楼层
请问RS接的是什么元件
回复

使用道具 举报

ID:304785 发表于 2019-4-27 11:07 | 显示全部楼层
keil123 发表于 2018-12-9 14:27
请问RS接的是什么元件

RS接的是液晶的控制引脚
回复

使用道具 举报

ID:304785 发表于 2019-4-27 11:08 | 显示全部楼层
天空飞鱼 发表于 2018-6-29 09:33
警告,有三个改都改不掉

为什么要消除警告呢,直接可以跑得。如果需要改掉可以联系我。
回复

使用道具 举报

ID:752801 发表于 2020-5-15 18:40 来自手机 | 显示全部楼层
可以教我一下嘛?
回复

使用道具 举报

ID:752801 发表于 2020-5-15 18:43 来自手机 | 显示全部楼层
可以教我一下嘛?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表