国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

51單片機-溫度傳感器DS18B20

發布時間:2011-3-22 11:37    發布者:techshare
溫度傳感器是各種傳感器中最常用的一種,早期使用的是模擬溫度傳感器,如熱敏電阻,隨著環境溫度的變化,它的阻值也發生線性變化,用處理器采集電阻兩端的電壓,然后根據某個公式就可以計算出當前環境溫度。美國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.qingdxww.cn/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視頻專區
  • 無線充電基礎知識及應用培訓教程2
  • 基于CEC1712實現的處理器SPI FLASH固件安全彈性方案培訓教程
  • PIC18-Q71系列MCU概述
  • 想要避免發生災難,就用MPLAB® SiC電源仿真器!
  • 貿澤電子(Mouser)專區

相關視頻

關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
快速回復 返回頂部 返回列表
主站蜘蛛池模板: 四虎永久免费网站 | 国产精品久久久久有声小说 | 日本精品中文字幕在线播放 | 色视频在线网站 | 日韩精品一区二区三区 在线观看 | 久久99国产乱子伦精品免费 | 99久久精品免费看国产四区 | 高清在线精品一区二区 | 五月婷色 | 好吊日在线观看 | 国产综合色香蕉精品五月婷 | 91手机在线 | 日本最新新片在线观看免费 | 日本亚洲精品成人 | 香焦伊人 | 啦啦啦资源视频在线观看4 啦啦啦中文在线影院观看 啦啦啦在线观看视频免费观看4 | 亚洲欧美成人中文在线网站 | 国产欧美一区二区三区精品 | 91成人国产福利 | 韩国福利一区二区三区高清视频 | 日本亚洲高清乱码中文在线观看 | 伊人日日夜夜 | 自拍偷拍欧美 | 日韩国产成人精品视频人 | 青青青免费高清视频在线 | 99久久好看一级毛片 | 亚洲国产欧美日韩 | 亚洲干综合 | 欧美一级特黄特黄做受 | 99精品热视频| 午夜秒播 | 九九老司机在线视频精品 | 亚洲精品视频区 | 羞羞人成午夜爽爽影院 | 日本亚洲综合 | 国产一级特黄a大片99 | 精品国产网站 | 国产精品一级香蕉一区 | 夜夜爽天天狠狠九月婷婷 | 国产麻豆91欧美一区二区 | 羞羞网站在线看 |