[51单片机]18b20驱动函数

/**********DS18B20.h**********/
#include "REG52.H"
#include "INTRINS.H"
sbit DQ = P3^3; //DS18B20的数据口位P3.3
extern unsigned char TPH;//    温度高位
extern unsigned char TPL;//    温度低位
extern unsigned char * DS18B20_GetTP();// 刷新温度值(2xx为-xx)
/**********DS18B20.c**********/
#include <DS18B20.h>
typedef unsigned char BYTE;
 
BYTE TPH;                           //存放温度值的高字节
BYTE TPL;                           //存放温度值的低字节
 
void DelayXus(BYTE n);
void DS18B20_Reset();
void DS18B20_WriteByte(BYTE dat);
BYTE DS18B20_ReadByte();
 
BYTE* DS18B20_GetTP()
{
    BYTE TEMP[]="000C\n";
    unsigned int temp;
    signed int t;
    BYTE bai,shi,ge,shifen;
    DS18B20_Reset();                //设备复位
    DS18B20_WriteByte(0xCC);        //跳过ROM命令
    DS18B20_WriteByte(0x44);        //开始转换命令
    while (!DQ);                    //等待转换完成
 
    DS18B20_Reset();                //设备复位
    DS18B20_WriteByte(0xCC);        //跳过ROM命令
    DS18B20_WriteByte(0xBE);        //读暂存存储器命令
    TPL = DS18B20_ReadByte();       //读温度低字节
    TPH = DS18B20_ReadByte();       //读温度高字节      
        
    t=TPH<<8;
    t=t|TPL;
    if(t<0) temp=(~t+1)*0.0625*10+0.5; //负温度时,取反加1再乘以0.0625得实际温度,乘10+0.5显示小数点一位,且四舍五入
        else temp=t*0.0625*10+0.5;     //正温度
    if(t<0) bai='-'-48;                //负温度时百位显示负号
        else bai=(const) temp/1000;
    if(bai) TEMP[0]=bai+48; else TEMP[0]=' ';        //百位
    shi=((const) temp%1000)/100; TEMP[1]=shi+48;    //十位
    ge=((const) temp%1000)%100/10; TEMP[2]=ge+48;   //个位
    shifen=((const) temp%1000)%100%10;              //十分位   
        
    return  TEMP;
}
 
/**************************************
延时X*10微秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数
当改用1T的MCU时,请调整此延时函数
**************************************/
void DelayX0us(BYTE n)
{
    while (n--)
    {
        _nop_();
        _nop_();
    }
}
 
/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
void DS18B20_Reset()
{
    CY = 1;
    while (CY)
    {
        DQ = 0;                     //送出低电平复位信号
        DelayX0us(48);              //延时至少480us
        DQ = 1;                     //释放数据线
        DelayX0us(6);               //等待60us
        CY = DQ;                    //检测存在脉冲
        DelayX0us(42);              //等待设备释放数据线
    }
}
 
/**************************************
从DS18B20读1字节数据
**************************************/
BYTE DS18B20_ReadByte()
{
    BYTE i;
    BYTE dat = 0;
 
    for (i=0; i<8; i++)             //8位计数器
    {
        dat >>= 1;
        DQ = 0;                     //开始时间片
        _nop_();                    //延时等待
        _nop_();
        DQ = 1;                     //准备接收
        _nop_();                    //接收延时
        _nop_();
        if (DQ) dat |= 0x80;        //读取数据
        DelayX0us(6);               //等待时间片结束
    }
 
    return dat;
}
 
/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(BYTE dat)
{
    char i;
 
    for (i=0; i<8; i++)             //8位计数器
    {
        DQ = 0;                     //开始时间片
        _nop_();                    //延时等待
        _nop_();
        dat >>= 1;                  //送出数据
        DQ = CY;
        DelayX0us(6);               //等待时间片结束
        DQ = 1;                     //恢复数据线
    }
}
原文地址:https://www.cnblogs.com/catmelo/p/2415161.html