记录DS18B20读取不对的一些小以及解决办法

DS18B20这个温度传感器是非常常见的,起初使用时也没有太在意,拿原子哥的例程直接跑,发现温度也可以读取到。
但是到实际做项目了发现要用好也没有那么容易。
负温度的换算
负温度换算时要加上1,至于为什么,就是二进制有符号数转换的那个取反加1.

    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
		TL =TL+1;//这个加1别忘记
        temp=0;//温度为负  
    }else temp=1;//温度为正	

读取温度会跳变
由于DS18B20有可能不是直接焊接在板子上的,如果线过长就会影响到数据的读取,然后读取到不正常的数,导致温度跳变。这里除了可以用一些滤波算法外,更重要的是对数据的校验。DS18B20就自带了CRC8的校验。
代码如下

int DS18B20_Get_Temp(void)
{
    volatile uint8_t temp;
    volatile uint8_t TL,TH;
    volatile short tem;
	volatile int value,calibration;
	uint8_t tab[9],Crc8;
    DS18B20_Start ();           //开始转换
    DS18B20_Rst();
	//DS18B20_Check();
    if(DS18B20_Check()==1)
		{
			tem = -9999;//-9999,表示传感器故障
			return tem;
		}	 

    DS18B20_Write_Byte(0xcc);   // skip rom
    DS18B20_Write_Byte(0xbe);   // convert	    
    tab[0]=TL=DS18B20_Read_Byte();     // LSB   
    tab[1]=TH=DS18B20_Read_Byte();     // MSB   
		tab[2]=DS18B20_Read_Byte();     // 
		tab[3]=DS18B20_Read_Byte();     // 
		tab[4]=DS18B20_Read_Byte();     // 
		tab[5]=DS18B20_Read_Byte();     // 
		tab[6]=DS18B20_Read_Byte();     // 
		tab[7]=DS18B20_Read_Byte();     // 
		tab[8]=DS18B20_Read_Byte();     // CRC
		Crc8 = DS18B20_Crc(tab,8);
		if(Crc8!=tab[8])  //CRC校验
		{
			return 0x7FFF;
		}
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
		TL =TL+1;
        temp=0;//温度为负  
    }else temp=1;//温度为正	  	  
    tem=TH; //获得高八位
    tem<<=8;    
    tem+=TL;//获得底八位
    tem=((float)tem)*0.625;//转换    

	if(temp)
	{
		value = tem;
	}
	else 
	{
		value = -tem;
	}		
	return value;  
}
uint8_t DS18B20_Crc(uint8_t *addr, uint8_t len)
{
    uint8_t crc = 0, inbyte, i, mix;

    while (len--)
    {
        // inbyte 存储当前参与计算的新字节
        inbyte = *addr++;

        for (i = 8; i; i--) 
        {
            // 将新字节与CRC从低位到高位, 依次做异或运算, 每次运算完CRC右移一位
            // 如果运算结果值为1, 则将CRC与 1000 1100 作异或
            // 第3,4位代表流程图中的异或运算, 第7位其实就是运算结果移入的1
            mix = (crc ^ inbyte) & 0x01;
            crc >>= 1;
            if (mix) 
            {
                crc ^= 0x8C;
            }
            inbyte >>= 1;
        }
    }
    return crc;
}

数据一直读取到FF
这个问题是由于,在配置IO输入时,使用了库函数,尤其是HAL库,这样会导致某些情况下根本IO根本读取不到低电平,所以虽然DS18B20 正确的返回的数据,(用逻辑分析仪或者示波器看波形都是正确的),但是就是读取的都是FF,所以配置输入时最好直接修改寄存器。因为我在调试中一样的程序可能换一批板子就无法读取到了,但是改成寄存器配置就可以读取到,这个目前我也是比较疑惑,猜测是库函数的配置时间过长导致的,有想法的朋友可以一起讨论一下。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值