找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4783|回复: 4
收起左侧

单片机花卉自动浇水电路原理图与源程序

  [复制链接]
ID:63146 发表于 2018-5-27 08:53 | 显示全部楼层 |阅读模式
花卉自动浇水系统仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
QQ截图20180527085033.jpg

0.png

我的毕业设计,自动浇水系统的仿真程序,是基于单片机的

单片机源码如下:
  1. #include <reg52.h>
  2. #include <intrins.h>




  3. #define uchar unsigned char
  4. #define uint  unsigned int


  5. sbit         Key_Min=P3^5;
  6. sbit         Key_Add=P3^6;
  7. sbit         Key_Set=P3^7;
  8. sbit         Key_Mode=P1^0;


  9. sbit         Key_Low=P1^2;
  10. sbit         Key_High=P1^3;


  11. sbit led1=P3^2;        //绿灯,浇水状态,与继电器同步
  12. sbit led2=P3^3;        //黄灯,水位上限
  13. sbit led3=P3^4;        //红灯,水位下限
  14. //------------继电器引脚-------------------
  15. sbit          JD=P2^1;
  16. sbit sw=P1^6;
  17. sbit BEEP=P2^0;
  18. uchar HumTab=0;                        //温度浇水时上下限切换的标志,记录是上一个状态,0是缺少,1是盛水。
  19. sbit rs=P2^5;    //命令/数据选择
  20. sbit rw=P2^6;    //读写口
  21. sbit  e=P2^7;    //锁存控制


  22. sbit DQ = P1^5;
  23. bit DS18B20_IS_OK = 1; //DS18B20 正常标志
  24. uchar Temp_Value[]={0x00,0x00}; //读到的温度值
  25. #define  NOP()   _nop_()   /* 定义空指令 */
  26. #define  _Nop()  _nop_()   /*定义空指令*/




  27. uchar ThresholdL=20;        //湿度阀值下限,低于这个值就开始浇水;
  28. uchar ThresholdH=50;        //湿度阀值上限,浇水超过这个值就停止浇水
  29. uchar code df_Table[]={ 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9 };
  30. uchar Display_Digit[]={0,0,0,0};
  31. uchar CurrentT = 0;
  32. float time=0.0;
  33. long distance=0.0;
  34. int  num=0,num1=0;






  35. //**************************************************************************************************
  36. //延时函数
  37. //**************************************************************************************************
  38. void delay(uint time)         //int型数据为16位,所以最大值为65535            
  39. {
  40.   uint  i,j;             //定义变量i,j,用于循环语句
  41.   for(i=0;i<time;i++)    //for循环,循环50*time次
  42.      for(j=0;j<100;j++); //for循环,循环50次
  43. }
  44. void Delay1(uint x) //延时 2
  45. {
  46.         while(x--);
  47. }
  48. //**************************************************************************************************
  49. //向LCD写一命令
  50. //**************************************************************************************************
  51. void wcode(uchar t)
  52. {
  53.   rs=0;           // 写的是命令
  54.   rw=0;           // 写状态
  55.   e=1;            //使能
  56.   P0=t;           //写入命令
  57.   delay(20);      //等待写入,如果时间太短,会导致液晶无法显示
  58.   e=0;            //数据的锁定
  59. }


  60. //**************************************************************************************************
  61. //向LCD写一数据
  62. //**************************************************************************************************
  63. void wdata(uchar t)
  64. {
  65.   rs=1;          // 写的是数据
  66.   rw=0;          // 写状态
  67.   e=1;           //使能
  68.   P0=t;          //写入数据
  69.   delay(20);     //等待写入,如果时间太短,会导致液晶无法显示
  70.   e=0;           //数据的锁定
  71. }
  72. //**************************************************************************************************
  73. //LCD显示第一行
  74. //**************************************************************************************************
  75. void xian1(uchar *dis)
  76. {
  77.   uchar i;
  78.   wcode(0x80);          //设置第一行显示地址
  79.   for(i=0;i<16;i++)     //循环16次,写完1行
  80.     {
  81.       wdata(dis[ i]);   //写入该行数据[ i]
  82.     }
  83. }
  84. //**************************************************************************************************
  85. //LCD显示第二行
  86. //**************************************************************************************************
  87. void xian2(uchar *str)
  88. {
  89.    uchar i;
  90.    wcode(0xc0);        //设置第二行显示地址
  91.    for(i=0;i<16;i++)   //循环16次,写完1行
  92.     {
  93.       wdata(str[ i]);  //写入该行数据[ i]
  94.     }
  95. }
  96. //**************************************************************************************************
  97. //LCD 初始化
  98. //**************************************************************************************************
  99. void InitLCD()
  100.    {                  
  101.    wcode(0x01);          //清屏
  102.    wcode(0x06);   //输入方式控制,增量光标不移位
  103.    wcode(0x0c);   //显示开关控制
  104.    wcode(0x38);   //功能设定:设置16x2显示,5x7显示,8位数据接口            
  105.    }  
  106. /*********************************************************/
  107. // 液晶光标定位函数
  108. /*********************************************************/
  109. void LcdGotoXY(uchar line,uchar column)
  110. {
  111.     if(line==1)        // 第一行
  112.         wcode(0x80+column-1);
  113.     if(line==2)        // 第二行
  114.         wcode(0xC0+column-1);
  115. }
  116. /*********************************************************/
  117. // 液晶输出数字
  118. /*********************************************************/
  119. void LcdPrintNum(uchar num)
  120. {


  121.         wdata(num/10%10+0x30);                    
  122.         wdata(num%10+0x30);        


  123. }


  124. void delay100us(void)   //误差 0us
  125. {
  126.     unsigned char a,b;
  127.     for(b=19;b>0;b--)
  128.         for(a=1;a>0;a--);
  129. }




  130. uchar Init_DS18B20() //初始化(或者说复位) DS18B20
  131. {
  132.         uchar status;
  133.         DQ = 1;
  134.         Delay1(8);
  135.         DQ = 0;
  136.         Delay1(90);
  137.         DQ = 1;
  138.         Delay1(8);
  139.         status=DQ;Delay1(100);
  140.         DQ = 1;
  141.         return status;
  142. }
  143. uchar ReadOneByte() //从 DS18B20 读一字节数据
  144. {
  145.         uchar i,dat=0;
  146.         DQ = 1;
  147.         _nop_();
  148.         for(i=0;i<8;i++)
  149.         {
  150.                 DQ = 0;
  151.                 dat >>= 1;
  152.                 DQ = 1;
  153.                 _nop_();
  154.                 _nop_();
  155.                 if(DQ)
  156.                 dat |= 0X80;
  157.                 Delay1(30);
  158.                 DQ = 1;
  159.         }
  160.         return dat;
  161. }
  162. void WriteOneByte(uchar dat) //从 DS18B20 写一字节数据
  163. {
  164.         uchar i;
  165.         for(i=0;i<8;i++)
  166.         {
  167.                 DQ = 0;
  168.                 DQ = dat& 0x01;
  169.                 Delay1(5);
  170.                 DQ = 1;
  171.                 dat >>= 1;
  172.         }
  173. }
  174. void Read_Temperature() //从 DS18B20 读取温度值
  175. {
  176.         if(Init_DS18B20()==1) //DS18B20 故障
  177.                 DS18B20_IS_OK=0;
  178.         else
  179.         {        
  180.                 WriteOneByte(0xcc); //跳过序列号命令
  181.                 WriteOneByte(0x44); //启动温度转换命令
  182.                 Init_DS18B20(); //复位 DS18B20 ( 每一次读写之前都要对 DS18B20 进行复位操作)
  183.                 WriteOneByte(0xcc); //跳过序列号命令
  184.                 WriteOneByte(0xbe); //读取温度寄存器
  185.                 Temp_Value[0] = ReadOneByte(); //读取温度低 8 位(先读低字节,再读高字节,)
  186.                 Temp_Value[1] = ReadOneByte();//读取温度高 8 位 (每次只能读一个字节)
  187.                 DS18B20_IS_OK=1; //DS18B20 正常
  188.         }
  189. }
  190. void Display_Temperature() //在 1602LCD 上显示当前温度
  191. {
  192.         
  193.         uchar t = 150, ng = 0; //延时值与负数标志
  194.         if((Temp_Value[1]&0xf8)==0xf8) //高字节高 5 位如果全为 1,则为负数,为负数时取反
  195.         { //加 1,并设置负数标志为 1
  196.                 Temp_Value[1] = ~Temp_Value[1];
  197.                 Temp_Value[0] = ~Temp_Value[0]+1;
  198.                 if(Temp_Value[0]==0x00) //若低字节进位,则高字节加 1
  199.                         Temp_Value[1]++;
  200.                         ng = 1; //设置负数标志为 1
  201.         }
  202.         Display_Digit[0] = df_Table[Temp_Value[0]&0x0f]; //查表得到温度小数部分
  203.         //获取温度整数部分(低字节低 4 位清零,高 4 位右移 4 位) +(高字节高 5 位清零,
  204.         //低三位左移 4 位)
  205.         CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4);
  206.         //将温度整数部分分解为 3 位待显示数字
  207.         Display_Digit[3] = CurrentT/100;
  208.         Display_Digit[2] = CurrentT%100/10;
  209.         Display_Digit[1] = CurrentT%10;
  210.         //刷新 LCD 缓冲 //加字符 0 是为了将待数字转化为字符显示
  211.         LcdGotoXY(2,3);
  212.         wdata(Display_Digit[2]+'0');
  213.         wdata(Display_Digit[1]+'0');
  214.         wdata('.');
  215.         wdata(Display_Digit[0]+'0');
  216. }
  217. void delay10ms(void)   //误差 -0.000000000001us
  218. {
  219.     unsigned char a,b,c;
  220.     for(c=7;c>0;c--)
  221.         for(b=168;b>0;b--)
  222.             for(a=22;a>0;a--);
  223. }
  224. void WateringIntelligence()        //智能控制模式
  225. {
  226.         //--------------设置湿度上下限函数----
  227.     {
  228.                    JD=1;
  229.                 wcode(0x0f);                                   // 显示光标,并闪烁
  230.                 //delay10ms();
  231.                 while(Key_Set==0);                                // 等待按键释放
  232.                 //delay10ms();
  233.                 wcode(0x01);                            // 清屏
  234.                 xian1("Humidity   Set  ");                                 // 显示 "Humidity Set" (第一行)
  235.                 xian2("      -   %RH   ");                                        // 显示“  -   %RH  ” (第二行)
  236.                 LcdGotoXY(2,5);
  237.                 LcdPrintNum(HumiLowTemp);
  238.                 LcdGotoXY(2,8);
  239.                 LcdPrintNum(HumiHigTemp);
  240.                 LcdGotoXY(2,6);
  241.                 /*****湿度下限值设置******************************************
  242.                 ------------------------------------------------------------*/
  243.                 while(Key_Set!=0)
  244.                 {
  245.                         if(Key_Min==0)                                                // 湿度下限值 减
  246.                         {
  247.                                 HumiLowTemp--;
  248.                                 if(HumiLowTemp<0)
  249.                                         HumiLowTemp=0;
  250.                                 LcdGotoXY(2,5);                                        // 显示湿度下限值
  251.                                 LcdPrintNum(HumiLowTemp);               
  252.                                 LcdGotoXY(2,6);
  253.                                 delay(500);                                       
  254.                         }
  255.                         if(Key_Add==0)                                                // 湿度下限值 加
  256.                         {
  257.                                   HumiLowTemp++;
  258.                                 if(HumiLowTemp==100)
  259.                                         HumiLowTemp=99;
  260.                                 LcdGotoXY(2,5);                                          // 显示湿度下限值
  261.                                 LcdPrintNum(HumiLowTemp);               
  262.                                 LcdGotoXY(2,6);
  263.                                 delay(500);        
  264.                         }
  265.                 }
  266.                 //delay10ms();
  267.                 while(Key_Set==0);                                                // 等待按键释放
  268.                 //delay10ms();
  269.                 LcdGotoXY(2,9);        
  270.                 while(Key_Set!=0)                                                // 如果按键1按下,那么跳到下一级设置,否则是湿度上限值的大小设置
  271.                 {
  272.                         if(Key_Min==0)                                                // 湿度上限值 减
  273.                         {
  274.                                 HumiHigTemp--;
  275.                                 if(HumiHigTemp<0)
  276.                                         HumiHigTemp=0;
  277.                                 LcdGotoXY(2,8);                                        // 显示湿度上限值
  278.                                 LcdPrintNum(HumiHigTemp);
  279.                                 LcdGotoXY(2,9);
  280.                                 delay(500);               
  281.                         }
  282.                         if(Key_Add==0)                                                // 湿度上限值 加
  283.                         {
  284.                                 HumiHigTemp++;
  285.                                 if(HumiHigTemp==100)
  286.                                         HumiHigTemp=99;
  287.                                 LcdGotoXY(2,8);                                        // 显示度上限值
  288.                                 LcdPrintNum(HumiHigTemp);
  289.                                 LcdGotoXY(2,9);
  290.                                 delay(500);                        
  291.                         }                                                        
  292.                 }
  293.                 //delay10ms();
  294.                 while(Key_Set==0);                                                // 等待按键释放
  295.                 //delay10ms();
  296.                 wcode(0x0c);
  297.                
  298.                 ThresholdL=HumiLowTemp;                // 更新湿度下限报警值
  299.                 ThresholdH=HumiHigTemp;                // 更新湿度上限报警               
  300.                
  301.                 InitLCD();           //初始化1602  
  302.                    xian1("Watering System ");           //显示第一行           
  303.                    xian2("T:   C H:  %RH  ");       //显示第二行                  
  304.                 LcdGotoXY(2,5);
  305.                 wdata(0xdf);                        
  306.                
  307.         }        


  308.         if(sw==0)                   //当前温度低于阈值下限,浇水        
  309.         {        
  310.                 JD=0;        
  311.                 led1=0;        
  312.                 HumTab=0;
  313.                 LcdGotoXY(2,10);
  314.                 LcdPrintNum(19);
  315.                                 
  316.         }               
  317.         else        //当前温度高于阈值上限,停止浇水        
  318.         {        
  319.                 JD=1;        
  320.                 led1=1;        
  321.                 HumTab=1;
  322.                 LcdGotoXY(2,10);
  323.                 LcdPrintNum(53);        
  324.         }                        


  325. }               


  326. //水位检测函数
  327. void CheckWaterLevel()
  328. {
  329.         if(Key_Low==1&&Key_High==1)//高低水位都没水
  330.         {
  331.                    led3=0;                         //下水位,快没水了
  332.                 led2=1;
  333.                 BEEP=0;                        //蜂鸣器报警
  334.         }


  335.         else if(Key_Low==0&&Key_High==0)//低水位有水,高水位有水,水满了
  336.         {
  337.                 led3=1;
  338.                 led2=0;
  339.                 BEEP=0;
  340.         }        
  341.           else
  342.           {
  343.         led3=1;
  344.                 led2=1;
  345.                 BEEP=1;


  346.           }
  347. }               
  348. void main()
  349. {


  350.         InitLCD();           //初始化1602  


  351.         xian1("Watering System ");
  352.         xian2("T:   C H:  %RH  ");       //显示第二行
  353.         LcdGotoXY(2,5);
  354.         wdata(0xdf);               
  355.            while(1)           //进入死循环,防止看门狗复位
  356.         {
  357.                 //key1deal();
  358.                 Read_Temperature();
  359.                 Display_Temperature();
  360.                 CheckWaterLevel();
  361.                 WateringIntelligence();
  362.                 delay(1000);
  363.         }


  364. }
复制代码


全部资料51hei下载地址:
花卉自动浇水.rar (76.03 KB, 下载次数: 156)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:345158 发表于 2018-6-13 00:33 | 显示全部楼层
hi,你这个毕业设计有电路原理图吗?
回复

使用道具 举报

ID:498721 发表于 2019-3-26 21:07 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:532592 发表于 2019-5-10 16:12 来自手机 | 显示全部楼层
楼主,我想问一下那个蓝色字体是什么,看不清楚
回复

使用道具 举报

ID:659078 发表于 2019-12-10 12:34 | 显示全部楼层
谢谢大佬
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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