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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8647|回復: 8
收起左側

51單片機的智能熱水器系統源碼+原理圖設計

  [復制鏈接]
ID:398752 發表于 2018-11-24 21:46 | 顯示全部樓層 |閱讀模式
  無水警報,自動加水,防溢出,利用電子稱檢測水位, DS18B20檢測溫度。

制作出來的實物圖如下:
控制系統.jpg

電路原理圖如下:

原理圖

原理圖


單片機源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include <string.h>

  4. bit bdata flag_key;
  5. #include "main.h"
  6. #include "LCD1602.h"
  7. #include "HX711.h"
  8. #include "keyboard.h"

  9. sfr AUXR = 0x8e;   

  10. #define uchar unsigned char
  11. #define uint  unsigned int

  12. unsigned char code digit[10]={"0123456789"};     //定義字符數組顯示數字
  13. unsigned char code Temp[]={"Temp:"};             //說明顯示的是溫度
  14. unsigned char code Cent[]={"C"};              //溫度單位
  15. unsigned long HX711_Buffer = 0;
  16. unsigned long Weight_Maopi = 0;
  17. unsigned long Weight_Maopi_0 = 0;
  18. unsigned int qupi=0;
  19. long Weight_Shiwu = 100;
  20. //鍵盤處理變量
  21. unsigned char keycode;
  22. //unsigned char DotPos;                                   //小數點標志及位置

  23. uint GapValue,GapValue1;

  24. unsigned int idata price=50;     //溫度設定值,長整型值

  25. //定義標識
  26. volatile bit FlagTest = 0;                //定時測試標志,每0.5秒置位,測完清0
  27. volatile bit FlagKeyPress = 0;  //有鍵按下標志,處理完畢清0
  28. //校準參數
  29. //因為不同的傳感器特性曲線不是很一致,因此,每一個傳感器需要矯正這里這個參數才能使測量值很準確。
  30. //當發現測試出來的重量偏大時,增加該數值。
  31. //如果測試出來的重量偏小時,減小改數值。
  32. //該值可以為小數
  33. //#define GapValue 349
  34. sbit LED=P1^1;

  35. sbit motor = P2^1;                                                           //水泵加水
  36. sbit jiare = P2^0;                                                           //啟動熱水壺的繼電器控制位


  37. volatile bit ClearWeighFlag = 0; //傳感器調零標志位,清除0漂

  38.                                                                                                                
  39. //顯示溫度設置

  40. void Display_Price()
  41. {
  42.                         unsigned char a,b,c,d;
  43.                         a = price /1000%10;
  44.                         b = price /100%10;
  45.                         c = price /10%10;
  46.                         d = price %10;
  47.             WriteAddress(0x86);
  48.                         WriteData(digit[a] );
  49.                         WriteData(digit[b] );

  50.                         WriteData(digit[c] );
  51. //                           WriteData(digit[d] );
  52. }

  53. //顯示溫度,第二行

  54. /************************************************************************
  55. 以下是DS18B20的操作程序
  56. ************************************************************************/
  57. sbit DQ=P2^2;
  58. unsigned char time;   //設置全局變量,專門用于嚴格延時
  59. /*****************************************************
  60. 函數功能:將DS18B20傳感器初始化,讀取應答信號
  61. 出口參數:flag
  62. ***************************************************/
  63. bit Init_DS18B20(void)
  64. {
  65. bit flag;         //儲存DS18B20是否存在的標志,flag=0,表示存在;flag=1,表示不存在
  66. DQ = 1;           //先將數據線拉高
  67. for(time=0;time<2;time++) //略微延時約6微秒
  68.      ;
  69. DQ = 0;           //再將數據線從高拉低,要求保持480~960us
  70. for(time=0;time<200;time++) //略微延時約600微秒
  71.      ;         //以向DS18B20發出一持續480~960us的低電平復位脈沖
  72. DQ = 1;           //釋放數據線(將數據線拉高)
  73. for(time=0;time<10;time++)
  74.      ; //延時約30us(釋放總線后需等待15~60us讓DS18B20輸出存在脈沖)
  75. flag=DQ;          //讓單片機檢測是否輸出了存在脈沖(DQ=0表示存在)      
  76. for(time=0;time<200;time++) //延時足夠長時間,等待存在脈沖輸出完畢
  77.       ;
  78. return (flag);    //返回檢測成功標志
  79. }
  80. /*****************************************************
  81. 函數功能:從DS18B20讀取一個字節數據
  82. 出口參數:dat
  83. ***************************************************/
  84. unsigned char ReadOneChar(void)
  85. {
  86.    unsigned char i=0;
  87.    unsigned char dat; //儲存讀出的一個字節數據
  88.    for (i=0;i<8;i++)
  89.    {
  90.      
  91.      DQ =1;       // 先將數據線拉高
  92.      _nop_();     //等待一個機器周期
  93.      DQ = 0;      //單片機從DS18B20讀書據時,將數據線從高拉低即啟動讀時序
  94.     dat>>=1;
  95.      _nop_();     //等待一個機器周期     
  96.      DQ = 1;     //將數據線"人為"拉高,為單片機檢測DS18B20的輸出電平作準備
  97.      for(time=0;time<2;time++)
  98.              ;      //延時約6us,使主機在15us內采樣
  99.      if(DQ==1)
  100.         dat|=0x80; //如果讀到的數據是1,則將1存入dat
  101.     else
  102.      dat|=0x00;//如果讀到的數據是0,則將0存入dat
  103.        //將單片機檢測到的電平信號DQ存入r[i]
  104.      for(time=0;time<8;time++)
  105.         ;              //延時3us,兩個讀時序之間必須有大于1us的恢復期
  106.      }                     
  107. return(dat);    //返回讀出的十進制數據
  108. }
  109. /*****************************************************
  110. 函數功能:向DS18B20寫入一個字節數據
  111. 入口參數:dat
  112. ***************************************************/
  113. WriteOneChar(unsigned char dat)
  114. {
  115. unsigned char i=0;
  116. for (i=0; i<8; i++)
  117.    {
  118.     DQ =1;         // 先將數據線拉高
  119.     _nop_();      //等待一個機器周期
  120.     DQ=0;          //將數據線從高拉低時即啟動寫時序      
  121.     DQ=dat&0x01;   //利用與運算取出要寫的某位二進制數據,
  122.                        //并將其送到數據線上等待DS18B20采樣
  123.    for(time=0;time<10;time++)
  124.        ;//延時約30us,DS18B20在拉低后的約15~60us期間從數據線上采樣
  125.     DQ=1;          //釋放數據線      
  126.     for(time=0;time<1;time++)
  127.      ;//延時3us,兩個寫時序間至少需要1us的恢復期
  128.     dat>>=1;       //將dat中的各二進制位數據右移1位
  129.    }
  130.    for(time=0;time<4;time++)
  131.                ; //稍作延時,給硬件一點反應時間
  132. }
  133. /*****************************************************
  134. 函數功能:延時1ms
  135. (3j+2)*i=(3×33+2)×10=1010(微秒),可以認為是1毫秒
  136. ***************************************************/
  137. void delay1ms()
  138. {
  139.    unsigned char i,j;
  140. for(i=0;i<4;i++)
  141.    for(j=0;j<33;j++)
  142.     ;   
  143. }
  144. /*****************************************************
  145. 函數功能:延時若干毫秒
  146. 入口參數:n
  147. ***************************************************/
  148. void delaynms(unsigned char n)
  149. {
  150.    unsigned char i;
  151.     for(i=0;i<n;i++)
  152.     delay1ms();
  153. }
  154. /***********************************************************
  155. //溫度顯示相關程序
  156. ***********************************************************/
  157. void display_symbol(void)
  158. {
  159.        unsigned char i;
  160.       WriteAddress(0x40);    //寫顯示地址,將在第2行第1列開始顯示
  161.       i = 0;                //從第一個字符開始顯示
  162.      while(Temp[i] != '\0') //只要沒有寫到結束標志,就繼續寫
  163.      {      
  164.       WriteData(Temp[i]);   //將字符常量寫入LCD
  165.       i++;                 //指向下一個字符
  166.       delaynms(50);        //延時1ms給硬件一點反應時間
  167.      }
  168. }
  169. /*****************************************************
  170. 函數功能:顯示溫度的小數點
  171. ***************************************************/   
  172. void display_dot(void)
  173. {         
  174. WriteAddress(0x49);   //寫顯示地址,將在第2行第10列開始顯示     
  175. WriteData('.');      //將小數點的字符常量寫入LCD
  176. delaynms(50);         //延時1ms給硬件一點反應時間  
  177. }
  178. /*****************************************************
  179. 函數功能:顯示溫度的單位(C)
  180. ***************************************************/   
  181. void display_cent(void)
  182. {
  183.            unsigned char i;   
  184.       WriteAddress(0x4c);        //寫顯示地址,將在第2行第13列開始顯示
  185.       i = 0;                    //從第一個字符開始顯示
  186.      while(Cent[i] != '\0')     //只要沒有寫到結束標志,就繼續寫
  187.      {     
  188.       WriteData(Cent[i]);     //將字符常量寫入LCD
  189.       i++;                 //指向下一個字符
  190.       delaynms(50);        //延時1ms給硬件一點反應時間
  191.      }
  192. }

  193. /*****************************************************
  194. 函數功能:顯示溫度的整數部分
  195. 入口參數:x
  196. ***************************************************/
  197. void display_temp1(unsigned char x)
  198. {
  199. unsigned char j,k,l;     //j,k,l分別儲存溫度的百位、十位和個位
  200. j=x/100;              //取百位
  201. k=(x%100)/10;    //取十位
  202. l=x%10;             //取個位
  203. WriteAddress(0x46);    //寫顯示地址,將在第2行第7列開始顯示
  204. WriteData(digit[j]);    //將百位數字的字符常量寫入LCD
  205. WriteData(digit[k]);    //將十位數字的字符常量寫入LCD
  206. WriteData(digit[l]);    //將個位數字的字符常量寫入LCD
  207. delaynms(50);         //延時1ms給硬件一點反應時間     
  208. }
  209. /*****************************************************
  210. 函數功能:顯示溫度的小數數部分
  211. 入口參數:x
  212. ***************************************************/
  213. void display_temP3(unsigned char x)
  214. {
  215.    WriteAddress(0x4a);      //寫顯示地址,將在第2行第11列開始顯示
  216. WriteData(digit[x]);     //將小數部分的第一位數字字符常量寫入LCD
  217. delaynms(50);          //延時1ms給硬件一點反應時間
  218. }
  219. void ReadyReadTemp(void)
  220. {
  221.       Init_DS18B20();     //將DS18B20初始化
  222.       WriteOneChar(0xCC); // 跳過讀序號列號的操作
  223.       WriteOneChar(0x44); // 啟動溫度轉換   
  224.       for(time=0;time<100;time++)
  225.              ; //溫度轉換需要一點時間
  226.    Init_DS18B20();     //將DS18B20初始化
  227.    WriteOneChar(0xCC); //跳過讀序號列號的操作
  228.    WriteOneChar(0xBE); //讀取溫度寄存器,前兩個分別是溫度的低位和高位
  229. }


  230. /***********************************************************/

  231. //數據初始化
  232. void Data_Init()
  233. {
  234.    price = 0;
  235. //   DotPos = 0;
  236. }
  237. //定時器0初始化               

  238. void Timer0_Init()
  239. {
  240.         ET0 = 1;        //允許定時器0中斷
  241.         TMOD = 1;       //定時器工作方式選擇
  242.         TL0 = 0xb0;     
  243.         TH0 = 0x3c;     //定時器賦予初值
  244.         TR0 = 1;        //啟動定時器
  245. //        AUXR &= 0x7F;                //定時器時鐘12T模式
  246. //        TMOD &= 0xF0;                //設置定時器模式
  247. //        TMOD |= 0x01;                //設置定時器模式
  248. //        TL0 = 0xCE;                //設置定時初值
  249. //        TH0 = 0xFF;                //設置定時初值
  250. //        TF0 = 0;                //清除TF0標志
  251. //        TR0 = 1;                //定時器0開始計時
  252. //                 ET0 = 1;        //允許定時器0中斷
  253. //                EA = 1;
  254. }

  255. //定時器0中斷
  256. void Timer0_ISR (void) interrupt 1 //using 0
  257. {
  258. uchar Counter;
  259.         TL0 = 0xb0;
  260.         TH0 = 0x3c;     //定時器賦予初值
  261. //        TL0 = 0xCE;                //設置定時初值
  262. //        TH0 = 0xFF;                //設置定時初值

  263.         //每0.5秒鐘刷新重量
  264.     Counter ++;
  265.     if (Counter >= 10)
  266.     {
  267.        FlagTest = 1;
  268.            Counter = 0;
  269.     }
  270. }


  271. //按鍵響應程序,參數是鍵值
  272. //返回鍵值:

  273. //        14   0    15  13                          //11:清除設置
  274. //        7    8    9   12                          //12:開啟motor控制繼電器
  275. //                  4    5    6   11                     //13:開啟jiare控制繼電器
  276. //        1    2    3   10                          //15:關閉兩個繼電器
  277. void KeyPress(uchar keycode)
  278. {
  279.         switch (keycode)
  280.         {
  281.                 case 0:
  282.                 case 1:
  283.                 case 2:
  284.                 case 3:
  285.                 case 4:
  286.                 case 5:
  287.                 case 6:
  288.                 case 7:
  289.                 case 8:
  290.                 case 9:        //目前在設置整數位,要注意price是整型,存儲單位為分
  291. //                        if (DotPos == 0)
  292. //                        {                        //最多只能設置到千位
  293.                                 if (price<10000)
  294.                                 {
  295.                                         price=price*10+keycode*10;

  296.                                 }
  297. //                        }//目前在設置小數位
  298. //                        else if (DotPos==1)  //小數點后第一位
  299. //                        {
  300. //                                price=price+keycode;
  301. //                                DotPos=2;
  302. //                        }
  303.                         Display_Price();
  304.                         break;
  305.                 case 10:   //去皮鍵

  306.                         Display_Price();
  307.                         break;
  308.                 case 11:        //刪除鍵
  309.                         price=0;
  310. //                        DotPos=0;
  311.                         Display_Price();
  312.                         break;
  313.                 case 12:           //
  314.                         motor = 1;       

  315.                         break;
  316.                 case 13:   //
  317.                         jiare = 1;
  318.                              
  319.                         break;
  320.                 case 15:   //                                 停止加熱,停止加水
  321.                            motor = 0;
  322.                            jiare = 0;
  323.                         break;

  324.    }
  325. }
  326. //****************************************************
  327. //主函數
  328. //****************************************************
  329. void main()
  330. {         
  331.     unsigned char TL;       //儲存暫存器的溫度低位
  332.     unsigned char TH;       //儲存暫存器的溫度高位
  333.     unsigned char TN;       //儲存溫度的整數部分
  334.     unsigned char TD;       //儲存溫度的小數部分
  335.         unsigned int h;
  336.            GapValue = 2200;

  337.         Init_LCD1602();                                                                        //初始化LCD1602
  338.     EA = 0;
  339.     Data_Init();
  340.     Timer0_Init();
  341.    //初中始化完成,開斷
  342.     EA = 1;
  343.          motor = 0;
  344.          jiare = 0;
  345.          
  346.          if(Init_DS18B20()==1)
  347.          
  348.              display_symbol();
  349.               display_dot();       //顯示溫度的小數點
  350.          display_cent();       //顯示溫度的單位

  351.    LCD1602_write_com(0x80);                                                //指針設置
  352.    LCD1602_write_word(" Welcome To Use ");        //  
  353.    LCD1602_write_com(0x80+0x40);                                                //指針設置
  354.    LCD1602_write_word("Temp:");

  355.    Get_Maopi();
  356.    LCD1602_write_com(0x80);                                                //指針設置
  357.    LCD1602_write_word("Set:        C  ");

  358.    Display_Price();

  359.         while(1)
  360.         {
  361. //每0.5秒稱重一次         

  362.           if (FlagTest==1)
  363.                 {                    
  364.                         Get_Weight();  
  365.                         FlagTest = 0;
  366.                 }
  367.           if ( h == 1)
  368.           {
  369.                 if (TN >= (price/10) )
  370.                 {
  371.                         jiare =0;
  372.                         Buzzer = 0;
  373.                 }

  374.                 if( (TN < (price/10))&&(Weight_Shiwu > 700))
  375.                 {
  376.                    jiare = 1;
  377.                    Buzzer = 1;
  378.                 }

  379.            }
  380.                 ReadyReadTemp();     //讀溫度準備
  381.         TL=ReadOneChar();    //先讀的是溫度值低位
  382.         TH=ReadOneChar();    //接著讀的是溫度值高位
  383.         TN=TH*16+TL/16;      //實際溫度值=(TH*256+TL)/16,即:TH*16+TL/16
  384.                      //這樣得出的是溫度的整數部分,小數部分被丟棄了
  385.         TD=(TL%16)*10/16;    //計算溫度的小數部分,將余數乘以10再除以16取整,
  386.                      //這樣得到的是溫度小數部分的第一位數字(保留1位小數)
  387.         display_temp1(TN);    //顯示溫度的整數部分
  388.         display_temP3(TD);    //顯示溫度的小數部分
  389.         delaynms(10);     
  390.                  
  391.                  
  392.           keycode = Getkeyboard();
  393.           //有效鍵值0-15
  394.           if (keycode<16)
  395.           {
  396.                  KeyPress(keycode);
  397.                  Buzzer=0;
  398.                  Delay_ms(100);
  399.                  Buzzer=1;
  400.                  while(keycode<16)
  401.                  {
  402.                         if(keycode==12||keycode==13||keycode==15)
  403.                         {
  404.                                 Buzzer=0;
  405.                                  Delay_ms(10);
  406.                                  Buzzer=1;                               
  407.                                  KeyPress(keycode);
  408.                                  Get_Weight();
  409.                                  flag_key=1;
  410.                                  h = 1;
  411.                         }
  412.                         keycode = Getkeyboard();
  413.                  }

  414.           }
  415.         }
  416. }
  417. //****************************************************
  418. //稱重
  419. //****************************************************
  420. void Get_Weight()
  421. {
  422.         Weight_Shiwu = HX711_Read();
  423.         Weight_Shiwu = Weight_Shiwu - Weight_Maopi;                //獲取凈重
  424.        
  425.         Weight_Shiwu = (unsigned int)((float)Weight_Shiwu*6/GapValue)-qupi ;         //計算實物的實際重量
  426.                                                                                                                                        
  427. ……………………

  428. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
智能飲水系統.rar (90.4 KB, 下載次數: 185)

評分

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

查看全部評分

回復

使用道具 舉報

ID:401170 發表于 2018-12-12 19:00 | 顯示全部樓層
想要那個電路圖QWQ能發一份給我嗎,我的7805畫不出來
回復

使用道具 舉報

ID:220936 發表于 2018-12-13 08:38 | 顯示全部樓層
這個創意挺好,用電子秤測水位
回復

使用道具 舉報

ID:600397 發表于 2019-8-15 12:22 來自手機 | 顯示全部樓層
不錯哦
回復

使用道具 舉報

ID:634919 發表于 2019-11-3 18:26 | 顯示全部樓層
想看一下完整的實物圖,謝謝
回復

使用道具 舉報

ID:634898 發表于 2019-11-3 20:22 | 顯示全部樓層
創意太好了  贊一個
回復

使用道具 舉報

ID:642942 發表于 2019-11-15 23:32 | 顯示全部樓層
你好 我的設計是這個能不能提供具體流程軟件介紹
回復

使用道具 舉報

ID:562553 發表于 2019-11-26 14:18 | 顯示全部樓層
感謝分享
回復

使用道具 舉報

ID:662319 發表于 2020-1-4 12:56 | 顯示全部樓層
謝謝大佬的分享
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 成人免费在线网 | 91久久久久久 | 99精品福利视频 | 国产精品久久久久久二区 | 精品一区二区三区在线观看国产 | 日韩欧美成人一区二区三区 | 欧美视频一区二区三区 | 一级做a爰片久久毛片 | 免费在线观看一区二区 | 亚洲日产精品 | 99久久精品国产一区二区三区 | 免费看91 | 四虎影视1304t | 亚洲天堂男人的天堂 | 日韩免费一区 | 男人天堂99 | 欧美在线高清 | 一区二区不卡视频 | 免费高清av | 久久久中文 | 日本小电影在线 | 国产区在线| 国产精品久久久久久久久久久免费看 | 992人人草 | 亚洲电影一区二区三区 | 在线欧美a| 国产一区二区三区视频 | 啪啪免费网 | 欧美成人精品在线 | 成人国产精品久久 | a亚洲精品 | 午夜激情免费 | 一区二区三区四区免费观看 | 日本欧美国产在线 | 在线看黄免费 | 日本视频中文字幕 | 国产一区二区三区四区在线观看 | av免费观看在线 | 一级免费看片 | 国产免费一区 | 日韩中文字幕一区 |