日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

DS18B20 測(cè)溫程序完全解讀

 ccbupt 2009-09-09

DS18B20 測(cè)溫程序完全解讀

 

硬件: 51板
    (1)單線ds18b20接 P2.2
    (2)使用外部電源給ds18b20供電,沒有使用寄生電源奧
軟件:
     Kei uVision 2
    剛開始對(duì)時(shí)序把握不好,可是在論壇里沒找到比較詳細(xì)的解釋,所以俺倒塌了這個(gè)東東,就把俺的經(jīng)驗(yàn)貼上來,供大家參考,呵呵……
    如有錯(cuò)誤請(qǐng)指正

#include "reg52.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^2;
sbit dula=P2^6;
sbit wela=P2^7;
uchar flag ;
uint temp;               //參數(shù)temp一定要聲明為 int 型
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};     //不帶小數(shù)點(diǎn)數(shù)字編碼

uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef};        //帶小數(shù)點(diǎn)數(shù)字編碼

/*延時(shí)函數(shù)*/
void TempDelay (uchar us)
{
   while(us--);
}

void delay(uint count) //延時(shí)子函數(shù)
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}

/*串口初始化,波特率9600,方式1 */
void init_com()
{
   TMOD=0x20;      //設(shè)置定時(shí)器1為模式2
   TH1=0xfd;       //裝初值設(shè)定波特率
   TL1=0xfd;
   TR1=1;          //啟動(dòng)定時(shí)器
   SM0=0;          //串口通信模式設(shè)置
   SM1=1;
// REN=1;          //串口允許接收數(shù)據(jù)
   CON=0;         //波特率不倍頻
//  SMOD=0;       //波特率不倍頻
  // EA=1;          //開總中斷
  //ES=1;          //開串行中斷
}

/*數(shù)碼管的顯示 */
void display(uint temp)
{
    uchar bai,shi,ge;
    bai=temp/100;
    shi=temp%100/10;
    ge=temp%100%10;

dula=0;
    0=table[bai];  //顯示百位
dula=1;         //從0到1,有個(gè)上升沿,解除鎖存,顯示相應(yīng)段
dula=0;         //從1到0再次鎖存
          
    wela=0;
    0=0xfe;
wela=1;
wela=0;
delay(1);    //延時(shí)約2ms

P0=table1[shi];  //顯示十位
dula=1;
    dula=0;
    
P0=0xfd;
wela=1;
    wela=0;
    delay(1);

    0=table[ge];  //顯示個(gè)位
dula=1;
    dula=0;
    
P0=0xfb;
wela=1;
    wela=0;
    delay(1);
}
/*****************************************
時(shí)序:初始化時(shí)序、讀時(shí)序、寫時(shí)序。
所有時(shí)序都是將主機(jī)(單片機(jī))作為主設(shè)備,單總
線器件作為從設(shè)備。而每一次命令和數(shù)據(jù)的傳輸
都是從主機(jī)主動(dòng)啟動(dòng)寫時(shí)序開始,如果要求單總
線器件回送數(shù)據(jù),在進(jìn)行寫命令后,主機(jī)需啟動(dòng)
讀時(shí)序完成數(shù)據(jù)接收。數(shù)據(jù)和命令的傳輸都是低
位在先。  
初始化時(shí)序:復(fù)位脈沖 存在脈沖
        讀;1 或 0時(shí)序
        寫;1 或 0時(shí)序
只有存在脈沖信號(hào)是從18b20(從機(jī))發(fā)出的,其
它信號(hào)都是由主機(jī)發(fā)出的。
存在脈沖:讓主機(jī)(總線)知道從機(jī)(18b20)已
經(jīng)做好了準(zhǔn)備。
******************************************/


/*--------------------------------------------------------------------------------------------------------------------
初始化:檢測(cè)總線控制器發(fā)出的復(fù)位脈沖
和ds18b20的任何通訊都要從初始化開始

初始化序列包括一個(gè)由總線控制器發(fā)出的復(fù)位脈沖
和跟在其后由從機(jī)發(fā)出的存在脈沖。

初始化:復(fù)位脈沖+存在脈沖

具體操作:
  總線控制器發(fā)出(TX)一個(gè)復(fù)位脈沖 (一個(gè)最少保持480μs 的低電平信號(hào)),然后釋放總線,
進(jìn)入接收狀態(tài)(RX)。單線總線由5K 上拉電阻拉到高電平。探測(cè)到I/O 引腳上的上升沿后
DS1820 等待15~60μs,然后發(fā)出存在脈沖(一個(gè)60~240μs 的低電平信號(hào))。

  具體看"倒塌 18b20"文檔里的 " 單線復(fù)位脈沖時(shí)序和1-wire presence detect "的時(shí)序圖
-------------------------------------------------------------------------------------------------------------------*/
void ds_reset(void)
{
   ds=1;
   _nop_();        //1us
   ds=0;
   TempDelay(80);  //當(dāng)總線停留在低電平超過480us,總線上所以器件都將被復(fù)位,這里//延時(shí)約530us總線停留在低電平超過480μs,總線上的所有器件都
//將被復(fù)位。
   _nop_();
   ds=1;           //產(chǎn)生復(fù)位脈沖后,微處理器釋放總線,讓總線處于空閑狀態(tài),原因查//18b20中文資料

   TempDelay(5);  //釋放總線后,以便從機(jī)18b20通過拉低總線來指示其是否在線,
                  //存在檢測(cè)高電平時(shí)間:15~60us, 所以延時(shí)44us,進(jìn)行            1-wire presence //detect(單線存在檢測(cè))
   _nop_();
   _nop_();
   _nop_();
   if(ds==0)
        flag=1;       //detect 18b20 success
   else
        flag=0;       //detect 18b20 fail
  TempDelay(20);    //存在檢測(cè)低電平時(shí)間:60~240us,所以延時(shí)約140us
   _nop_();
   _nop_();
   ds=1;          //再次拉高總線,讓總線處于空閑狀態(tài)
/**/
}

