色偷偷偷久久伊人大杳蕉,色爽交视频免费观看,欧美扒开腿做爽爽爽a片,欧美孕交alscan巨交xxx,日日碰狠狠躁久久躁蜜桃

x
x

51單片機-溫度傳感器DS18B20

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

DS18B20的三種封裝:  


   
DS18B20的內(nèi)部結(jié)構(gòu):  


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

DS18B20的復(fù)位時序:  


   
DS18B20復(fù)位,確定其存在:     #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;                        //數(shù)據(jù)線拉高,系統(tǒng)將總線放開,并進入接受狀態(tài)
          i=4;
          while(i>0)i--;        //延時等待,若初始化成功則在15"60ms內(nèi)產(chǎn)生一個由
        if(DQ == 0){        //DS18B20在檢測到總線的上升沿后,等待15"60ms,接著
                while(DQ == 0); //在T2時刻發(fā)出存在脈沖(低電平)
                bell = 0;
        }
        else
                bell = 1;        
}

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






   



DS18B20的寫0和寫1時序:







DS18B20的讀數(shù)據(jù)時序:










讀出光刻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;                    //傳數(shù)據(jù)
    delay(14);                //看時序圖,數(shù)據(jù)需要穩(wěn)定一段時間
    E = 1;                            //給一個高脈沖,發(fā)送命令
    delay(14);                    //如圖,高脈沖延時一段時間,確保命令發(fā)送
    E = 0;                            //發(fā)送結(jié)束E置為低電平
}

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

void init_lcd(){
    RS = 1;         //先發(fā)指令,在初始時刻RS是高,E和RW是低
    E = 0;
    RW = 0;
    lcd_com(0x38);           //設(shè)置為16*2顯示,5*7點陣,8位數(shù)據(jù)接口
    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;                        //數(shù)據(jù)線拉高
          i=4;
          while(i>0)i--;        //延時等待,若初始化成功則在15"60ms內(nèi)產(chǎn)生一個由
        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時刻將總線拉高,產(chǎn)生讀時間隙
                        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從高拉低產(chǎn)生寫時隙,
                delay(5);        
                DQ = Value & 0x01;   //必須在t0開始的15us內(nèi)將數(shù)據(jù)送到總線上
                delay(20);           //DS18B20在t0后的15us"60us內(nèi)對總線采樣
                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并聯(lián)工作流程:

  



  DS18B20溫度存儲格式:

  



  DS18B20暫存器的分布:

  



  DS18B20內(nèi)部ROM指令:

  



  DS18B20內(nèi)部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;                    //傳數(shù)據(jù)
    delay(14);                //看時序圖,數(shù)據(jù)需要穩(wěn)定一段時間
    E = 1;                            //給一個高脈沖,發(fā)送命令
    delay(14);                    //如圖,高脈沖延時一段時間,確保命令發(fā)送
    E = 0;                            //發(fā)送結(jié)束E置為低電平
}

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

void Init_Lcd(){
    RS = 1;         //先發(fā)指令,在初始時刻RS是高,E和RW是低
    E = 0;
    RW = 0;
    Lcd_Com(0x38);           //設(shè)置為16*2顯示,5*7點陣,8位數(shù)據(jù)接口
    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;                        //數(shù)據(jù)線拉高
          i=4;
          while(i>0)i--;        //延時等待,若初始化成功則在15"60ms內(nèi)產(chǎn)生一個由
        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();                        //復(fù)位
        DS18B20_Write(0x0cc);                //跳過ROM,只有一個所以跳過
        DS18B20_Write(0x44);                //開始溫度轉(zhuǎn)換
        DS18B20_Reset();                        //復(fù)位
        DS18B20_Write(0x0cc);                //跳過ROM
        DS18B20_Write(0x0be);                //讀暫存器
        temp_l = DS18B20_Read();        //讀出溫度低8位
        temp_h = DS18B20_Read();        //讀出溫度高8位
        temp_l >>= 4;                                //去掉4位小數(shù)位
        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://m.54549.cn/thread-59318-1-1.html     【打印本頁】

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

相關(guān)視頻

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表