DS18B20溫度傳感器實現代碼


 
平台: freescale CodeWarrior
MCU:MC9S12G128(汽車級芯片)
 
#include "Ds18b20.h"
 
/************************************************************
*   DS18B20  status initialization
************************************************************/
#pragma MESSAGE DISABLE C12056       //屏蔽警告
INT8U Ds18b20StsInit(void)
{
    INT8U ack = DB_OK;
    INT16U outTime = 500;
   
    //DisableInterrupts       
   
    /* 初始化狀態 */
    BUS_DIR = HIGH;
    BUS     = HIGH;
    DelayUs(8);
   
    /* 拉低BUS,延時500us */
    BUS     = LOW;
    DelayUs(480);
   
    /* BUS上拉,延時15us-60us */
    BUS     = HIGH;
    DelayUs(30);
   
    /* BUS設置為輸入 */
    BUS_DIR = LOW;
   
    /* 等待DS18B20存在脈沖做出回應,0正常,60-240us */
    DelayUs(8);
   
    while(BUS)      
    {
        --outTime;  //超時處理
        if(outTime == 0)
        {
            ack = DB_ERR;
            break;
        }
    }
    /* 等待DS18B20恢復穩定 */     
    DelayUs(128);
   
    /* BUS上拉 */
    BUS_DIR = HIGH;
    BUS     = HIGH;
    DelayUs(280);
   
    //EnableInterrupts       
    return (ack);
}
 
 
 
/************************************************************
*   Write data to ds18b20
************************************************************/
PRIVATE void Ds18b20WriteData(INT8U cmd)
{
    INT8U i;
   
    DisableInterrupts   
    for(i = 0; i < 8; i++)
    {
        //BUS = LOW;                  //HIGH->LOW 啟動寫時序
        //Tim_Delay8Us(2);
               
        if(cmd & 0x01)              //從低位開始發送數據,15us完成
        {       
            BUS = 0;                //寫1時序
            DelayUs(5);
            BUS = 1;                       
        }
        else
        {
            BUS = 0;                //寫0時序 
            DelayUs(5);
        }
        DelayUs(60);                //等待從器件采集數據
 
        BUS = HIGH;                  //拉高總線,起始狀態
        DelayUs(8);       
        cmd >>= 0x01;                      
    }
    EnableInterrupts   
}
 
 
#if 1
/************************************************************
*   Read data from ds18b20
************************************************************/
PRIVATE INT8U Ds18b20ReadData(void)
{
    INT8U i;
    INT8U data = 0x00;
 
       
    BUS = HIGH;
    DelayUs(8);
   
    DisableInterrupts      
    for(i = 0; i < 8; i++)
    {
        data >>= 0x01;
 
        BUS = LOW;                  //拉低總線,進行讀時序操作
        DelayUs(8);
 
        BUS = HIGH;                 //拉低總線,進行讀時序操作
        DelayUs(8);
       
        BUS_DIR = LOW;              //配置為輸入
        asm("nop");
        //Tim_Delay8Us(1);
        if(BUS)
        {  
            data |= 0x80;
        }
        DelayUs(60);                //等待數據讀緩存 
       
        BUS_DIR = HIGH;
        BUS = HIGH;
        DelayUs(8);                         
    }
    EnableInterrupts 
     
    return (data);
}
#endif
 
 
INT8U Dt = 0, Dt1 = 0;
 
/************************************************************
*   Get data from ds18b20
************************************************************/
INT16U Ds18b20GetTemperature(void)
{
    INT16U data = CLEAR;
    INT8U temp[2] = {0};
   
    Dt = Ds18b20StsInit();   
    Ds18b20WriteData(0xcc);             //跳過rom命令
    Ds18b20WriteData(0x44);             //啟動溫度轉換
       
    Dt1 = Ds18b20StsInit();
    Ds18b20WriteData(0xcc);             //跳過rom命令
    Ds18b20WriteData(0xbe);             //讀暫存寄存器
   
    temp[0] = Ds18b20ReadData();
    temp[1] = Ds18b20ReadData();
    data = (temp[1] << 8) | temp[0];  
          
    return (data);
}
 
 
 
調試DS18B20遇到采集數據不穩定情況:
  不穩定現象:每讀到幾個正常數據后會有幾個不正常的數據
  不穩定原因:因為中斷在打斷我數據的讀寫以及采集
  解決辦法:因為DS18B20單總線讀寫時對時序要求很嚴格,每次讀寫時關閉中斷即可得到穩定數據。
 
 
 
 
 
               


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM