关于部分18B20读数据错误的问题分析:
部分18B20可能是生产厂家的不同,对程序的适应有些不一样,相同的程序,使用带防水封装的和裸的18B20产生了不同的结果,部分芯片读温度数据错误,出现500-600度的情况,心里一直错误的认为是芯片有故障,一度想把有问题的芯片丢了算了,分析了很久,终于想到了问题的根源:
发现问题出在读1bit数据的时候:
uint8_t DS18B20_Read_Bit(void) //读一位
{
uint8_t data;
b12_18b20_out(); //设置为输出
DS18B20_DQ_OUT0; //输出低电0
delay_us(2);
DS18B20_DQ_OUT1; //拉高
b12_18b20_in(); //设置为输入
delay_us(12); //延时12us
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9); //看波形用指令,正常后可以删除
if(DS18B20_DQ_IN)data=1; //读取总线数据
else data=0;
delay_us(50); //延时50us
return data;
}
串口读到数据
[10:03:52.072]接收←温度 = 655.35,0
[10:03:53.278]接收←温度 = 655.35,0
从波形可以看出上波型是在读18B20一位数据电平之前的GPIO B9管脚电平变化来参考,发现读电平时间晚了,18B20拉低的时刻已经过去了才读,显然数据是错误的。
修改后:
uint8_t DS18B20_Read_Bit(void) //读一位
{
uint8_t data;
b12_18b20_out(); //设置为输出
DS18B20_DQ_OUT0; //输出低电0
delay_us(2);
DS18B20_DQ_OUT1; //拉高
b12_18b20_in(); //设置为输入
delay_us(2); //延时12us 这里改为2us
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9); //看波形用指令,正常后可以删除
if(DS18B20_DQ_IN)data=1; //读取总线数据
else data=0;
delay_us(50); //延时50us
return data;
}
可以看出,程序已经顺利读到数据为0的位。温度数据正确。
温度的两个字节。
不同的18B20的拉低电平宽度有所不同,不同的器件需要不同的时序来适应。
可以参考。