DS18B20温度传感源代码

来源:互联网 发布:淘宝企业店铺贷款条件 编辑:程序博客网 时间:2024/04/28 06:11
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char


sbit DQ = P1^4;                    //ds18b20数据通信口
sbit SEGLE = P1^0;                //数码管段选锁存控制端口
sbit DIGLE = P1^1;                 //位选


uchar code Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};   //      0~9不带点数码管字段
//uchar code Tab_D[10] = {0xbf,0x86,0xdb,0xcf,0xe6,
  //                      0xed,0xfd,0x87,0xff,0xef};     //0~9带小数点数码管
uchar code Tab_D[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};           //0~7数码管位选

bit g_bt_index = 1;        //最终温度读数的符号标志位
uchar  Temp_Value0,Temp_Value1;     //从DS18B20 读取温度值

void Delay()//延迟2
{
    uchar i,j;
    for(i = 100;i > 0;i--)
        for(j = 15;j > 0;j--);
}

void Delayus(uchar t)
{    
    while(t--) {};
}
uchar Init_DS18B20()//初始化DS8Button0
{
    bit status;
    DQ = 1;
    Delayus(0);
    DQ = 0;
    Delayus(160);
    _nop_();
    DQ = 1;

    Delayus(10);
    status = DQ;
    Delayus(20);

    return status;
}

bit ReadBit()
{
    bit dat;
    DQ = 1;                    //先将数据线拉高
    _nop_();
    _nop_();                //延时1us等待
    DQ = 0;                    //当数据线从高拉低时,读时序开始
    _nop_();
    _nop_();                //数据线必须至少保持1us,然后总线被释放

    DQ = 1;                    //人为拉高,释放数据线,让18b20接管数据总线
    Delayus(0);                //延时5us,在下降沿出现的15us内读取有效
    dat = DQ;                //主机从18b20读取数据

    Delayus(20);            //延时约65us,所有读"时间隙"必须60~120us,

    return dat;                //返回读取数据
}

/************************************************
*        *函数名:ReadByte()
*        *函数功能:读一字节函数
*        *全局变量:无
*        *调用函数:ReadBit();
*        *传入参数:无
*************************************************/
uchar ReadOneByte()
{
    uchar i,j,value;
    for(i = 0;i < 8;i++)
    {
        j = ReadBit();
        value=(j<<7)|(value>>1);     //读写数据都是从低位到高位,先将读取的数
                                    //存在value最高位,value依次右移
    }

    return value;
}

void WriteOneByte(uchar dat) //写一个数据
{
    uchar i;
    for(i = 0;i < 8;i++)
    {
          DQ = dat & 0x01;
          dat >>= 1;
          if(DQ)
          {
              DQ = 1;
            _nop_();
              DQ = 0;
            
            DQ = 1;
            //_nop_();
            Delayus(0);

            Delayus(5);
          }
          else
          {
              DQ = 1;
            _nop_();
              DQ = 0;

            Delayus(5);
            DQ = 1;
          }    
    }
}

void Read_Temperature()//读数据
{

         Init_DS18B20();
         WriteOneByte(0xcc);          //跳过序列号
        WriteOneByte(0x44);           //启动温度转换
        Init_DS18B20();               //复位
        WriteOneByte(0xcc);
        WriteOneByte(0xbe);             //读取
        Temp_Value0 = ReadOneByte();      //温度低8位
        Temp_Value1 = ReadOneByte();      //高8位        
}

uint Display_Temperature()
{
    float Temp;                     //定义float型存储温度变量
    uint tmp;                    

    if((Temp_Value1 & 0xf8) == 0xf8) //字节高5位,如果全为1则为负数,为负取反加一
    {
        Temp_Value1 = ~Temp_Value1;
        Temp_Value0 = ~Temp_Value0 + 1;
        if(Temp_Value0 == 0x00)
        {
            Temp_Value1++;
        }        
    }

    tmp = Temp_Value1;
    tmp = (tmp << 8)|Temp_Value0;     //高八位左移八位,在 | 低八位    

    Temp = tmp * 0.0625;            //转换精度默认为为0.0625/LSB
    tmp = Temp * 100 + 0.5;         //保留两位小数并第三位小数四舍五入

    return tmp;
}

void Display(uint tmp)
{
    uchar i;
    uint Num[5];
    if(!g_bt_index)                          // 负数标志
        Num[0] = 16;                  
    else
        Num[0] = tmp / 10000;             //正数百位,负数符号位
    Num[1] = tmp % 10000 / 1000;         //十位
    Num[2] = tmp % 1000 / 100;             //个位
    Num[3] = tmp % 100 / 10;             //小数点后一位
    Num[4] = tmp % 10;                     //小数点后二位
    
    for(i = 0;i < 5;i++)
    {
        P0 = Tab_D[i + 3];                 //共八位数码管,五位字符,
        DIGLE = 1;                          //从数码管第三位开始显示
        DIGLE = 0;
        
        if(i == 2)                         //段选,如果是字符第三位(个位),后加小数点
            P0 = Tab[Num[i]] + 0x80;
        else
            P0 = Tab[Num[i]];
        SEGLE = 1;
        SEGLE = 0;
        Delay();                          //延时
    }    
}

void main()
{    
    while(1)
    {
        Read_Temperature();
        Display(Display_Temperature());
    }

}

0 0
原创粉丝点击