/*----------------------------------------
讀/寫時(shí)間隙:
DS1820 的數(shù)據(jù)讀寫是通過時(shí)間隙處理
位和命令字來確認(rèn)信息交換。
------------------------------------------*/
bit  ds_read_bit(void)    //讀一位
{
   bit dat;
   ds=0;         //單片機(jī)(微處理器)將總線拉低
  _nop_();       //讀時(shí)隙起始于微處理器將總線拉低至少1us
   ds=1;        //拉低總線后接著釋放總線,讓從機(jī)18b20能夠接管總線,輸出有效數(shù)據(jù)
   _nop_();
   _nop_();          //小延時(shí)一下,讀取18b20上的數(shù)據(jù) ,因?yàn)閺膁s18b20上輸出的數(shù)據(jù)
//在讀"時(shí)間隙"下降沿出現(xiàn)15us內(nèi)有效
   dat=ds;           //主機(jī)讀從機(jī)18b20輸出的數(shù)據(jù),這些數(shù)據(jù)在讀時(shí)隙的下降沿出現(xiàn)//15us內(nèi)有效
   TempDelay(10);    //所有讀"時(shí)間隙"必須60~120us,這里77us
   return(dat);       //返回有效數(shù)據(jù)
}
uchar ds_read_byte(void ) //讀一字節(jié)
{

uchar value,i,j;
value=0;           //一定別忘了給初值
for(i=0;i<8;i++)
{
    j=ds_read_bit();
     value=(j<<7)|(value>>1);   //這一步的說明在一個(gè)word文檔里面
}
return(value);        //返回一個(gè)字節(jié)的數(shù)據(jù)
}
void ds_write_byte(uchar dat) //寫一個(gè)字節(jié)
{
  uchar i;
  bit onebit;        //一定不要忘了,onebit是一位
  for(i=1;i<=8;i++)
  {
    onebit=dat&0x01;
    dat=dat>>1;
if(onebit)      //寫 1
{
ds=0;
_nop_();    
      _nop_();      //看時(shí)序圖,至少延時(shí)1us,才產(chǎn)生寫"時(shí)間隙"  
ds=1;       //寫時(shí)間隙開始后的15μs內(nèi)允許數(shù)據(jù)線拉到高電平
     TempDelay(5);  //所有寫時(shí)間隙必須最少持續(xù)60us
}
else         //寫 0
{
ds=0;
     TempDelay(8);    //主機(jī)要生成一個(gè)寫0 時(shí)間隙,必須把數(shù)據(jù)線拉到低電平并保持至少60μs,這里64us
ds=1;
_nop_();
     _nop_();
}
  }
}

/*****************************************
主機(jī)(單片機(jī))控制18B20完成溫度轉(zhuǎn)換要經(jīng)過三個(gè)步驟:
每一次讀寫之前都要18B20進(jìn)行復(fù)位操作,復(fù)位成功后發(fā)送
一條ROM指令,最后發(fā)送RAM指令,這樣才能對(duì)DS18b20進(jìn)行
預(yù)定的操作。
復(fù)位要求主CPU將數(shù)據(jù)線下拉500us,然后釋放,當(dāng)ds18B20
受到信號(hào)后等待16~60us,后發(fā)出60~240us的存在低脈沖,
主CPU收到此信號(hào)表示復(fù)位成功
******************************************/

/*----------------------------------------
進(jìn)行溫度轉(zhuǎn)換:
先初始化
然后跳過ROM:跳過64位ROM地址,直接向ds18B20發(fā)溫度轉(zhuǎn)換命令,適合單片工作
發(fā)送溫度轉(zhuǎn)換命令
------------------------------------------*/

void tem_change()
{
  ds_reset();
  delay(1);              //約2ms
  ds_write_byte(0xcc);
  ds_write_byte(0x44);
}

/*----------------------------------------
獲得溫度:
------------------------------------------*/
uint get_temperature()
{
  float wendu;
  uchar a,b;
  ds_reset();
  delay(1);              //約2ms
  ds_write_byte(0xcc);
  ds_write_byte(0xbe);
  a=ds_read_byte();
  b=ds_read_byte();
  temp=b;
  temp<<=8;
  temp=temp|a;
  wendu=temp*0.0625;     //溫度讀取的解釋我記錄在 "倒塌 18B20"里面
  temp=wendu*10+0.5;
  return temp;
}
/*----------------------------------------
讀ROM   
------------------------------------------*/
/*
void ds_read_rom()                  //這里沒有用到
{
   uchar a,b;
   ds_reset();
   delay(30);
   ds_write_byte(0x33);
   a=ds_read_byte();
   b=ds_read_byte();
}
*/
void main()
{
   uint a;
   init_com();
   while(1)
   {
tem_change();          //12位轉(zhuǎn)換時(shí)間最大為750ms
for(a=10;a>0;a--)
{
display( get_temperature());
}
   }
}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多