久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3073|回復: 1
收起左側

單片機澆花系統Proteus仿真程序

[復制鏈接]
ID:762393 發表于 2021-5-6 11:25 | 顯示全部樓層 |閱讀模式
本設計是基于AT89C51單片機和ADC0832的自動澆花系統。本設計的電路內部包含濕度采集和AD轉換等主要功能。自動澆水系統設計的澆水部分是通過單片機程序設計澆水的上下限值與感應電路送入單片機的土壤濕度值相比較,當低于下限值時,單片機輸出一個信號控制澆水,高于上限值時再由單片機輸出一個信號控制停止澆水。這樣可以幫助人們及時地給心愛的盆花澆水

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png

單片機源程序如下:
  1. //程序頭函數
  2. #include <reg52.h>
  3. #include <intrins.h>        //包含頭文件
  4. //顯示函數
  5. #include <display.h>
  6. #include "eeprom52.h"

  7. //宏定義
  8. #define uint unsigned int
  9. #define uchar unsigned char

  10. //管腳聲明
  11. sbit LED_R= P2^2;                          //紅色指示燈
  12. sbit LED_G= P2^0;                          //綠色指示燈
  13. sbit FENG = P2^5;                          //蜂鳴器
  14. sbit CS   = P1^4;
  15. sbit Clk = P1^2;
  16. sbit DATI = P1^3;
  17. sbit DATO = P1^3;                        //ADC0832引腳

  18. sbit san=P3^4;                                  //繼電器
  19. //按鍵
  20. sbit Key1=P2^6;
  21. sbit Key2=P2^7;
  22. sbit Key3=P3^7;
  23. /*******************************定義全局變量********************************/
  24. unsigned char dat = 0;      //AD值
  25. unsigned char CH=0;       //通道變量
  26. unsigned int sum=0;                         //平均值計算時的總數
  27. unsigned char m=0;
  28. bit bdata flag;                                  //定義位變量
  29. uchar set;                                          //設置變量
  30. uchar full_range=153;                  //滿量程AD數值
  31. //函數聲明
  32. extern void Key();

  33. //濕度值變量
  34. uint temp=0;

  35. char MH=80,ML=20;                //上下限變量

  36. /******************把數據保存到單片機內部eeprom中******************/
  37. void write_eeprom()
  38. {
  39.         SectorErase(0x2000);
  40.         byte_write(0x2000, MH);
  41.         byte_write(0x2001, ML);
  42.         byte_write(0x2060, a_a);        
  43. }

  44. /******************把數據從單片機內部eeprom中讀出來*****************/
  45. void read_eeprom()
  46. {
  47.         MH   = byte_read(0x2000);
  48.         ML   = byte_read(0x2001);
  49.         a_a      = byte_read(0x2060);
  50. }

  51. /**************開機自檢eeprom初始化*****************/
  52. void init_eeprom()
  53. {
  54.         read_eeprom();                //先讀
  55.         if(a_a != 1)                //新的單片機初始單片機內問eeprom
  56.         {
  57.                 MH  = 80;
  58.                 ML  = 20;
  59.                 a_a = 1;
  60.                 write_eeprom();           //保存數據
  61.         }        
  62. }

  63. /****************************************************************************
  64. 函數功能:AD轉換子程序
  65. 入口參數:CH
  66. 出口參數:dat
  67. ****************************************************************************/
  68. unsigned char adc0832(unsigned char CH)
  69. {
  70.         unsigned char i,test,adval;
  71.         adval = 0x00;
  72.         test = 0x00;
  73.         Clk = 0;       //初始化
  74.         DATI = 1;
  75.         _nop_();
  76.         CS = 0;
  77.         _nop_();
  78.         Clk = 1;
  79.         _nop_();
  80.         
  81.         
  82.         if ( CH == 0x00 )      //通道選擇
  83.         {
  84.                 Clk = 0;
  85.                 DATI = 1;      //通道0的第一位
  86.                 _nop_();
  87.                 Clk = 1;
  88.                 _nop_();
  89.                 Clk = 0;
  90.                 DATI = 0;      //通道0的第二位
  91.                 _nop_();
  92.                 Clk = 1;
  93.                 _nop_();
  94.         }
  95.         else
  96.         {
  97.                 Clk = 0;
  98.                 DATI = 1;      //通道1的第一位
  99.                 _nop_();
  100.                 Clk = 1;
  101.                 _nop_();
  102.                 Clk = 0;
  103.                 DATI = 1;      //通道1的第二位
  104.                 _nop_();
  105.                 Clk = 1;
  106.                 _nop_();
  107.         }
  108.         
  109.         Clk = 0;
  110.         DATI = 1;
  111.         for( i = 0;i < 8;i++ )      //讀取前8位的值
  112.         {
  113.                 _nop_();
  114.                 adval <<= 1;
  115.                 Clk = 1;
  116.                 _nop_();
  117.                 Clk = 0;
  118.                 if (DATO)
  119.                 adval |= 0x01;
  120.                 else
  121.                 adval |= 0x00;
  122.         }
  123.         for (i = 0; i < 8; i++)      //讀取后8位的值
  124.         {
  125.                 test >>= 1;
  126.                 if (DATO)
  127.                 test |= 0x80;
  128.                 else
  129.                 test |= 0x00;
  130.                 _nop_();
  131.                 Clk = 1;
  132.                 _nop_();
  133.                 Clk = 0;
  134.         }
  135.         if (adval == test)      //比較前8位與后8位的值,如果不相同舍去。若一直出現顯示為零,請將該行去掉
  136.         dat = test;
  137.         nop_();
  138.         CS = 1;        //釋放ADC0832
  139.         DATO = 1;
  140.         Clk = 1;
  141.         return dat;
  142. }

  143. void init()                                //定時器初始化函數
  144. {
  145.         TMOD=0x01;                        //定時器工作方式
  146.          TL0=0xb0;
  147.          TH0=0x3c;                        //賦初值50ms
  148.          EA=1;                                //打開中斷總開關
  149.         ET0=1;                                //打開定時器0中斷允許開關
  150.          TR0=1;                                //打開定時器0定時開關
  151. }

  152. void main()                                //主函數
  153. {
  154.         Init1602();                                                 //初始化液晶函數
  155.         init();                                                         //初始化定時器
  156.         init_eeprom();  //開始初始化保存的數據
  157.         while(1)                                                 //進入循環
  158.         {
  159.                 for(m=0;m<50;m++)                        //讀50次AD值
  160.                 sum = adc0832(0)+sum;                //讀到的AD值,將讀到的數據累加到sum
  161.                 temp=sum/50;                                //跳出上面的for循環后,將累加的總數除以50得到平均值temp
  162.                 sum=0;                                                 //平均值計算完成后,將總數清零
  163.                 if(temp<=full_range)                //讀取的AD數值小于滿量程數值
  164.                 temp=(temp*100)/full_range;        //除以滿量程數值,得到百分比
  165.                 else                                                //如果大于
  166.                 temp=100;                                        //直接賦值100%
  167.                 if(set==0)                                         //set為0,說明現在不是設置狀態
  168.                 Display_1602(temp,MH,ML);         //顯示AD數值和報警值
  169.                 if(temp<ML&&set==0)         //AD數值小于報警值
  170.                 {
  171.                         flag=1;                                         //打開報警
  172.                         san=0;                                         //打開繼電器
  173.                         LED_G=1;                                          //綠燈熄滅
  174.                         LED_R=0;                                          //紅燈點亮
  175.                 }
  176.                 else if(temp>MH&&set==0)//AD值大于報警值
  177.                 {
  178.                         flag=0;                                         //關閉報警
  179.                         san=1;                                         //關閉繼電器
  180.                         LED_G=0;                                          //綠燈點亮
  181.                         LED_R=1;                                          //紅燈熄滅
  182.                 }
  183.                 else
  184.                 {
  185.                         flag=0;                                                  //關閉報警
  186.                         LED_G=0;                                          //綠燈點亮
  187.                         LED_R=1;                                          //紅燈熄滅
  188.                 }
  189.                 Key();                                                 //調用按鍵函數
  190.         }
  191. }

  192. void Key()                                          //按鍵函數
  193. {
  194.         if(Key1==0)                                  //設置鍵按下
  195.         {
  196.                 while(Key1==0);                  //按鍵松開
  197.                 FENG=0;                                  //蜂鳴器響
  198.                 set++;                                  //設置變量加
  199.                 flag=0;                                  //關閉報警
  200.                 TR0=0;                                  //關閉定時器
  201.         }
  202.         if(set==1)                                  //設置報警值時
  203.         {
  204.                 write_com(0x80+0x40+4);//位置
  205.                    write_com(0x0f);//打開顯示 無光標 光標閃爍
  206.                 FENG=1;                                //關閉蜂鳴器
  207.         }
  208.         if(set==2)                                  //設置報警值時
  209.         {
  210.                 write_com(0x80+0x40+14);//位置
  211.                    write_com(0x0f);//打開顯示 無光標 光標閃爍
  212.                 FENG=1;                                //關閉蜂鳴器
  213.         }
  214.         else if(set>=3)                //設置完成時
  215.         {
  216.                 set=0;                        //變量清零
  217.                 write_com(0x38);//屏幕初始化
  218.                 write_com(0x0c);//打開顯示 無光標 無光標閃爍
  219.                 FENG=1;                        //關閉蜂鳴器
  220.                 flag=1;                        //打開報警
  221.                 TR0=1;                        //打開定時器
  222.         }
  223.         if(Key2==0&&set!=0)                        //設置報警值時加鍵按下
  224.         {
  225.                 while(Key2==0);                        //按鍵松開
  226.                 FENG=0;                                        //打開蜂鳴器
  227.                 if(set==1)
  228.                 {
  229.                         MH++;                                //報警值加
  230.                         if(MH>99)                //最大加到99
  231.                         MH=ML+1;                                //上限=下限+1
  232.                         write_com(0x80+0x40+3);           //選中液晶屏上的第二行第3列
  233.                         write_data('0'+MH/10);
  234.                         write_data('0'+MH%10);         //顯示上限數值
  235.                         write_com(0x80+0x40+4);//閃爍位置
  236.                         FENG=1;                                                //關閉蜂鳴器
  237.                 }
  238.                 if(set==2)
  239.                 {
  240.                         ML++;                                //報警值加
  241.                         if(ML>=MH&&MH<99)                //下限值大于上限并且上限小于99時
  242.                         MH=ML+1;                                //上限=下限+1
  243.                         if(ML>98)                                //下限加到大于98
  244.                         ML=0;                                        //下限清零
  245.                         write_com(0x80+0x40+3);           //選中液晶屏上的第二行第3列
  246.                         write_data('0'+MH/10);
  247.                         write_data('0'+MH%10);
  248.                         write_com(0x80+0x40+13);           //選中液晶屏上的第二行第13列
  249.                         write_data('0'+ML/10);
  250.                         write_data('0'+ML%10);
  251.                         write_com(0x80+0x40+14);//閃爍位置
  252.                         FENG=1;                                                //關閉蜂鳴器
  253.                 }
  254.                 write_eeprom();                           //保存數據
  255.         }
  256.         if(Key3==0&&set!=0)                                //注釋同加按鍵
  257.         {
  258.                 while(Key3==0);
  259.                 FENG=0;
  260.                 if(set==1)
  261.                 {
  262.                         MH--;                                //上限值減
  263.                         if(MH<=ML&&ML>0)                //上限小于下限且下限大于0時
  264.                         ML=MH-1;                                //下限=上限-1
  265.                         if(MH<1)                                //上限小于1時
  266.                         MH=99;                                        //上限賦值99
  267.                         write_com(0x80+0x40+3);           //選中液晶屏上的第二行第3列
  268.                         write_data('0'+MH/10);
  269.                         write_data('0'+MH%10);
  270.                         write_com(0x80+0x40+13);           //選中液晶屏上的第二行第13列
  271.                         write_data('0'+ML/10);
  272.                         write_data('0'+ML%10);
  273.                         write_com(0x80+0x40+4);//閃爍位置
  274.                         FENG=1;                                                //關閉蜂鳴器
  275.                 }
  276.                 if(set==2)
  277.                 {
  278.                         ML--;                                //下限值減
  279.                         if(ML<0)                //小于0時
  280.                         ML=MH-1;                                //下限-上限-1
  281.                         write_com(0x80+0x40+13);           //選中液晶屏上的第二行第13列
  282.                         write_data('0'+ML/10);
  283.                         write_data('0'+ML%10);
  284.                         write_com(0x80+0x40+14);//閃爍位置
  285.                         FENG=1;                                        //關閉蜂鳴器
  286.                 }
  287.                 write_eeprom();                           //保存數據
  288.         }
  289. }

  290. void  time1_int(void) interrupt 1                  //定時器工作函數
  291. {
  292.         uchar count;                                                  //定義計時變量
  293.         TL0=0xb0;
  294.          TH0=0x3c;                                                          //重新賦初值50ms
  295.           count++;                                                          //變量加一次就是50ms
  296.         if(count==10)                                                  //加到10次就是500ms
  297.         {
  298.                 if(flag==0)                                                  //flag=0時,也就是不開啟報警
  299.                 FENG=1;                                                  //關閉蜂鳴器
  300.                 if(flag==1)                                                  //flag為1時,也就是打開報警
  301.                 FENG=0;                                                  //打開蜂鳴器
  302.         }

  303.            if(count==20)                                                  //計數20次,就是1s
  304.            {                                                                          //在1s時,紅綠燈都是熄滅狀態,蜂鳴器也是關閉狀態,可以達到閃爍的目的
  305.                 count=0;                                                  //變量清零
  306.                 if(flag==0)                                                  //不是報警狀態時
  307.                 FENG=1;                                                         
  308.                 if(flag==1)                                                  //報警狀態時
  309.                 FENG=1;
  310.         }
  311. }
