找回密码
 注册

QQ登录

只需一步,快速开始

搜索

51单片机程序源码+ADC0832智能浇花系统Proteus仿真程序

[复制链接]
eng 发表于 2021-6-5 15:34:45 | 显示全部楼层 |阅读模式
功能描述:
(1)本系统采用单片机STC89C52+ADC0832+LCD1602液晶+土壤湿度传感器+抽水电机+ 按键+蜂鸣器设计而成。
(2)能够检测土壤的湿度,实时显示到LCD1602液晶屏上。其中,液晶第一行显示实际的湿度。液晶第二行显示湿度上限值和湿度下限值。
(3)根据不同的土壤,能够合理的调整浇水要求。通过按键设置上下限值。湿度低于下限报警,开始浇水直到上限停止报警及浇水。随后湿度下降到下限开始报警并启动浇水。
(4)按键分为,减键、加键、设置键。潜水泵通过继电器控制通断。
(5)可通过蓝牙模块对应的手机端读取实时湿度数据,并控制单片机端继电器和蜂鸣器功能的有无。

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

部分单片机c源码:完整源码请下载本文尾部附件
  1. #include <reg52.H>
  2. #include "intrins.h"
  3. #include "uart.h"
  4. #include "stdio.h"
  5. #include <stdio.h>

  6. #define uint unsigned int
  7. #define uchar unsigned char
  8. #define ulong unsigned long
  9. #define     LCDIO      P0         //液晶屏数据口
  10. //ADC0832的引脚
  11. sbit ADCLK =P3^6;  //ADC0832 clock signal
  12. sbit ADDIO =P3^7;  //ADC0832 k in
  13. sbit ADCS =P3^4;  //ADC0832 chip seclect

  14. sbit rs=P2^5;  //定义1602 RS
  15. sbit rw=P2^6;  //定义1602 Rw
  16. sbit lcden=P2^7; //定义1602 EN

  17. sbit key1=P1^7;    //设定
  18. sbit key2=P1^6;    //加
  19. sbit key3=P1^5;    //减
  20. sbit motor=P2^1;   //继电器接口
  21. sbit speak=P2^0;        //蜂鸣器接口
  22. uchar key;         //设定指针
  23. uint RH=500,RL=10;//水位上下限
  24. float temp_f;
  25. ulong temp;
  26. uchar v;
  27. uchar count,s1num;
  28. uchar code table[]= "shi du:          ";
  29. uchar code table1[]="RH:  %              ";
  30. uchar getdata; //获取ADC转换回来的值

  31. unsigned char init_flag=1;

  32. /*********************************************/
  33. void delay(uint z)                  //延时
  34. {
  35.         uint x,y;
  36.         for(x=z;x>0;x--)
  37.                 for(y=110;y>0;y--);
  38. }

  39. void long_alarm(void)                  //延时
  40. {
  41.     speak=0;                       
  42.     delay(800);               
  43.     speak=1;
  44.     delay(800);
  45. }

  46. void alarm(void)                  //延时
  47. {
  48.     speak=0;                       
  49.     delay(50);               
  50.     speak=1;
  51.     delay(50);
  52. }

  53. /**********************************************/
  54. void write_com(uchar com)
  55. {
  56.         rs=0;
  57. //        rd=0;
  58.         lcden=0;
  59.         P0=com;
  60.         delay(5);
  61.         lcden=1;
  62.         delay(5);
  63.         lcden=0;      
  64. }
  65. /*********************************************/
  66. void write_date(uchar date)
  67. {
  68.         rs=1;
  69. //        rd=0;
  70.         lcden=0;
  71.         P0=date;
  72.         delay(5);
  73.         lcden=1;
  74.         delay(5);
  75.         lcden=0;      
  76. }
  77. /***********************************************/
  78. void init()
  79. {
  80.         uchar num;

  81.         Uart_Init();

  82.         lcden=0;
  83.         rw=0;
  84.         write_com(0x38);
  85.         write_com(0x0c);
  86.         write_com(0x06);
  87.         write_com(0x01);
  88.         write_com(0x80);
  89.         for(num=0;num<15;num++)
  90.                 {
  91.                         write_date(table[num]);
  92.                         delay(5);
  93.                 }
  94.         write_com(0x80+0x40);
  95.         for(num=0;num<15;num++)
  96.                 {
  97.                         write_date(table1[num]);
  98.                         delay(5);
  99.                 }
  100.         }
  101. //****************************************************************************/
  102. /************
  103. 读ADC0832函数
  104. ************/
  105. //采集并返回
  106. /****************************************************************************
  107. 函数功能:AD转换子程序
  108. 入口参数:CH(如果读取CH0,channel的值为0x01,如果读取CH1则channel的值为0x03)
  109. 出口参数:adval
  110. ****************************************************************************/
  111. uchar Adc0832()     //AD转换,返回结果
  112. {
  113.     uchar i;
  114.     uchar dat=0;

  115.     ADCLK=0;
  116.     ADDIO=1;
  117.     ADCS=0;                  //拉低CS端
  118.     ADCLK=1;                 
  119.     ADCLK=0;                 //拉低CLK端,形成下降沿1

  120.     ADDIO=1;//指定转换通道是CH1还是CH2,指定值位与0x1,取最后一位的值
  121.     ADCLK=1;   
  122.     ADCLK=0;                 //拉低CLK端,形成下降沿2

  123.     ADDIO=0;//指定值右移一位,再取最后一位的值
  124.     ADCLK=1;
  125.     ADCLK=0;                //拉低CLK端,形成下降沿3


  126.     ADDIO=1;               
  127.         for(i=0;i<8;i++)
  128.     {
  129.         ADCLK=1;
  130.         ADCLK=0;           //形成一次时钟脉冲
  131.         if(ADDIO)
  132.                    dat|= 0x80>>i;  //收数据
  133.     }


  134.     ADCS=1;                //拉低CS端
  135.     ADCLK=1;
  136.     ADDIO=1;               //拉高数据端,回到初始状态
  137.     return(dat);           //return dat
  138. }
  139. /***************************************************************************/


  140. /********************************************************/
  141. void displayRH()                        //下限显示
  142. {write_com(0xc0+3);
  143. write_date(RH/100%10+0x30);//上限百位
  144. write_date(RH/10%10+0x30);//上限十位
  145. //write_date('.');
  146. //write_date(RH%10+0x30);
  147. }
  148. void displayRL()          //下限显示
  149. {write_com(0xca);
  150.   write_date('R');
  151.   write_date('L');
  152.   write_date(':');
  153. write_date(RL/100%10+0x30);//下限百位
  154. write_date(RL/10%10+0x30);//下限十位
  155. write_date('%');
  156. }
  157. /**************************************************/
  158. /********************************************************/
  159. void keyscan()                 //按键处理
  160. {
  161.         bit kk1=0,kk2=0;

  162.         if(key1==0)
  163.         {
  164.          delay(10);
  165.          while(key1==0);
  166.          alarm();      
  167.          key=1;

  168.            switch(key)
  169.            {
  170. //            speak=1;kk2=motor;motor=1;
  171.             case 1:        //RL下线报警值设置
  172.                     {
  173.                             write_com(0x0f);write_com(0xce); //光标闪烁
  174.                                 while(key1!=0)         //等待按键松开
  175.                                 {
  176.                                     if(key2==0)                //key2按键下
  177.                                    {   
  178.                                            delay(10);                //按键延时消抖
  179.                                            if(key2==0)                //确定key2按下
  180.                                            {
  181.                                                     while(key2==0); //等待松开
  182.                                             alarm();
  183.                                                         if(RL>=998)
  184.                                                         {RL=999;                //RL下限最大设置为99
  185.                                                         }
  186.                                                         else
  187.                                                         {RL+=10;                //RL加1
  188.                                                         }      
  189.                                            }
  190.                                            displayRL();                //调用RL下限显示函数
  191.                                            write_com(0xce);
  192.                                    }  
  193.                                     

  194.                                    if(key3==0)                //key3按下
  195.                                    {                                 
  196.                                                    delay(10);                //按键延时消抖
  197.                                                   if(key3==0)                //确定key3按下
  198.                                            {
  199.                                                     while(key3==0);         //等待key3按键松开
  200.                                             alarm();
  201.                                                         if(RL<=1)                 //RL最小设置为1
  202.                                                         {RL=0;
  203.                                                         }
  204.                                                         else
  205.                                                         {RL-=10;                 //RL下限减1
  206.                                                         }
  207.                                            }
  208.                                            displayRL();                //调用RL下限显示函数
  209.                                            write_com(0xce);
  210.                                   }                          
  211.                            }
  212.                                    while(key1==0);
  213.                     alarm();                       
  214.                         }


  215.                         case 2:        //RL上线报警值设置
  216.                         {
  217.                            write_com(0x0f);write_com(0xc4);  //RH设置数据,光标闪烁
  218.                            while(key1==1)
  219.                            {
  220.                                     if(key2==0)           //key2按下
  221.                                    {
  222.                                            delay(30);           //按键延时消抖
  223.                                            if(key2==0)           //确定key2按下
  224.                                            {
  225.                                                     while(key2==0);        //等待松开
  226.                                             alarm();
  227.                                                         if(RH>=998)                //RH最大设置为99
  228.                                                         {RH=999;
  229.                                                         }
  230.                                                         else
  231.                                                         {RH+=10;                //RH加1
  232.                                                         }                                       
  233.                                            }
  234.                                             displayRH();                //RH上限显示函数
  235.                                             write_com(0xc4);
  236.                                     }
  237.                                  
  238.                                  
  239.                                  
  240.                                    if(key3==0)          //key3按下
  241.                                    {
  242.                                            delay(30);          //按键延时消抖
  243.                                            if(key3==0)          //确定按下
  244.                                            {
  245.                                                     while(key3==0);//等待松开
  246.                                             alarm();
  247.                                                         if(RH<=1)           //RH最小设置为1
  248.                                                         {RH=0;
  249.                                                         }
  250.                                                         else
  251.                                                         {RH-=10;                //RH减1
  252.                                                         }                                               
  253.                                                 }
  254.                                                    displayRH();                //调用RH显示函数
  255.                                                    write_com(0xc4);
  256.                                   }                       
  257.                            }
  258.                            while(key1==0);
  259.                        alarm();
  260.                            }


  261.                         case 0:
  262.                         {
  263.                                         write_com(0x0c);
  264.                                     break;
  265.                         }


  266.          }
  267.    }
  268. }
  269. /**************************************************/
  270. void Conut(void)          //土壤检测数据转换
  271. {         
  272.       v=Adc0832();
  273.           temp=v;
  274. //      temp_f=temp*10/2.55;
  275.           temp_f=(temp-173.4)*12.25;
  276.       temp=temp_f;
  277.           temp=1000-temp;         
  278.           write_com(0x80+10);
  279.           write_date(temp/100%10+0x30);//千位
  280.           write_date(temp/10%10+0x30);//百位
  281.           write_date('.');
  282.           write_date(temp%10+0x30);
  283.           write_date('%');//显示符号位
  284.       
  285.          }
  286. /********************************************************/
  287. void main(void)
  288. {
  289.     char alarm_flag=0;
  290.         char alarm_forbidden_flag=0;
  291.         unsigned char shidu_string[20];

  292.         init();
  293.         displayRH();   //显示上限
  294.         displayRL();   //显示下限
  295.         delay(50);         //启动等待,等LCD讲入工作状态
  296.         delay(50);         //延时片刻(可不要)
  297.         delay(50);                         //延时
  298.         delay(50);
  299.         Conut();           //显示函数
  300.         delay(150);        
  301.       

  302.         while(1)
  303.         {        
  304. //                printf("%d",1);
  305.            Conut();        //显示当前湿度
  306.                  keyscan();
  307.                  

  308.                   sprintf(shidu_string, "shi du: %2d.%d \r\n",(int)(temp/10),(int)(temp%10));
  309.                   Send_Word(shidu_string); //通过蓝牙将数据上报出去,给你的手机蓝牙助手。


  310.                 if(init_flag!=0)
  311.                  {
  312. ……………………

  313. …………限于本文篇幅 余下代码请下载附件…………
复制代码
完整源码和仿真文件: 基于51单片机智能浇花系统.zip (299.55 KB, 售价: 5 E币)

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

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-4-25 05:59

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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