找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1960|回復: 1
收起左側(cè)

單片機DS18B20智能溫控系統(tǒng)程序與Proteus仿真圖

[復制鏈接]
ID:456407 發(fā)表于 2023-3-11 21:53 | 顯示全部樓層 |閱讀模式
溫度監(jiān)控系統(tǒng)采用單片機進行控制,由溫度檢測電路、顯示電路、A/D 轉(zhuǎn)換電路、執(zhí)行機構(gòu)、控制電路和單片微處理器等組成。用單片機作為控制器,可對執(zhí)行機構(gòu)發(fā)出指令,實現(xiàn)溫度參數(shù)調(diào),溫度實時顯示等功能。系統(tǒng)下位機由傳感器檢測模塊,鍵盤顯示模塊和執(zhí)行機構(gòu)模塊三大部分構(gòu)成。

Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei.png 51hei.png

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

單片機源程序如下:
  1. #include<reg52.h>         //51單片機的頭文件
  2. #include<intrins.h>   //函數(shù)程序中需要使用到空指令
  3. /***_crol_ 字符循環(huán)左移
  4.     _cror_ 字符循環(huán)右移
  5.     _irol_ 整數(shù)循環(huán)左移
  6.     _iror_ 整數(shù)循環(huán)右移
  7.     _lrol_ 長整數(shù)循環(huán)左移
  8.     _lror_ 長整數(shù)循環(huán)右移
  9.     _nop_ 空操作 (相當于8051 NOP 指令)
  10.     _testbit_ 測試并清零位 (相當于8051 JBC 指令) ***/
  11. #define dm P0          //段碼輸出口
  12. #define uchar unsigned char //宏定義,用uchar來代替unsigned char(無符號字符型變量,也即是無符號的8位變量),                                         
  13. //宏定義的原因就是書寫方便,宏定義后,uchar可直接用來定義變量
  14. #define uint unsigned int  //原因同上,不過要注意,unsigned int為無符號的整型變量
  15. //sbit是用來管腳的。
  16. sbit DQ=P1^0;          //溫度輸入口
  17. sbit w0=P2^4;          //數(shù)碼管4
  18. sbit w1=P2^5;          //數(shù)碼管3
  19. sbit w2=P2^6;          //數(shù)碼管2
  20. sbit w3=P2^7;          //數(shù)碼管1
  21. sbit beep=P2^0;   //蜂鳴器
  22. sbit jidianqi=P2^1; //繼電器
  23. sbit yellow=P3^5;          //加熱指示燈
  24. sbit led=P3^6;            //高溫指示燈
  25. sbit zc=P3^7;         //系統(tǒng)運行正常指示燈
  26. sbit set=P3^4;                     //選擇設(shè)置
  27. sbit add=P3^3;                  //加
  28. sbit dec=P3^2;                  //減
  29. int temp1=0;//最高溫度和最低溫度標志位         
  30. uint h;
  31. uint temp;        //溫度函數(shù)
  32. uchar r;
  33. uchar high=30,low=28;        //開機默認最高溫度和最低溫度
  34. uchar sign;
  35. uchar q=0;
  36. uchar tt=0;
  37. uchar scale;
  38. uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};          //共陽小數(shù)斷碼表
  39. uchar code table_dm[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xbf};          //共陽LED段碼表"0""1""2""3""4""5""6""7""8""9""不亮""-"
  40. uchar code table_dm1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};        //共陽個位帶小數(shù)點的斷碼表
  41. uchar data temp_data[2]={0xff,0xff};//讀出溫度暫放
  42. uchar data display[5]={0xff,0xff,0xff,0xff,0xff};//顯示單元數(shù)據(jù),共四個數(shù)據(jù)和一個運算暫用
  43. /***************11us延時函數(shù)***************/
  44. void delay(uint t)
  45. {
  46.         for(;t>0;t--);
  47. }
  48. /***************數(shù)碼管顯示***************/
  49. void scan()
  50. {
  51.         int j;
  52.         for(j=0;j<4;j++)
  53.         {
  54.                 switch(j)
  55.                 {
  56.                         case 0:
  57.                         dm=table_dm[display[0]];;
  58.                         w0=0;  //打開數(shù)碼管顯示小數(shù)數(shù)字的數(shù)碼管位選端
  59.                         delay(50);
  60.                         w0=1;        //關(guān)閉數(shù)碼管顯示小數(shù)數(shù)字的數(shù)碼管位選端
  61.                         case 1:
  62.                         dm=table_dm1[display[1]];
  63.                         w1=0;  //打開數(shù)碼管顯示個位數(shù)字的數(shù)碼管位選端
  64.                         delay(50);
  65.                         w1=1;        //關(guān)閉數(shù)碼管顯示個位數(shù)字的數(shù)碼管位選端
  66.                         case 2:
  67.                         dm=table_dm[display[2]];
  68.                         w2=0;        //打開數(shù)碼管顯示十位數(shù)字的數(shù)碼管位選端
  69.                         delay(50);
  70.                         w2=1;        //關(guān)閉數(shù)碼管顯示十位數(shù)字的數(shù)碼管位選端
  71.                         case 3:
  72.                         dm=table_dm[display[3]];
  73.                         w3=0;        //打開數(shù)碼管顯示百位數(shù)字的數(shù)碼管位選端
  74.                         delay(50);
  75.                         w3=1;        //關(guān)閉數(shù)碼管顯示百位數(shù)字的數(shù)碼管位選端
  76.                 }
  77.         }
  78. }
  79. /****溫度傳感器采用的是DS18b20,此傳感器采用的
  80. 是“單總線”來傳輸數(shù)據(jù)。****/
  81. /**************DS18B20初始化**************/
  82. ow_reset(void)         //初始化
  83. {
  84.         char presence=1;
  85.         while(presence)
  86.         {
  87.                 while(presence)
  88.                 {
  89.                         DQ=1;_nop_();_nop_();   //將數(shù)據(jù)線拉高并延時
  90.                         DQ=0;           //將DQ(P1.0)引腳拉低。請注意,這里的DQ不是變量,而是單片機的引腳!!                 
  91.                         delay(50);   //延時
  92.                         DQ=1;     //將DS拉高
  93.                         delay(6);
  94.                         presence=DQ;
  95.                 }
  96.                 delay(45);
  97.                 presence=~DQ;
  98.         }
  99.         DQ=1;        
  100.         return presence;
  101. }
  102. /****************寫命令函數(shù)*****************/
  103. void write_byte(uchar val)
  104. {
  105.         uchar i;
  106.         for(i=8;i>0;i--)
  107.         {
  108.                 DQ=1;_nop_();_nop_();    //將數(shù)據(jù)線拉高并延時
  109.                 DQ=0;_nop_();_nop_();_nop_();_nop_();          //將數(shù)據(jù)線拉低并延時
  110.                 DQ=val&0x01;
  111.                 delay(6);
  112.                 val=val>>1;               
  113.         }
  114.         DQ=1;
  115.         delay(1);
  116. }        
  117. /****************讀一個字節(jié)函數(shù)*******************/
  118. uchar read_byte(void)
  119. {
  120.         uchar i;
  121.         uchar value=0;
  122.         for(i=8;i>0;i--)  //采用for 循環(huán),讀取原始溫度數(shù)據(jù)
  123.         {
  124.                 DQ=1;_nop_();_nop_();
  125.                 value>>=1;
  126.                 DQ=0;_nop_();_nop_();_nop_();_nop_();
  127.                 DQ=1;_nop_();_nop_();_nop_();_nop_();
  128.                 if(DQ)value|=0x80;
  129.                 delay(6);
  130.         }
  131.         DQ=1;        
  132.         return value;
  133. }
  134. /***************讀取溫度函數(shù)***************/
  135. read_temp()           //讀取18b20傳感器函數(shù)
  136. {
  137.         ow_reset();
  138.         delay(200);
  139.         write_byte(0xcc);
  140.         write_byte(0x44);
  141.         ow_reset();
  142.         delay(1);
  143.         write_byte(0xcc);
  144.         write_byte(0xbe);
  145.         temp_data[0]=read_byte();
  146.         temp_data[1]=read_byte();
  147.         temp=temp_data[1];
  148.         temp<<=8;
  149.         temp=temp|temp_data[0];
  150.         return temp;
  151. }
  152. /***************溫度數(shù)據(jù)處理函數(shù)***************/
  153. work_temp(uint tem)         //溫度轉(zhuǎn)換函數(shù)
  154. {
  155.         uchar n=0;
  156.         if(tem>6348)
  157.         {
  158.                 tem=65536-tem;
  159.                 n=1;
  160.         }
  161.         display[4]=tem&0x0f;
  162.         display[0]=ditab[display[4]];
  163.         display[4]=tem>>4;
  164.         display[3]=display[4]/100;
  165.         display[1]=display[4]%100;
  166.         display[2]=display[1]/10;
  167.         display[1]=display[1]%10;
  168.         r=display[1]+display[2]*10+display[3]*100;
  169.         if(!display[3])
  170.         {
  171.                 display[3]=0x0a;
  172.                 if(!display[2])        
  173.                 {
  174.                         display[2]=0x0a;
  175.                 }
  176.         }
  177.         if(n)
  178.         {
  179.                 display[3]=0x0b;
  180.         }
  181.         return n;
  182. }
  183. /***************報警提示電路***************/
  184. void BEEP()
  185. {
  186.    
  187.         {zc=0;}         //系統(tǒng)正常指示燈
  188.         if(r>=high&&r<129)         //如果實際溫度高于等于于設(shè)定溫度
  189.         {
  190.                 led=0;//保溫燈亮
  191.                 beep=0;//蜂鳴器響
  192.                 jidianqi=1; //繼電器停止加熱
  193.                 yellow=1;//加熱燈滅
  194.         }
  195.         else  //否則
  196.         {
  197.                 beep=1;//蜂鳴器停
  198.         }
  199.         if(r<low)         //如果實際溫度小于設(shè)定溫度
  200.         {
  201.                 yellow=0;//加熱燈亮
  202.             led=1;//保溫燈滅
  203.                 jidianqi=0;          //繼電器開始加熱
  204.         }
  205. }
  206. /***************溫度顯示轉(zhuǎn)換**************/
  207. void xianshi(int horl)                 //數(shù)碼管顯示函數(shù)
  208. {
  209.         int n=0;
  210.         if(horl>128)
  211.         {
  212.                 horl=256-horl;
  213.                 n=1;
  214.         }
  215.         display[3]=horl/100;         //         顯示千位
  216.         display[3]=display[3]&0x0f;          //顯示千位
  217.         display[2]=horl%100/10;                   // 顯示百位
  218.         display[1]=horl%10;                                // 顯示個位
  219.         display[0]=0;                          // 顯示分
  220.         if(!display[3])
  221.         {
  222.                 display[3]=0x0a;
  223.                 if(!display[2])        
  224.                 {
  225.                         display[2]=0x0a;
  226.                 }
  227.         }
  228.         if(n)
  229.         {
  230.                 display[3]=0x0b;
  231.         }                                                                                
  232. }
  233. /**************按鍵設(shè)置*************/
  234. void keyscan()
  235. {
  236.         int temp1;    //最高溫度和最低溫度標志位
  237.         if(set==0)          //設(shè)置按鍵按下按鍵低電平有效
  238.         {
  239.                 while(1)
  240.                 {
  241.                         delay(500);//消抖
  242.                         if(set==0)         //只有按下松手后,再按按鍵才能再次使設(shè)定值自加一次
  243.                         {
  244.                                 temp1++;  //設(shè)定值自加一次
  245.                                 while(!set)
  246.                                 scan();
  247.                         }
  248.                         if(temp1==1)
  249.                         {
  250.                                 xianshi(high);
  251.                                 scan();
  252.                                 if(add==0)
  253.                                 {
  254.                                         while(!add)
  255.                                         scan();
  256.                                         high+=1;
  257.                                 }
  258.                                 if(dec==0)
  259.                                 {
  260.                                         while(!dec)
  261.                                         scan();
  262.                                         high-=1;
  263.                                 }
  264.                         }
  265.                         if(temp1==2)
  266.                         {
  267.                                 xianshi(low);
  268.                                 if(add==0)
  269.                                 {
  270.                                         while(!add)
  271.                                         scan();
  272.                                         low+=1;
  273.                                 }
  274.                                 if(dec==0)
  275.                                 {
  276.                                         while(!dec)
  277.                                         scan();
  278.                                         low-=1;
  279.                                 }
  280.                                 scan();
  281.                         }
  282.                         if(temp1>=3)
  283.                         {
  284.                                 temp1=0;
  285.                                 break;
  286.                         }
  287.                 }
  288.         }
  289. }
  290. /**************主函數(shù)*************/
  291. void main()
  292. {
  293.         dm=0x00; //對P0口初始化,開機讓數(shù)碼管顯示(000.0)
  294.         w0=0;         //關(guān)閉數(shù)碼管位選W0~W3
  295.         w1=0;
  296.         w2=0;
  297.         w3=0;
  298.         for(h=0;h<4;h++)
  299.         {
  300.                 display[h]=0;
  301.         }
  302.         ow_reset();
  303.         write_byte(0xcc);
  304.         write_byte(0x44);
  305.         for(h=0;h<100;h++)
  306.         {
  307.                 scan();
  308.         }
  309.         while(1)                  //循環(huán)
  310.         {
  311.                 if(temp1==0)
  312.                 {
  313.                         work_temp(read_temp());
  314.                         scan();
  315.                         BEEP();
  316.                         keyscan();
  317.                 }
  318.                 else        
  319.                         keyscan();
  320.             
  321.         }        
  322. }
  323. /*****************結(jié)束*****************//*****************結(jié)束*****************/
復制代碼

Keil代碼與Proteus8.13仿真下載:
溫控.7z (1.58 MB, 下載次數(shù): 41)

評分

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

查看全部評分

回復

使用道具 舉報

ID:492633 發(fā)表于 2023-3-13 21:19 來自手機 | 顯示全部樓層
這不是我的圖嗎?雖然程序也是轉(zhuǎn)別人的魔改的
回復

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表