一、传感器概述
DS18B20 是一款数字温度传感器,通过单总线(One-Wire)与单片机通信,只需一根 GPIO 信号线即可完成数据传输。
二、传感器指标参数
| 量程(温度测量范围) | -55℃ 至 125℃ |
| 精度(最大允许误差) | ±0.5℃ |
| 工作电压 | 3V – 5.5V |
精度说明:精度指传感器测量的温度与实际温度值之间允许的最大误差。例如实际温度为 25℃ 时,传感器采集温度值在 24.5℃ – 25.5℃ 之间。
三、分辨率
分辨率反映传感器对温度变化的敏感程度。分辨率越高,能察觉到的微小温度变化越小,读数越细腻。
| 9 位 | 0.5℃ |
| 10 位 | 0.25℃ |
| 11 位 | 0.125℃ |
| 12 位 | 0.0625℃ |
四、51 单片机与 DS18B20 通信
通信方式为半双工、异步、串行通信。DS18B20 通过一根 GPIO 信号线(DQ)与单片机连接,采用 One-Wire 单总线协议。

| VCC | 电源 |
| DQ | 数据线 |
| GND | 地线 |
线与特性
单总线具有线与特性,引脚拉高时不能直接决定引脚电平,拉高表示释放总线。当作为数据接收方时,需要释放总线。

| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 1 | 1 |
| 0 | 0 | 0 |
GPIO 输出模式用于发送数据,GPIO 输入模式用于接收数据。读数格式为 16 位、符号位扩展、二进制补码。
五、DS18B20 采集温度流程

六、时序详解
1. 复位时序
对应函数:ds18b20_reset();

// ds18b20 复位
int ds18b20_reset(void)
{
int time = 0;
// 主机向ds18b20发送复位脉冲
DQ_PIN_LOW;
Delay10us(70);
DQ_PIN_HIGH;
Delay10us(6);
// 等待低电平到来 (超时时间)
while (DQ_CHECK && time < 30)
{
Delay10us(1);
time++;
}
if (time >= 30)
{
uart_sendstr("wait ds18b20_low timeout!\\n");
return -1;
}
// 等待高电平到来
time = 0;
while (!DQ_CHECK && time < 30)
{
Delay10us(1);
time++;
}
if (time >= 30)
{
uart_sendstr("wait ds18b20_high timeout!\\n");
return -2;
}
return 1;
}
2. 写时序
写 '0' 时序:
写 '1' 时序:
// 主机发送一个字节
void write_ds18b20(unsigned char dat)
{
int i = 0;
for (i = 0; i < 8; i++)
{
if (dat & 1) // 写1
{
DQ_PIN_LOW;
_nop_();
_nop_();
DQ_PIN_HIGH;
Delay10us(6);
}
else // 写0
{
DQ_PIN_LOW;
Delay10us(6);
DQ_PIN_HIGH;
}
dat >>= 1;
}
}
3. 读时序
读 '1' 时序:
读 '0' 时序:
// 主机读取一个字节
unsigned char read_ds18b20(void)
{
unsigned char dat = 0;
int i = 0;
for (i = 0; i < 8; i++)
{
DQ_PIN_LOW;
_nop_();
_nop_();
DQ_PIN_HIGH;
_nop_();
_nop_();
_nop_();
// 代表读到1
if (DQ_CHECK)
{
dat |= (1 << i);
}
Delay10us(6);
}
return dat;
}
七、关键指令与代码
指令说明:
- 0xCC(1100 1100):跳过 ROM 指令
- 0x44:开启温度转换指令
- 0xBE:读取温度指令
写数据函数:
void write_ds18b20(unsigned char dat)
{
// 按位写入,每位遵循写时序要求
}
典型调用:
// 读取ds18b20温度
float get_temp(void)
{
unsigned char temp_low = 0;
unsigned char temp_high = 0;
short temp = 0;
ds18b20_reset(); // 复位
write_ds18b20(0xCC); // skip ROM
write_ds18b20(0x44); // 开启温度转换
Delay1ms(1000); // 等待温度转换完毕
ds18b20_reset(); // 复位
write_ds18b20(0xCC); // skip ROM
write_ds18b20(0xBE); // 读取温度
temp_low = read_ds18b20(); // 读取温度低位
temp_high = read_ds18b20(); // 读取温度高位
// 2个字节温度值
temp = temp_high << 8;
temp |= temp_low;
return temp * 0.0625;
}





