找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2721|回復(fù): 8
收起左側(cè)

一個“基于ds18b20的電熱水器水溫控制器”的求助

[復(fù)制鏈接]
ID:528612 發(fā)表于 2022-6-19 12:15 | 顯示全部樓層 |閱讀模式
這個是單片機練習(xí),大致需要實現(xiàn)的功能如下:
1.包括一個電源開關(guān),一個設(shè)定按鍵,兩個控制設(shè)定溫度增減的按鍵
2.通過4位數(shù)碼管分別顯示設(shè)定溫度和實際溫度,量程為0到99度,開機后設(shè)定溫度值初始化為26度(這個地方我用了兩個2位數(shù)碼管分別顯示,設(shè)定溫度值通過藍色數(shù)碼管顯示)
3.用ds18b20對溫度進行轉(zhuǎn)換并通過數(shù)碼管顯示(通過紅色數(shù)碼管顯示)
4.單片機要根據(jù)設(shè)定溫度S和實測溫度P控制繼電器R的動作,精度為2度
(1)當(dāng)P<=S-1時,繼電器接通加熱回路
(2)當(dāng)P>S+1時,繼電器斷開加熱回路
(3)當(dāng)P>S-1且P<=S+1時,繼電器保持原狀態(tài)不變

目前原理圖和程序都已經(jīng)基本完成了,但是只實現(xiàn)了“通過ds18b20讀取溫度并通過數(shù)碼管顯示”,和“通過數(shù)碼管顯示設(shè)定溫度,并通過按鍵增減數(shù)值”這兩個模塊的功能,按下設(shè)定按鍵后,無論設(shè)定溫度和實測溫度值之間關(guān)系如何,P3.0口始終保持高電平,繼電器沒有任何動作,目前找不到問題出在什么地方。
此外還很好奇為什么開始仿真時,顯示實測溫度的數(shù)碼管會顯示85大約1秒鐘的時間,之后才恢復(fù)正常,如果可以解決的話又要如何解決呢?
希望各位大神能夠指導(dǎo)一下。

下面是原理圖:

原理圖,應(yīng)該也存在需要修改的地方

原理圖,應(yīng)該也存在需要修改的地方

