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单总线读写时对时序要求很严格,每次读写时关闭中断即可得到稳定数据。
 
 
 
 
 
               

猜你喜欢

转载自www.cnblogs.com/ownDefine/p/10802080.html