读取温度传感器DS18B20的实例

配置IO引脚

#define DS18B20         BIT4                      //配置IO引脚
#define DS18B20_HIGH    P2OUT |= BIT4
#define DS18B20_LOW     P2OUT &= ~BIT4

精确延时宏代码

#define CPU_CLOCK       8000000UL               //MCLK设为8MHz                
#define delay_us(us)    __delay_cycles(CPU_CLOCK/1000000*(us))
#define delay_ms(ms)    __delay_cycles(CPU_CLOCK/1000*(ms))

求二进制小数部分的查表

const int N16Tab[16]={      //用于求二进制小数部分查表
    0,
    625,
    1250,
    1875,
    2500,
    3125,
    3750,
    4375,
    5000,
    5625,
    6250,
    6875,
    7500,
    8125,
    8750,
    9375
};

复位

/*
**********************************************************************
* 名  称:DS18B20_init()
* 功  能:复位DS18B20
* 入口参数:无
* 出口参数:1--存在,0--不存在
* 说  明:需要配置IO,软件延时要准确
* 范  例:无
**********************************************************************
*/
char DS18B20_Reset(void)
{
        int i;
        char e;
        //-------拉低-----------------------------------   
        P2DIR |= DS18B20;                       //配置为输出
        DS18B20_LOW;                            //拉低

        //-------等待480微秒以上----------------------------
        delay_us(540);          //只少等待480微秒以上

        //-------拉高-----------------------------------
        P2DIR &= ~DS18B20;                      //配置为输入
        P2REN |=DS18B20;                        //启用电阻
        DS18B20_HIGH;                           //上拉

        //-------等待15微秒---------------------------------
        delay_us(15);

        //-------检测存在-------------------------------------------
        i=0;
        e=0;
        while(1)
        {
            if((P2IN & DS18B20)==0)
            {   
                e=1;
                break; 
            }
            delay_us(1);
            i++;
            if(i>60)
            {
                break;   
            }
        }

        //------------延时480微秒以上---------------------------------
        delay_us(500);
        return e;
} 

读字节

/*
**********************************************************************
* 名  称:DS18B20_ReadByte()
* 功  能:读位字
* 入口参数:无
* 出口参数:返回从DS18B20读回的一个字节
* 说  明:需要配置IO,软件延时要准确
* 范  例:无
**********************************************************************
*/
unsigned char DS18B20_ReadByte(void)
{
    unsigned char i,retd=0;
    for(i=0;i<8;i++)            //位计数值
    {
        retd>>=1;               //右移,准备接受新的数据位

        //-------拉低总线5微秒--------------------------
        P2DIR |=DS18B20;        //配置为输出
        DS18B20_LOW;            //拉低,启动读数据位
        delay_us(5);        //等待5微秒

        //-------释放总线-----------------------------------
        P2DIR &= ~DS18B20;      //配置为输入
        P2REN |=DS18B20;        //启用电阻
        DS18B20_HIGH;           //上拉

        //-------等待15微秒-----------------------------
        delay_us(15);       //等待15微秒

        //-------检查该位是否为高-----------------------
        if(P2IN&DS18B20)        //该位是否为高
        {
            retd|=0x80;     //是就将此位置高
        }

        //-------等待42微秒-----------------------------
        delay_us(42);       //等待42微秒
    }
    return retd;                //将读到的一个字节返回
}

写字节

/*
**********************************************************************
* 名  称:DS18B20_WriteByte()
* 功  能:写字节
* 入口参数:无
* 出口参数:无
* 说  明:需要配置IO,软件延时要准确
* 范  例:无
**********************************************************************
*/
void DS18B20_WriteByte(unsigned char wrd)
{
    unsigned char i;

    for(i=0;i<8;i++)            //位计数值
    {
        if(wrd&0x01)            //此位数据是否为高
        {
              //-------拉低总线5微秒--------------------------
              P2DIR |=DS18B20;        //配置为输出
              DS18B20_LOW;  
              delay_us(5);

              //-------拉高总线60微秒----------------------------------
              P2DIR &= ~DS18B20;//配置为输入
              P2REN |=DS18B20;  //启用电阻
              DS18B20_HIGH;     //上拉
              delay_us(60);
        }
        else
        {
              //-------拉低总线60微秒----------------------------------
              P2DIR |=DS18B20;  //配置为输出
              DS18B20_LOW;      //是低则将单总线拉低
              delay_us(60);

              //-------拉高总线5微秒-----------------------------------
              P2DIR &= ~DS18B20;//配置为输入
              P2REN |=DS18B20;  //启用电阻
              DS18B20_HIGH;     //上拉
              delay_us(5);
        }


        //-------等待1微秒以上-------------------------------
        delay_us(2);

        //-------右移1位-------------------------------------
        wrd>>=1;                //右移,为写入新的数据位做准备
    }

}

读温度

一次完整的读温度流程.

/*
**********************************************************************
* 名  称:DS18B20_ReadTemp()
* 功  能:读温度
* 入口参数:无
* 出口参数:返回温度值
* 说  明:需要配置IO,软件延时要准确
* 范  例:无
**********************************************************************
*/
char e;
int DS18B20_ReadTemp()
{
    unsigned char buff[9];
    unsigned char i;
    //unsigned char a,b,c;

    //------MCLK设置为8MHz------------
    DCOCTL=CALDCO_8MHZ;
    BCSCTL1=CALBC1_8MHZ;

    e=DS18B20_Reset();          //初始化,每次写命令都从初始化开始
    DS18B20_WriteByte(0xcc);        //跳过ROM
    DS18B20_WriteByte(0x44);        //启动温度转换
    delay_ms(750);                  //延时750us
    e=DS18B20_Reset();              //初始化,每次写命令都从初始化开始
    DS18B20_WriteByte(0xcc);        //跳过ROM

    DS18B20_WriteByte(0xbe);        //送读寄存器命令

    //-----连续读入9个-----------------
    for(i=0;i<9;i++)
    {
        buff[i]=DS18B20_ReadByte();   //读寄存器
    }

    /*
    //---------计算温度----------------------------------------------------
    a=buff[0]&0x0f;
    if((buff[1]&0x80) != 0)
    {
            a=~a;
            a=a&0x0f;
            a+=1;
    }
    *fDat=N16Tab[a];      //得到小数部分

    b=buff[0]>>4;
    c=buff[1]<<4;
    c|=b;
    *iDat=c;              //得到整数部分
    */

    //-----MCLK设置为1MHz-----------
    DCOCTL=CALDCO_1MHZ;
    BCSCTL1=CALBC1_1MHZ;

    return ((int*)buff)[0];
}

计算温度值

由二进制数据,得到整数部分iDat,小数部分fDat.

void Calc_Temp(int Hex,char *iDat,int *fDat)
{
    unsigned char a,b,c;
    char hi,lo;
    lo=Hex;
    hi=Hex>>8;
    //---------计算温度----------------------------------------------------
    a=lo&0x0f;
    if((hi&0x80) != 0)
    {
        a=~a;
        a=a&0x0f;
        a+=1;
    }
    *fDat=N16Tab[a];      //得到小数部分

    b=lo>>4;
    c=hi<<4;
    c|=b;
    *iDat=c;              //得到整数部分
}

你可能感兴趣的:(MSP430)