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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3488|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)兩路DS18B20溫度檢測仿真與源碼(帶詳細(xì)注釋)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
兩路DS18B20溫度仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)



單片機(jī)源程序如下(注釋非常詳細(xì)):
  1. #include<reg51.h>                  //預(yù)處理命令,定義SFR的頭文件
  2. #include<math.h>                        //數(shù)學(xué)函數(shù)庫文件
  3. #define uchar unsigned char                //定義無符號字符變量 uchar
  4. #define uint unsigned int         //定義無符號字符變量 uint         
  5. #define lcd_data P0       //定義LCD1602接口 P0
  6. sbit P1_1=P1^1;
  7. sbit P1_0=P1^0;
  8. sbit DQ1=P3^7;        //將DQ1位定義為P3.7引腳
  9. sbit DQ=P3^6;         //將DQ位定義為P3.6引腳                                 
  10. sbit lcd_RS=P2^0;                     //將RS位定義為P2.0引腳
  11. sbit lcd_RW=P2^1;                    //將RW位定義為P2.1引腳
  12. sbit lcd_EN=P2^2;                    //將EN位定義為P2.2引腳
  13. uchar t[2],speed,temperature;      //用來存放溫度值
  14. uchar DS18B20_is_ok;
  15. uchar TempBufferl[16]={0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xdf,0x43,'\0'};
  16. uchar tab[16]={0x20,0x20,0x20,0x54,0x20,0x4d,0x6f,0x6e,0x69,0x74,0x6f,0x72,'\0'};   //顯示“T Monitor”
  17. /***********************LCD顯示子程序*****************************/
  18. void delay_20ms(void)     //延時20ms函數(shù)
  19. {  
  20.    uchar i,temp;                    //聲明變量i,temp
  21.    for(i=20;i>0;i--)           //循環(huán)
  22.    {
  23.      temp=248;                                //給temp賦值248
  24.          while(--temp);                         //temp減1是否等于0,否則繼續(xù)執(zhí)行該行
  25.          temp=248;                                  //給temp賦值248
  26.          while(--temp);                           //temp減1是否等于0,否則繼續(xù)執(zhí)行該行
  27.    }
  28. }
  29. void delay_38us(void)  //延時38μs函數(shù)
  30. {
  31.    uchar temp;                        //聲明變量temp
  32.    temp=18;                                // 給temp賦值
  33.    while(--temp);                 //temp減1是否等于0,否則繼續(xù)執(zhí)行該行
  34. }
  35. void delay_1520us(void)  //延時1520μs函數(shù)
  36. {
  37.    uchar i,temp;                  //聲明變量i,temp
  38.    for(i=3;i>0;i--)                   //循環(huán)
  39.    {
  40.      temp=252;                                //給temp賦值
  41.      while(--temp);                         //temp減1是否等于0,否則繼續(xù)執(zhí)行該行
  42.    }
  43. }
  44. uchar lcd_rd_status()      //讀取LCD602的狀態(tài),主要用于判斷是否忙
  45. {
  46.    uchar tmp_sts;                           //聲明變量tmp_sts
  47.    lcd_data=0xff;          //初始化P3口
  48.    lcd_RW=1;                                 //RW=1 讀
  49.    lcd_RS=0;                                 //RS=0 命令,合起來表示讀命令(狀態(tài))
  50.    lcd_EN=1;                                 //EN=1,打開EN,LCD1602開始輸出命令數(shù)據(jù),100ns后命令數(shù)據(jù)有效
  51.    tmp_sts=lcd_data;                  //讀取命令到tmp_sts
  52.    lcd_EN=0;                                  //關(guān)閉LCD1602
  53.    lcd_RW=0;                                  //把LCD1602設(shè)置成寫
  54.    return tmp_sts;                  //函數(shù)返回值tmp_sts
  55. }
  56. void lcd_wr_com(uchar command)          //寫一個命令到LCD1602
  57. {
  58.    while(0x80&lcd_rd_status());          //寫之前先判斷LCD1602是否忙,看讀出的命令的最高位是否為1,為1表示忙,繼續(xù)讀,直到不忙
  59.    lcd_RW=0;
  60.    lcd_RS=0;                                         //RW=0,RS=0寫命令
  61.    lcd_data=command;                         //把需要寫的命令寫到數(shù)據(jù)線上
  62.    lcd_EN=1;
  63.    lcd_EN=0;                                         //EN高電平脈沖,命令寫入
  64. }
  65. void lcd_wr_data(uchar sjdata)          //寫一個顯示數(shù)據(jù)到LCD1602
  66. {
  67.    while(0x80&lcd_rd_status());          //寫之前先判斷LCD1602是否忙,看讀出的命令的最高位是否為1,為1表示忙,繼續(xù)讀,直到不忙
  68.    lcd_RW=0;
  69.    lcd_RS=1;                                         //RW=0,RS=1寫顯示數(shù)據(jù)
  70.    lcd_data=sjdata;                         //把需要寫的顯示數(shù)據(jù)寫到數(shù)據(jù)線上
  71.    lcd_EN=1;
  72.    lcd_EN=0;                                         //EN高電平脈沖,命令寫入
  73.    lcd_RS=0;       
  74. }
  75. void Init_lcd(void)                        //初始化LCD1602
  76. {
  77.    delay_20ms();                                 //調(diào)用延時
  78.    lcd_wr_com(0x38);                   //設(shè)置16*2格式,5*8點(diǎn)陣,8位數(shù)據(jù)接口
  79.    delay_38us();                                  //調(diào)用延時
  80.    lcd_wr_com(0x0c);                   //開顯示,不顯示光標(biāo)
  81.    delay_38us();                                  //調(diào)用延時
  82.    lcd_wr_com(0x01);                   //清屏
  83.    delay_1520us();                        //調(diào)用延時
  84.    lcd_wr_com(0x06);                  //顯示一個數(shù)據(jù)后光標(biāo)自動+1
  85. }
  86. void GotoXY(uchar x,uchar y)        //設(shè)置位置,X為列,y為行
  87. {                                                               
  88.    if(y==0)
  89.      lcd_wr_com(0x80|x);                         //如果Y為0,則顯示第一行
  90.    if(y==1)
  91.      lcd_wr_com(0xc0|x);                          //如果Y為1,則顯示第二行
  92. }
  93. void Print(uchar *str)                          //顯示字符串函數(shù)
  94. {                                                                       
  95.    while(*str!='\0')                                   //判斷字符串是否顯示完
  96.    {
  97.      lcd_wr_data(*str);                         //寫數(shù)據(jù)
  98.      str++        ;
  99.    }
  100. }
  101. void LCD_Print(uchar x,uchar y,uchar *str)          //X為列值,Y為行值,str是要顯示的字符串
  102. {
  103.    GotoXY(x,y);                                                                  //設(shè)定顯示位置
  104.    Print(str);                                                                 //顯示字符串
  105. }
  106. /************************系統(tǒng)顯示子函數(shù)********************/
  107. void covert1()                                                         //溫度轉(zhuǎn)化程序
  108. {
  109.    uchar x=0x00;                                                         //變量初始化
  110.    if(t[1]>0x07)                                                         //判斷正負(fù)溫度
  111.    {
  112.      TempBufferl[3]=0x2d;                                   //0x2d為“-”的ASCII碼
  113.      t[1]=~t[1];                                                   //負(fù)數(shù)的補(bǔ)碼
  114.      t[0]=~t[0];                                                   //換算成絕對值
  115.      x=t[0]+1;                                                           //加1
  116.      t[0]=x;                                                           //把X的值送入t[0]
  117.      if(x>255)                                                           //如果X大于255
  118.      t[1]++;                                                           //t[1]加1
  119.    }
  120.    else                          
  121.      TempBufferl[3]=0x2b;                                  //0xfe為變“+”的ASCII碼
  122.    t[1]<<=4;                                                           //將高字節(jié)左移4位
  123.    t[1]=t[1]&0x70;                                           //取出高字節(jié)的3個有效數(shù)字位
  124.    x=t[0];                                                           //將t[0]暫存到X,因?yàn)槿⌒?shù)部分還要用它
  125.    x>>=4;                                                                   //右移4位
  126.    x=x&0x0f;                                                           //和前面兩句就是取出t[0]的高四位
  127.    t[1]=t[1]|x ;                                                    //將高低字節(jié)的有效值的整數(shù)部分拼成一個字節(jié)
  128.    temperature=t[1];
  129.    TempBufferl[4]=t[1]/100+0x30;                        //加0X30為變0-9ASCII碼
  130.    if(TempBufferl[4]==0x30)                                 //如果百位為0
  131.    TempBufferl[4]=0xfe;                                         //百位數(shù)消隱
  132.    TempBufferl[5]=(t[1]%100)/10+0x30;         //分離出十位
  133.    TempBufferl[6]=(t[1]%100)%10+0x30;         //分離出個位
  134. }
  135. /*********************DS18B20函數(shù)**********************/
  136. void delay_18B20(uint i)        //延時程序
  137. {
  138.    while(i--);
  139. }
  140. void Init_DS18B20(void)                                        //DS18B20初始化函數(shù)
  141. {
  142.    uchar x=0;
  143.    if(P1_0==1&P1_1==0)                                                  //按下P1_1
  144.    {
  145.      TempBufferl[0]=0x32;                                          //設(shè)置LCD第二行的第一位為2
  146.          TempBufferl[1]=0x3a;                                          //設(shè)置LCD第二行的第二位為:
  147.      DQ1=1;                                                                                //DQ1復(fù)位
  148.          delay_18B20(8);                                                        //稍做延時
  149.             DQ1=0;                                                                           //單片機(jī)將DQ1拉低
  150.          delay_18B20(80);                                                  //精確延時大于480us
  151.             DQ1=1;                                                                        //拉高總線
  152.          delay_18B20(14);                                                   //確保發(fā)出存在脈沖
  153.          x=DQ1;                                   //稍作延遲后,如果X=0則初始化成功,如果X=1則初始化失敗
  154.      delay_18B20(20);}
  155.    if(P1_0==0&P1_1==1)                                                        //按下P1_0
  156.    {
  157.          TempBufferl[0]=0x31;                                          //設(shè)置LCD第二行的第一位為1
  158.          TempBufferl[1]=0x3a;                                          //設(shè)置LCD第二行的第二位為:
  159.          DQ=1;                                                                           //DQ1復(fù)位
  160.          delay_18B20(8);                                                   //稍做延時
  161.             DQ=0;                                                                                //單片機(jī)將DQ1拉低
  162.          delay_18B20(80);                                                  //精確延時大于480us
  163.             DQ=1;                                                                           //拉高總線
  164.          delay_18B20(14);                                                   //確保發(fā)出存在脈沖
  165.          x=DQ;                                   //稍作延遲后,如果X=0則初始化成功,如果X=1則初始化失敗
  166.      delay_18B20(20);
  167.    }                                                                                  
  168.    if(P1_0==1&P1_1==1)                                                   //無按鍵按下
  169.    {
  170.      TempBufferl[0]=0x20;                                          //設(shè)置LCD第二行的第一位為空白
  171.      TempBufferl[1]=0x20;                                          //設(shè)置LCD第二行的第二位為空白
  172.    }
  173. }
  174. uchar ReadOneChar(void)                                                 //DS18B20讀一個字節(jié)函數(shù)
  175. {
  176.    unsigned char i=0;
  177.    unsigned char dat0=0;
  178.    for(i=8;i>0;i--)
  179.    {
  180.      if(P1_0==1&P1_1==0)                                                  //按下P1_1
  181.      {
  182.            TempBufferl[0]=0x32;                                          //設(shè)置LCD第二行的第一位為“2”
  183.            TempBufferl[1]=0x3a;                                          //設(shè)置LCD第二行的第二位為“:”
  184.            DQ1=0;                                                                                //讀前總線保持為低
  185.        dat0>>=1;
  186.        DQ1=1;                                                     //開始讀總線釋放                       
  187.        if(DQ1) dat0|=0x80;                                         //從DS18B20總線讀得一位
  188.            delay_18B20(4);                                   //延時一段時間
  189.          }
  190.    if(P1_0==0&P1_1==1)                                                   //按下P1_0
  191.    {
  192.          TempBufferl[0]=0x31;                                          //設(shè)置LCD第二行的第一位為1
  193.          TempBufferl[1]=0x3a;                                          //設(shè)置LCD第二行的第二位為:
  194.          DQ=0;                                                                                 //讀前總線保持為低
  195.      dat0>>=1;
  196.      DQ=1;                                              //開始讀總線釋放                               
  197.      if(DQ) dat0|=0x80;                                                                          //從DS18B20總線讀得一位
  198.          delay_18B20(4);                    //延時一段時間
  199.    }
  200.    if(P1_0==1&P1_1==1)                   //無按鍵按下
  201.    {
  202.      TempBufferl[0]=0x20;                                          //設(shè)置LCD第二行的第一位為空白
  203.      TempBufferl[1]=0x20;                                          //設(shè)置LCD第二行的第二位為空白
  204.    }
  205.   }
  206.   return(dat0);                                                           //返回?cái)?shù)據(jù)
  207. }
  208. void WriteOneChar(uchar dat1)                                //DS18B20寫一個字節(jié)函數(shù)
  209. {
  210.    uchar i=0;
  211.    for(i=8;i>0;i--)
  212.    {
  213.      if(P1_0==1&P1_1==0)                                                  //按下P1_1
  214.      {
  215.           TempBufferl[0]=0x32;                                          //設(shè)置LCD第二行的第一位為“2”
  216.           TempBufferl[1]=0x3a;                                          //設(shè)置LCD第二行的第二位為“:”
  217.           DQ1=0;                //開始寫入DS18B20總線要處于復(fù)位(低)狀態(tài)
  218.           DQ1=dat1&0x01;        //寫入下一位                                       
  219.           delay_18B20(5);                                                 
  220.       DQ1=1;                 //重新釋放總線
  221.           dat1>>=1;                 //把一個字節(jié)分成8個BIT環(huán)移給DQ1
  222.          }          
  223.      if(P1_0==0&P1_1==1)         //按下P1_0
  224.      {
  225.           TempBufferl[0]=0x31;                                          //設(shè)置LCD第二行的第一位為1
  226.           TempBufferl[1]=0x3a;                                          //設(shè)置LCD第二行的第二位為:
  227.           DQ=0;                                 //開始寫入DS18B20總線要處于復(fù)位(低)狀態(tài)
  228.           DQ=dat1&0x01;                        //寫入下一位                       
  229.           delay_18B20(5);                                                  
  230.       DQ=1;                 //重新釋放總線
  231.           dat1>>=1;                 //把一個字節(jié)分成8個BIT環(huán)移給DQ
  232.          }                                                                  
  233.      if(P1_0==1&P1_1==1)           //無按鍵按下
  234.      {
  235.       TempBufferl[0]=0x20;                                          //設(shè)置LCD第二行的第一位為空白
  236.       TempBufferl[1]=0x20;                                          //設(shè)置LCD第二行的第二位為空白
  237.          }
  238.    }
  239. }                                                                                  
  240. void ReadTemperature()                                          //讀取DS18B20當(dāng)前溫度
  241. {
  242.   delay_18B20(80);                                                        //延時一段時間
  243.   Init_DS18B20();
  244.   WriteOneChar(0xcc);                                           //跳過讀序列列號的操作
  245.   WriteOneChar(0x44);                                          //啟動溫度轉(zhuǎn)換
  246.   delay_18B20(80);                                                   //延時一段時間
  247. ……………………

  248. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
兩路DS18B20.zip (464.64 KB, 下載次數(shù): 94)






分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:57896 發(fā)表于 2018-1-16 17:15 | 只看該作者
參考一下,謝謝分享
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久精品国产久精国产 | 成人久久网| 国产精品一二区 | 国产在线高清 | 色99视频 | 无毛av| 国产免费看 | 国产一级视频在线观看 | 国产精品久久精品 | 欧美精品网 | 久久99精品久久久97夜夜嗨 | 精品国产一区二区三区免费 | 国产精品一区网站 | 国产在线观看一区 | 欧美一区二区激情三区 | 国产一区二区在线视频 | 嫩草视频免费 | 美女视频一区二区三区 | 欧美日批| www.亚洲视频.com | 蜜月va乱码一区二区三区 | 国内91在线| 日韩在线观看 | 午夜不卡福利视频 | 亚洲精品久久久一区二区三区 | 欧美多人在线 | 在线观看中文字幕 | 免费黄色的视频 | 祝你幸福电影在线观看 | 一级黄色夫妻生活 | av在线三级 | 自拍偷拍中文字幕 | 国产电影一区二区在线观看 | 久久久精品综合 | 久久精品国产一区二区三区不卡 | 亚洲国产精品第一区二区 | 一区二区三区视频在线 | 久热免费 | 麻豆亚洲 | 久久在线| 日日干日日 |