下面是我自己在參考了一些文章后編寫的代碼,參考的部分主要是控制ds18b20初始化和讀寫數(shù)據(jù)
  1. /*預(yù)計實現(xiàn)功能:DS18B20讀取溫度通過P3.7口送入單片機,P3.2和P3.3通過外部中斷方式增大或減小設(shè)定溫度值*/
  2. /*P3.1口是設(shè)定按鍵,P3.0口通過光耦連接繼電器*/
  3. /*設(shè)定按鍵按下后,當(dāng)DS18B20讀取到的溫度數(shù)值小于設(shè)定溫度減1時,繼電器會接通;*/
  4. /*當(dāng)讀取到的溫度大于設(shè)定溫度加1時,繼電器斷開;*/
  5. /*當(dāng)讀取到的溫度大于設(shè)定溫度-1且小于等于設(shè)定溫度+1時,繼電器不動作*/
  6. /*目前的問題是程序只能實現(xiàn)顯示當(dāng)前溫度和設(shè)定溫度兩個功能*/
  7. /*而無論當(dāng)前溫度和設(shè)定溫度數(shù)值大小關(guān)系如何,P3.0口始終保持高電平,無任何動作,目前找不到問題出在什么地方*/
  8. /*希望能夠得到解答和幫助*/
  9. #include<reg51.h>//頭文件

  10. /*測量部分溫度顯示相關(guān)變量定義*/
  11. sbit DQ=P3^7;//DE18B20總線
  12. sbit CurTempTP=P2^0;//當(dāng)前溫度十位,Curent Temperature's Ten Place
  13. sbit CurTempOP=P2^1;//當(dāng)前溫度個位,Curent Temperature's One Place
  14. char CurTemp;//量程限制為0到99攝氏度,故使用有符號字符型變量
  15. int CurTempTPNum;//當(dāng)前溫度十位數(shù)字
  16. int CurTempOPNum;//當(dāng)前溫度個位數(shù)字

  17. /*設(shè)定部分溫度顯示相關(guān)變量定義*/
  18. char SetTemp=26;//設(shè)定溫度,初始值為26
  19. sbit SetTempTP=P2^2;//設(shè)定溫度的十位,set temperature's one place
  20. sbit SetTempOP=P2^3;//設(shè)定溫度的個位,set temperature's ten place
  21. int SetTempTPNum;//設(shè)定溫度十位數(shù)字
  22. int SetTempOPNum;//設(shè)定溫度個位數(shù)字

  23. /*其他設(shè)定*/
  24. sbit SetButton=P3^1;//溫度設(shè)定按鍵
  25. sbit Heater=P3^0;//加熱線圈繼電器控制
  26. int a,b;

  27. unsigned char LED[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};//定義0~9共陽極數(shù)碼管字符碼

  28. void DelayMs(const int ms)//毫秒延時子程序,正常
  29. {
  30.     int i;
  31.     for(i=0;i<ms;i++)//單次循環(huán)約1毫秒,根據(jù)輸入的ms值進行延時
  32.     {
  33.         int j;
  34.         for(j=0;j<120;j++);
  35.     }
  36. }

  37. void DelayUs(unsigned int k)//微秒延時子程序,正常
  38. {
  39.     while(k--);//每次數(shù)值減1延時約6微秒,設(shè)定值為需要延時的時間除以6
  40. }

  41. void DS18B20Init()//ds18b20初始化子程序,正常
  42. {        
  43.     unsigned char Flag=0;//DS18B20初始化標(biāo)志位
  44.     DQ=1;//暫時拉高總線
  45.     DelayUs(5);//稍作延時
  46.     DQ=0;//主機(單片機)發(fā)送復(fù)位脈沖
  47.     DelayUs(80);//保持480微秒以上
  48.     DQ=1;//然后釋放總線
  49.     DelayUs(14);//若從機(DS18B20)初始化成功,會在15到60微秒后產(chǎn)生低電平信號,信號持續(xù)60到240微秒
  50.         Flag=DQ;//若DQFlag=0則初始化成功,DQFlag=1則初始化失敗
  51.         DelayUs(20);
  52. }

  53. unsigned char DS18B20ReadData()//ds18b20讀數(shù)據(jù)子程序,正常
  54. {
  55.     unsigned char k=0;
  56.     unsigned char dat=0;
  57.     for(k=8;k>0;k--)
  58.     {
  59.         DQ=0;//拉低總線
  60.         dat=dat>>1;//從最高位開始讀取數(shù)據(jù),每讀取一位后向右移動一位
  61.         DQ=1;//釋放總線
  62.         if(DQ)
  63.             dat|=0x80;
  64.                 DelayUs(4);

  65.     }
  66.     return dat;
  67. }

  68. void DS18B20WriteData(unsigned char com)//ds18b20寫數(shù)據(jù)子程序,com為command,正常
  69. {
  70.     unsigned char l=0;
  71.     for(l=8;l>0;l--)
  72.     {
  73.         DQ=0;//拉低總線
  74.         DQ=com&0x01;//從最低位開始寫入指令數(shù)據(jù),
  75.                 DelayUs(5);//延時
  76.         DQ=1;//釋放總線
  77.         com=com>>1;//寫入一位后,指令數(shù)據(jù)右移一位等待下一位寫入
  78.     }
  79. }

  80. unsigned char DS18B20GetTemp()//溫度獲取
  81. {
  82.     unsigned char TL=0;//溫度低8位
  83.     unsigned char TH=0;//溫度高8位
  84.         unsigned char Temp=0;
  85.     DS18B20Init();//溫度轉(zhuǎn)換部分,初始化
  86.     DS18B20WriteData(0xcc);//跳過讀rom
  87.     DS18B20WriteData(0x44);//轉(zhuǎn)換溫度
  88.         DS18B20Init();//溫度讀取部分
  89.     DS18B20WriteData(0xcc);
  90.     DS18B20WriteData(0xbe);//讀取溫度
  91.     TL=DS18B20ReadData();//讀低8位
  92.     TH=DS18B20ReadData();//讀高8位
  93.     Temp=TH<<4;//高8位左移4位后賦值
  94.         Temp=Temp|TL>>4;//低8位左移4位舍棄小數(shù)部分后按位或賦值
  95.     return Temp;//返回Temp
  96. }

  97. void ShowTemp()//測量溫度數(shù)值與設(shè)定溫度數(shù)值綜合顯示,兩種數(shù)值顯示區(qū)間均為0到99攝氏度,正常
  98. {
  99.         //顯示當(dāng)前測量溫度,數(shù)碼管接P0口,數(shù)位由P2.0和P2.1口控制
  100.         if(CurTemp>=0&&CurTemp<=99)//當(dāng)測量值處于0到99攝氏度區(qū)間
  101.     {
  102.             CurTempTPNum=CurTemp/10;//取測量值十位
  103.         CurTempOPNum=CurTemp%10;//取測量值個位
  104.             //顯示測量值十位,點亮1毫秒后熄滅
  105.                 CurTempTP=1;
  106.             P0=LED[CurTempTPNum];
  107.             DelayMs(10);
  108.             CurTempTP=0;
  109.             //顯示測量值個位,點亮1毫秒后熄滅
  110.                 CurTempOP=1;
  111.             P0=LED[CurTempOPNum];
  112.             DelayMs(10);
  113.             CurTempOP=0;
  114.         }
  115.         else if(CurTemp<0)//當(dāng)測量值低于0攝氏度,則數(shù)碼管顯示0
  116.         {
  117.             CurTempTP=1;
  118.             P0=LED[0];
  119.             DelayMs(10);
  120.             CurTempTP=0;
  121.             CurTempOP=1;
  122.             P0=LED[0];
  123.             DelayMs(10);
  124.             CurTempOP=0;
  125.           }
  126.         else if(CurTemp>99)//當(dāng)測量值高于99攝氏度,則數(shù)碼管顯示9
  127.         {
  128.             CurTempTP=1;
  129.             P0=LED[9];
  130.             DelayMs(10);
  131.             CurTempTP=0;
  132.             CurTempOP=1;
  133.             P0=LED[9];
  134.             DelayMs(10);
  135.             CurTempOP=0;
  136.           }
  137.         //顯示當(dāng)前設(shè)定溫度,數(shù)碼管連接P1口,數(shù)位由P2.2和P2.3控制
  138.     SetTempTPNum=SetTemp/10;//取設(shè)定值十位
  139.     SetTempOPNum=SetTemp%10;//取設(shè)定值個位
  140.     //顯示設(shè)定值十位,點亮1毫秒后熄滅
  141.         SetTempOP=1;
  142.     P1=LED[SetTempOPNum];
  143.     DelayMs(10) ;
  144.     SetTempOP=0;
  145.     //顯示設(shè)定值個位,點亮1毫秒后熄滅
  146.         SetTempTP=1;
  147.     P1=LED[SetTempTPNum];
  148.     DelayMs(10);
  149.     SetTempTP=0;
  150. }

  151. void Add() interrupt 0//P3.2口接按鈕控制增加設(shè)定值,正常
  152. {
  153.     if(SetTemp<99)//防止數(shù)值溢出
  154.     {
  155.         SetTemp++;//設(shè)定值加1
  156.     }
  157. }

  158. void Sub() interrupt 2//P3.3口接按鈕控制減小設(shè)定值,正常
  159. {
  160.     if(SetTemp>0)//防止數(shù)值過小
  161.     {
  162.         SetTemp--;//設(shè)定值減1
  163.     }
  164. }

  165. void main()//主函數(shù),有問題
  166. {
  167.     EA=1;//允許總中斷
  168.         EX0=1;//允許外部中斷0
  169.         EX1=1;//允許外部中斷1
  170.     IT0=1;//外部中斷0跳沿觸發(fā)
  171.     IT1=1;//外部中斷1跳沿觸發(fā)
  172.         Heater=0;
  173.     while(1)
  174.         {
  175.                 CurTemp=DS18B20GetTemp();//讀取DS18B20轉(zhuǎn)換的溫度
  176.                 ShowTemp();
  177.                 a=SetTemp-1;
  178.                 b=SetTemp+1;
  179.                 if(SetButton==0)//原本按下按鍵后應(yīng)該會對當(dāng)前溫度和設(shè)定溫度進行比較然后確定繼電器的動作,但是卻沒有任何反應(yīng),也不清楚是哪里出了問題
  180.                 {
  181.                     DelayMs(10);
  182.                     if(SetButton==0)
  183.                     {                       
  184.                             if(CurTemp>a&&CurTemp<=b)
  185.                             {
  186.                                 ;
  187.                             }
  188.                                 else if(CurTemp<=a)
  189.                             {
  190.                                 Heater=0;
  191.                             }
  192.                             else if(CurTemp>b)
  193.                             {
  194.                                     Heater=1;
  195.                             }
  196.                     }
  197.                 }                                                           
  198.         }
  199. }                    
