<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • x
    x

    51單片機-溫度傳感器DS18B20

    發布時間:2011-3-22 11:37    發布者:techshare
    關鍵詞: 51單片機 , DS18B20 , 溫度傳感器
    溫度傳感器是各種傳感器中最常用的一種,早期使用的是模擬溫度傳感器,如熱敏電阻,隨著環境溫度的變化,它的阻值也發生線性變化,用處理器采集電阻兩端的電壓,然后根據某個公式就可以計算出當前環境溫度。美國DALLAS半導體公司推出的數字化溫度傳感器DS18B20采用單總線協議,即與單片機接口僅需占用一個I/O端口,無需任何外部元件,直接將環境溫度轉化成數字信號,以數字碼方式串行輸出,從而大大簡化了傳感器與處理器的接口。  

    DS18B20的三種封裝:  


       
    DS18B20的內部結構:  


       
    它采用單條信號線,既可傳輸時鐘,又可傳輸數據,而且數據傳輸是雙向的。如果要控制多個DS18B20進行溫度采集,只要將所有的DS18B20的I/O口全部連接到一起就可以了。在具體操作時,通過讀取每個DS18B20內部芯片的序列號來識別。64位光刻ROM中的序列號是出場前被光刻好的,他可以看做該DS18B20的地址序列碼。  

    DS18B20的復位時序:  


       
    DS18B20復位,確定其存在:     #include <reg52.h>
    #define uint unsigned int
    uint i;
    sbit DQ = P3^3;
    sbit bell = P3^4;

    void reset(){
            DQ = 1;                //開始的時候是高脈沖
            DQ=0;                      //然后是低脈沖
            i=103;
              while(i>0)i--;        //低脈沖需要延遲一會兒
              DQ=1;                        //數據線拉高,系統將總線放開,并進入接受狀態
              i=4;
              while(i>0)i--;        //延時等待,若初始化成功則在15"60ms內產生一個由
            if(DQ == 0){        //DS18B20在檢測到總線的上升沿后,等待15"60ms,接著
                    while(DQ == 0); //在T2時刻發出存在脈沖(低電平)
                    bell = 0;
            }
            else
                    bell = 1;        
    }

    void main(){
            reset();
            while(1);
    }






       



    DS18B20的寫0和寫1時序:







    DS18B20的讀數據時序:










    讀出光刻ROM中的ID號,在LCD上顯示:


      
        #include <reg52.h>
    #include<intrins.h>
    sbit DQ = P3^3;
    sbit RS = P1^0;
    sbit RW = P1^1;
    sbit E = P1^2;
    sbit bell = P3^4;

    #define uchar unsigned char
    #define uint unsigned int
    #define        nop() _nop_()

    uint i;
    uchar value;
    uchar DS[8];
    uchar Time_Data[]={'0','1','2','3','4','5','6','7',
                                       '8','9','A','B','C','D','E','F'};

    void delay(uchar t){
       while(--t);
    }

    void lcd_com(uchar s){
        RS = 0;                    //低電平,寫指令
        P2 = s;                    //傳數據
        delay(14);                //看時序圖,數據需要穩定一段時間
        E = 1;                            //給一個高脈沖,發送命令
        delay(14);                    //如圖,高脈沖延時一段時間,確保命令發送
        E = 0;                            //發送結束E置為低電平
    }

    void lcd_data(uchar s){
        RS = 1;
        P2 = s;
        delay(14);
        E = 1;
        delay(14);
        E = 0;
    }

    void init_lcd(){
        RS = 1;         //先發指令,在初始時刻RS是高,E和RW是低
        E = 0;
        RW = 0;
        lcd_com(0x38);           //設置為16*2顯示,5*7點陣,8位數據接口
        lcd_com(0x0f);           //開顯示,顯示光標,光標閃爍
        lcd_com(0x06);           //讀寫一個字符后地址指針加一
        lcd_com(0x01);
    }

    void Display_lcd(uchar y, uchar x, uchar value){
            if(y)
                    lcd_com(0x80+0x40+x);   //如果y為1,寫在第二行
            else
                    lcd_com(0x80+x);
            lcd_data(value);                        //寫到LCD602上
    }
             
    void DS18B20_reset(){
            DQ = 1;                //開始的時候是高脈沖
            DQ=0;                //然后是低脈沖
            i=103;
              while(i>0)i--;        //低脈沖需要延遲一會兒
              DQ=1;                        //數據線拉高
              i=4;
              while(i>0)i--;        //延時等待,若初始化成功則在15"60ms內產生一個由
            if(DQ == 0){        //DS18B20返回的低電平
                    while(DQ == 0);
            //        bell = 0;
            }
            else
                    bell = 1;        
    }

    uchar DS18B20_read(void)
    {
            uchar i = 0;
            uchar Value = 0;
            for(i = 0; i < 8; i ++)
                    {
                            DQ = 1;         
                            DQ = 0;
                            delay(1);   
                            DQ = 1;      //在T1時刻將總線拉高,產生讀時間隙
                            delay(1);    //讀時隙在T1和T2之間有效
                            if(DQ)
                                    {
                                            Value |= 0x01 << i;
                                    }
                            delay(17);   //必須在T3時刻之間主機完成讀操作
                            DQ = 1;
                            nop();
                    }
            return Value;
    }
            
    void DS18B20_write(uchar Value){
            for(i = 0; i < 8; i++){
                    DQ = 1;              
                    DQ = 0;              //當t0從高拉低產生寫時隙,
                    delay(5);        
                    DQ = Value & 0x01;   //必須在t0開始的15us內將數據送到總線上
                    delay(20);           //DS18B20在t0后的15us"60us內對總線采樣
                    DQ = 1;              //如果采到低電平則寫入0,高電平寫入1
                    Value >>= 1;
                    delay(2);
            }        
    }
      
    void DS18B20_ID_read(){
            DS18B20_reset();
            DS18B20_write(0x33);
            for(i = 0; i < 8; i++)
                    DS[ i] = DS18B20_read();
    }

    void main(){
             init_lcd();
             while(1){
                     DS18B20_ID_read();
                     Display_lcd(0,0,'>');
                    Display_lcd(0,1,':');
                    Display_lcd(0,2,Time_Data[DS[0]/16]);
                    Display_lcd(0,3,Time_Data[DS[0]%16]);
                    Display_lcd(0,4,'>');
                    Display_lcd(0,5,':');
                    Display_lcd(0,6,Time_Data[DS[1]/16]);
                    Display_lcd(0,7,Time_Data[DS[1]%16]);
                    Display_lcd(0,8,'>');
                    Display_lcd(0,9,':');
                    Display_lcd(0,10,Time_Data[DS[2]/16]);
                    Display_lcd(0,11,Time_Data[DS[2]%16]);
                    Display_lcd(0,12,'>');
                    Display_lcd(0,13,':');
                    Display_lcd(0,14,Time_Data[DS[3]/16]);
                    Display_lcd(0,15,Time_Data[DS[3]%16]);
                    Display_lcd(1,0,'>');
                    Display_lcd(1,1,':');
                    Display_lcd(1,2,Time_Data[DS[4]/16]);
                    Display_lcd(1,3,Time_Data[DS[4]%16]);
                    Display_lcd(1,4,'>');
                    Display_lcd(1,5,':');
                    Display_lcd(1,6,Time_Data[DS[5]/16]);
                    Display_lcd(1,7,Time_Data[DS[5]%16]);
                    Display_lcd(1,8,'>');
                    Display_lcd(1,9,':');
                    Display_lcd(1,10,Time_Data[DS[6]/16]);
                    Display_lcd(1,11,Time_Data[DS[6]%16]);
                    Display_lcd(1,12,'>');
                    Display_lcd(1,13,':');
                    Display_lcd(1,14,Time_Data[DS[7]/16]);
                    Display_lcd(1,15,Time_Data[DS[7]%16]);
             }
    }
      

      


      單只DS18B20工作流程:

      



      2只DS18B20并聯工作流程:

      



      DS18B20溫度存儲格式:

      



      DS18B20暫存器的分布:

      



      DS18B20內部ROM指令:

      



      DS18B20內部RAM指令:

      

      

    讀出當前溫度,在LCD上顯示,溫度超過一定時,報警。
      



      #include <reg52.h>
    #include<intrins.h>
    sbit DQ = P3^3;
    sbit RS = P1^0;
    sbit RW = P1^1;
    sbit E = P1^2;
    sbit bell = P3^4;

    #define uchar unsigned char
    #define uint unsigned int
    #define        nop() _nop_()

    uint i;
    uchar value;
    uchar DS[8];
    uchar Time_Data[]={'0','1','2','3','4','5','6','7',
                                       '8','9','A','B','C','D','E','F'};

    void delay(uchar t){
       while(--t);
    }

    void Lcd_Com(uchar s){
        RS = 0;                    //低電平,寫指令
        P2 = s;                    //傳數據
        delay(14);                //看時序圖,數據需要穩定一段時間
        E = 1;                            //給一個高脈沖,發送命令
        delay(14);                    //如圖,高脈沖延時一段時間,確保命令發送
        E = 0;                            //發送結束E置為低電平
    }

    void Lcd_Data(uchar s){
        RS = 1;
        P2 = s;
        delay(14);
        E = 1;
        delay(14);
        E = 0;
    }

    void Init_Lcd(){
        RS = 1;         //先發指令,在初始時刻RS是高,E和RW是低
        E = 0;
        RW = 0;
        Lcd_Com(0x38);           //設置為16*2顯示,5*7點陣,8位數據接口
        Lcd_Com(0x0f);           //開顯示,顯示光標,光標閃爍
        Lcd_Com(0x06);           //讀寫一個字符后地址指針加一
        Lcd_Com(0x01);
    }

    void Display_Lcd(uchar y, uchar x, uchar value){
            if(y)
                    Lcd_Com(0x80+0x40+x);   //如果y為1,寫在第二行
            else
                    Lcd_Com(0x80+x);
            Lcd_Data(value);                        //寫到LCD602上
    }
             
    void DS18B20_Reset(){
            DQ = 1;                //開始的時候是高脈沖
            DQ=0;                //然后是低脈沖
            i=103;
              while(i>0)i--;        //低脈沖需要延遲一會兒
              DQ=1;                        //數據線拉高
              i=4;
              while(i>0)i--;        //延時等待,若初始化成功則在15"60ms內產生一個由
            if(DQ == 0){        //DS18B20返回的低電平
                    while(DQ == 0);
            //        bell = 0;
            }
            else
                    bell = 1;        
    }

    uchar DS18B20_Read(void)
    {
            uchar i = 0;
            uchar Value = 0;
            for(i = 0; i < 8; i ++)
                    {
                            DQ = 1;
                            DQ = 0;
                            delay(1);
                            DQ = 1;
                            delay(1);
                            if(DQ)
                                    {
                                            Value |= 0x01 << i;
                                    }
                            delay(17);
                            DQ = 1;
                            nop();
                    }
            return Value;
    }
            
    void DS18B20_Write(uchar Value){
            for(i = 0; i < 8; i++){
                    DQ = 1;
                    DQ = 0;
                    delay(5);
                    DQ = Value & 0x01;
                    delay(20);
                    DQ = 1;
                    Value >>= 1;
                    delay(2);
            }        
    }
      
    uchar DS18B20_Temp_Read(){
            uchar temp_h,temp_l,temp;
            DS18B20_Reset();                        //復位
            DS18B20_Write(0x0cc);                //跳過ROM,只有一個所以跳過
            DS18B20_Write(0x44);                //開始溫度轉換
            DS18B20_Reset();                        //復位
            DS18B20_Write(0x0cc);                //跳過ROM
            DS18B20_Write(0x0be);                //讀暫存器
            temp_l = DS18B20_Read();        //讀出溫度低8位
            temp_h = DS18B20_Read();        //讀出溫度高8位
            temp_l >>= 4;                                //去掉4位小數位
            temp_h <<= 4;                                //去掉4位符號位
            temp = temp_h | temp_l;               
            temp = temp & 0x7f;                        //最高位是符號位
            return temp;        
    }

    void main(){
             uchar temp;
             Init_Lcd();
             while(1){
                     temp = DS18B20_Temp_Read();
                    if(temp > 25)                                 //如果溫度大于25報警
                            bell = 0;
                    else
                            bell = 1;
                    Display_Lcd(0,0,'T');
                    Display_Lcd(0,1,'E');
                    Display_Lcd(0,2,'M');
                    Display_Lcd(0,3,'P');
                    Display_Lcd(0,4,':');
                    Display_Lcd(0,5,Time_Data[temp/100]);
                    Display_Lcd(0,6,Time_Data[temp%100/10]);
                    Display_Lcd(0,7,Time_Data[temp%10]);
             }
    }

    李萬鵬
    本文地址:http://www.portaltwn.com/thread-59318-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    williamkmcn 發表于 2011-7-7 16:58:43
    好東西值得收藏
    williamkmcn 發表于 2011-7-7 16:59:00
    好東西值得收藏
    horse 發表于 2017-1-24 10:41:35
    收藏學習了!
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • EtherCAT®和Microchip LAN925x從站控制器介紹培訓教程
    • MPLAB®模擬設計器——在線電源解決方案,加速設計
    • 讓您的模擬設計靈感,化為觸手可及的現實
    • 深度體驗Microchip自動輔助駕駛應用方案——2025巡展開啟報名!
    • 貿澤電子(Mouser)專區

    相關視頻

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