ds18b20遇到的坑
最近在搞防水的ds18b20传感器驱动代码,本想着参考原子哥的代码移植一下,不料却遇到了一些棘手的问题,程序读出来的温度一直为0xff,温度读取错误;将传感器直接放在原子哥的stm32开发板子上也读出也是0xff;顿时有点怀疑传感器是不是坏了,然后又换了一个还是这样,所以就开始重新研究一下这个传感器了。
网上搜ds18b20的数据手册,如下为ds18b20的时序图,和时序时间参考表(时序参考表一直上传失败,就不贴了)
第一个时序为写1的时序为低电平持续tlow1(1~15us),高电平持续tslot-trec-tlow1(58~105us)
第二个时序为写0的时序为低电平持续tlow0(60~120us),高电平持续trec(>1us)
第三个时序为读0的时序为低电平持续trdv(<15us),高电平持续tslot-trdv(60~105us)
第四个时序为复位的时序trstl(>480us),trsth(>480us)
第五个时序为传感器检测的时序,在复位被拉高后,需要拉高tpdhigh(15~60us),再拉低tpdlow(60>240us)
接下来看程序源码,原子哥写1和写0的时序为
if (testb)
{
DS18B20_DQ_OUT=0;// Write 1
delay_us(2);
DS18B20_DQ_OUT=1;
delay_us(60);
}
else
{
DS18B20_DQ_OUT=0;// Write 0
delay_us(60);
DS18B20_DQ_OUT=1;
delay_us(2);
}
我这里按照推荐改为10us和80us,烧录程序发现仍然读出0xff.然后继续查找读的函数,
u8 DS18B20_Read_Bit(void) // read one bit
{
u8 data;
DS18B20_IO_OUT();//SET PG11 OUTPUT
DS18B20_DQ_OUT=0;
delay_us(2);
DS18B20_DQ_OUT=1;
DS18B20_IO_IN();//SET PG11 INPUT
delay_us(12);
if(DS18B20_DQ_IN)data=1;
else data=0;
delay_us(50);
return data;
}
并查看数据手册读的操作,
The host generates read time slots when data is to be read from the DS18B20. A read time slot is initiated
when the host pulls the data line from a logic high level to logic low level. The data line must remain at a
low logic level for a minimum of 1 µs; output data from the DS18B20 is valid for 15 µs after the falling
edge of the read time slot. The host therefore must stop driving the DQ pin low in order to read its state
15 µs from the start of the read slot (see Figure 12). By the end of the read time slot, the DQ pin will pull
back high via the external pullup resistor. All read time slots must be a minimum of 60 µs in duration
with a minimum of a 1-µs recovery time between individual read slots.
大体意思就是当主机将数据线从逻辑高电平拉到逻辑低电平时。 数据线必须保持在低逻辑电平至少1 µs; 下降后,DS18B20的输出数据有效期为15 µs,到读取结束时, 所有读取时隙的持续时间必须至少为60 µs。根据这些介绍,发现以上读的时序好像没有什么问题,但是读出来仍然是0xff。
然后只有另辟其境,将波形用逻辑分析仪波形看了一下,这里波形我就不一一贴出来了,直接说结果吧,程序在读的时候,我用逻辑分析仪看得波形并没有看到通讯引脚 DS18B20_DQ_OUT=0;delay_us(2);被拉低2us,这里就索性把2us改成5us发现波形正常,数据也出来了。随后笔者测试只要这个延时>2us温度就可以正常读出来了,至此,ds18b20问题终于解决。