復(fù)制代碼

基于DS18B20的水溫控制器,但是程序有點小問題.zip (98.88 KB, 下載次數(shù): 162)

回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2022-6-19 20:15 | 顯示全部樓層
把這個示例略改一下就能滿足你的要求
DS18B20溫度上下限報警 仿真.rar (177.89 KB, 下載次數(shù): 113)

回復(fù)

使用道具 舉報

ID:161164 發(fā)表于 2022-6-19 23:25 | 顯示全部樓層
電阻!你最少缺了一個電阻
2022-06-19_232402.png
回復(fù)

使用道具 舉報

ID:528612 發(fā)表于 2022-6-20 00:17 來自觸屏版 | 顯示全部樓層
lkc8210 發(fā)表于 2022-6-19 23:25
電阻!你最少缺了一個電阻

啊…這個沒注意到,感謝指出
回復(fù)

使用道具 舉報

ID:1030903 發(fā)表于 2022-6-20 23:29 來自觸屏版 | 顯示全部樓層
剛上電顯示85?1秒后才是正常讀數(shù)?是不是你初始設(shè)定的值是85呀
回復(fù)

使用道具 舉報

ID:528612 發(fā)表于 2022-6-23 08:38 | 顯示全部樓層
無恥之徒 發(fā)表于 2022-6-20 23:29
剛上電顯示85?1秒后才是正常讀數(shù)?是不是你初始設(shè)定的值是85呀

沒有,初始值是默認就是85
回復(fù)

使用道具 舉報

ID:1006814 發(fā)表于 2022-6-23 09:11 | 顯示全部樓層
主程序應(yīng)該一直比較當(dāng)前溫度和設(shè)置溫度,符合條件執(zhí)行對應(yīng)的程序。
回復(fù)

使用道具 舉報

ID:195496 發(fā)表于 2022-6-24 17:51 | 顯示全部樓層
上電后第一次讀出的就是85度,要多讀幾次才行
回復(fù)

使用道具 舉報

ID:528612 發(fā)表于 2022-7-15 11:41 | 顯示全部樓層
問題已經(jīng)解決了,感謝各位
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表