標(biāo)題: 單片機(jī)DS18B20溫度控制系統(tǒng)代碼與Proteus仿真原理圖 按鍵控制報警值 [打印本頁]

作者: willtg    時間: 2022-4-25 22:33
標(biāo)題: 單片機(jī)DS18B20溫度控制系統(tǒng)代碼與Proteus仿真原理圖 按鍵控制報警值
單片機(jī)+DS18b20完成溫度監(jiān)測系統(tǒng)設(shè)計,1602液晶顯示器顯示溫度數(shù)據(jù)和溫度報警數(shù)據(jù),按鍵控制報警值.

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


單片機(jī)源程序如下:
  1. #include<reg51.h>   
  2. #include<intrins.h>  //定義_nop_()函數(shù)的頭文件
  3. #include"lcd1602.h"
  4. #define uchar unsigned char   
  5. #define uint unsigned int

  6. int f;           //定義正 負(fù)溫度標(biāo)志
  7. unsigned char code str1[]={"T :"};
  8. unsigned char code str2[]={"T Alarm:"};
  9. unsigned char code digit[10]={"0123456789"};     //定義字符數(shù)組顯示的數(shù)字
  10. unsigned char code Cent[]={0xdf,"C"};           //顯示溫度單位為攝氏度

  11. sbit DQ=P3^3;                //DS18B20的DQ端與P3.3腳相連


  12. sbit key_up=P1^0;         //報警值增加按鍵
  13. sbit key_down=P1^1;         //報警值減小按鍵

  14. sbit led=P1^6;


  15. /*******************DS18B20延時函數(shù)****************************/
  16. void Delay_DS(int num)
  17. {
  18.     while(num--) ;
  19. }


  20. //DS18B20驅(qū)動程序
  21. /************************************************************/
  22. void Init_DS18B20(void)//初始化ds18b20
  23. {
  24.         DQ = 0;    //單片機(jī)將DQ拉低
  25.         Delay_DS(80);   //精確延時 大于 480us
  26.         DQ = 1;    //拉高總線
  27.         Delay_DS(14);
  28.         Delay_DS(20);
  29. }

  30. /******************************************************************************/
  31. unsigned char ReadOneChar(void)//讀一個字節(jié)
  32. {
  33.         unsigned char i=0;
  34.         unsigned char dat = 0;
  35.         for (i=8;i>0;i--)
  36.         {
  37.                 DQ = 0; // 給脈沖信號
  38.                 DQ=dat>>=1;        
  39.                 DQ = 1; // 給脈沖信號
  40.                 if(DQ)
  41.                 dat|=0x80;
  42.                 Delay_DS(4);
  43.         }
  44.         return(dat);
  45. }

  46. /******************************************************************************/
  47. void WriteOneChar(unsigned char dat)//寫一個字節(jié)
  48. {
  49.         unsigned char i=0;
  50.         for (i=8; i>0; i--)
  51.         {
  52.                 DQ = 0;
  53.                 DQ = dat&0x01;
  54.                 Delay_DS(5);
  55.                 DQ = 1;
  56.                 dat>>=1;
  57.         }
  58. }
  59. /******************************************************************************/
  60. unsigned int ReadTemperature(void)//讀取溫度
  61. {
  62.     unsigned char a=0;
  63.     unsigned char b=0;
  64.     unsigned int t=0;
  65.     float tt=0;
  66.     Init_DS18B20();
  67.         WriteOneChar(0xCC); // 跳過讀序號列號的操作
  68.         WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換      
  69.         Init_DS18B20();
  70.         WriteOneChar(0xCC); //跳過讀序號列號的操作
  71.         WriteOneChar(0xBE); //讀取溫度寄存器     
  72.         a=ReadOneChar();    //讀低8位            
  73.         b=ReadOneChar();    //讀高8位            
  74.    
  75. //        t = ((a&0xf0)>>4) | ((b&0x07)<<4);
  76. /*        t=b;
  77.     t<<=8;
  78.     t=t|a;
  79.     tt=t*0.0625;
  80.     t= tt*10+0.5; //放大10倍輸出并四舍五入*/

  81.         t=b;
  82.         t <<= 8;
  83.         t = t | a;         //將LSB和MSB整合成為一個16位的整數(shù)
  84.         //首先通過溫度數(shù)據(jù)的高5位判斷采用結(jié)果是正溫度還是負(fù)溫度
  85.         if((t & 0xf800) == 0x0000)    //正溫度的處理辦法
  86.         {
  87.                 t >>= 4;         //取出溫度結(jié)果的整數(shù)部分
  88.                 t = t*10;    //放大10倍,然后加上小數(shù)部分
  89.                 t = t + (a&0x0f)*0.625;        //保留1位小數(shù)
  90.                 f=0;
  91.         }
  92.         else if((t & 0xf800)== 0xf800)        //負(fù)溫度的處理辦法
  93.         {
  94.                 t=~t+1;           //負(fù)數(shù)補(bǔ)碼運(yùn)算,取反之后+1
  95.                 t >>= 4;         //取出溫度結(jié)果的整數(shù)部分
  96.                 t = t*10;    //放大10倍,然后加上小數(shù)部分
  97.                 t = t + (a&0x0f)*0.625;
  98.                 f=1;

  99.         }
  100.     return t;
  101.         return f;
  102. }

  103. void main()
  104. {
  105.         uchar n,m=0;
  106.         int i;
  107.         int alarm=0;
  108.         lcd_init();
  109.         lcd_wcom(0x80);   //顯示地址設(shè)為80H(即00H,)上排第一位         
  110.         for(m=0;m<3;m++)     //將table[]中的數(shù)據(jù)依次寫入1602顯示     
  111.         {               
  112.                 lcd_wdat(str1[m]);   
  113.                 delay(200);     
  114.         }
  115.         lcd_wcom(0x80+0x40); //重新設(shè)定顯示地址為0xc4,即下排第5位     

  116.         for(n=0;n<8;n++)   //將table1[]中的數(shù)據(jù)依次寫入1602顯示     
  117.         {                  
  118.                 lcd_wdat(str2[n]);            
  119.                 delay(200);     
  120.         }

  121.         
  122. while(1)
  123. {

  124.         i=ReadTemperature(); /*讀取當(dāng)前溫度*/
  125.         if(f==0)
  126.         {
  127.         lcd_wcom(0x80+0x05); //第一行顯示當(dāng)前溫度
  128.         lcd_wdat(digit[i/1000]);
  129.         lcd_wdat(digit[i/100%10]);
  130.         lcd_wdat(digit[i%100/10]);
  131.         lcd_wdat('.');
  132.         lcd_wdat(digit[i%10]);
  133.         lcd_wdat(Cent[0]);        
  134.         lcd_wdat(Cent[1]);

  135.         lcd_wcom(0x80+0x49);  //第二行顯示報警值
  136.         lcd_wdat(digit[alarm/10]);
  137.         lcd_wdat(digit[alarm%10]);
  138.         lcd_wdat(Cent[0]);        
  139.         lcd_wdat(Cent[1]);
  140.         }
  141.         else if(f==1)
  142.         {
  143.         lcd_wcom(0x80+0x05); //第一行顯示當(dāng)前溫度
  144.         lcd_wdat('-');
  145.         lcd_wdat(digit[i/1000]);
  146.         lcd_wdat(digit[i/100%10]);
  147.         lcd_wdat(digit[i%100/10]);
  148.         lcd_wdat('.');
  149.         lcd_wdat(digit[i%10]);
  150.         lcd_wdat(Cent[0]);        
  151.         lcd_wdat(Cent[1]);

  152.         lcd_wcom(0x80+0x49);  //第二行顯示報警值
  153.         lcd_wdat(digit[alarm/10]);
  154.         lcd_wdat(digit[alarm%10]);
  155.         lcd_wdat(Cent[0]);        
  156.         lcd_wdat(Cent[1]);        
  157.         }

  158.         if(key_up==0)   //報警值增加
  159.         {
  160.                 delay(10);
  161.                 if(key_up==0)
  162.                 {
  163.                         while(key_up==0);
  164.                         alarm++;
  165.                 }
  166.         }
  167.                 if(key_down==0)         //報警值減少
  168.         {
  169.                 delay(10);
  170.                 if(key_down==0)
  171.                 {
  172.                         while(key_down==0);
  173.                         if(alarm>0)
  174.                         {
  175.                         alarm--;
  176.                         }
  177.                         else
  178.                         alarm=0;
  179.                 }
  180.         }
  181.         
  182.         if(f==0&&i/10>alarm)        //超過報警值,報警燈亮
  183.         {
  184.                 led=0;
  185.         }
  186.         else if(f==1||i/10<alarm)
  187.         {
  188.         led=1;
  189.         }        
  190.         
  191. }   
  192. }
復(fù)制代碼

Keil代碼與Proteus仿真下載:
DS18B20例程.7z (1.11 MB, 下載次數(shù): 95)



作者: heicad    時間: 2022-4-27 22:46
好資料,51黑有你更精彩!!!




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1