復制代碼

所有資料51hei提供下載(Proteus7.5仿真才能打開哦):
澆花系統.7z (423.66 KB, 下載次數: 62)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:918700 發表于 2021-5-12 16:37 | 顯示全部樓層
澆水的模塊呢
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲日本一区二区三区四区 | 精品二区 | 亚洲综合99 | 亚洲一区二区视频 | 精品一区二区三区电影 | 亚洲高清在线免费观看 | 精品视频一区二区三区在线观看 | 午夜在线电影网 | 欧美日韩一区二区三区不卡视频 | 久久久久国产一级毛片 | 91精品国产一区二区三区香蕉 | 日韩精品在线免费 | 日韩欧美三区 | 一区二区三区国产精品 | 亚洲视频欧美视频 | 超级乱淫av片免费播放 | 99精品一区二区 | 国产精品久久在线 | 欧美jizzhd精品欧美巨大免费 | 亚洲精品第一 | 亚洲一区二区三区免费在线观看 | 一区二区在线观看免费视频 | 91精品久久久久久久 | 欧美一级黄色片免费观看 | 九九看片| 一区二区三区不卡视频 | 中国人pornoxxx麻豆 | 免费成人av | 欧美中文字幕一区二区三区亚洲 | 久久综合九九 | 精一区二区 | h视频免费在线观看 | 日韩在线视频播放 | 欧美成人免费在线 | 在线视频91| 99草免费视频 | 国产一区二区精品在线观看 | 视频一区中文字幕 | 午夜一区二区三区在线观看 | 国产在线精品一区二区 | 特级特黄特色的免费大片 |