【传感器DS18B20】51单片机上实现温度采集

文章目录

一、数字温度传感器DS18B20

应用:设备温度 环境温度

二、传感器指标参数

  1. 量程

    (测量范围):-55℃ - 125℃

  2. 精度

    (传感器测量的温度与实际温度值之间所允许的最大误差):±0.5℃

  3. 分辨率

    (传感器对温度变化的敏感程度):分辨率越高,能察觉到越微小的温度变化,读数越细腻。

    9位:0.5℃

    10位:0.25℃

    11位:0.125℃

    12位:0.0625℃(默认分辨率)

  4. 工作电压

    3V - 5.5V

三、51单片机与DS18B20通信

半双工、异步通信、串行

GPIO One-Wire 单总线:传感器与单片机通过一根GPIO进行通信

四、线与特性

引脚拉高,不能直接决定引脚电平

释放总线:在传感器通信中,将引脚拉高这一行为称为释放总线。

你作为数据的接收方时,需要释放总线

五、温度读数

(两字节):16位、符号位扩展、二进制补码

六、DS18B20采集温度流程

七、DS18B20复位时序

复位时序:

  1. 主机将总线拉低480-960us,发送复位脉冲

  2. 主机释放总线,延时15-60us

  3. DS18B20将总线拉低60-240us,回复响应脉冲

  4. DS18B20释放总线,总线呈现高电平,初始化过程结束。

八、DS18B20读写时序

写时序:

  1. 写'0'时序:

    a. 主机将总线拉低至少60us,最多不超过120us

    b. ds18b20在15us-60us内进行采样,若总线此时为低电平,则代表主机发送了'0'

    c. 主机释放总线

  2. 写'1'时序:

    a. 主机将总线拉低小于15us,释放总线

    b. ds18b20在15us-60us内进行采样,若此时为高电平,则代表主机发送了'1'

读时序:

  1. 读'1'时序:

    a. 主机拉低总线,大于1us,然后释放总线

    b. ds18b20释放总线,总线呈现高电平

    c. 主机在15us内采样电平,此时总线为高电平,代表主机读到'1

  2. 读'0'时序:

    a. 主机拉低总线,大于1us,然后释放总线

    b. ds18b20在主机释放总线后,主动拉低(代表要传输'0)

    c. 主机在15us内进行采样,此时总线为低电平,代表主机读到'0

九、代码示例

下面的代码以 P3.7 作为单总线 DQ 引脚,封装了单总线复位、写字节、读字节底层时序函数,复位函数完成总线复位并检测传感器应答,超时就串口输出错误信息;写、读函数按照 DS18B20 单总线时序逐位收发数据,低位优先;get_temp 函数先复位传感器,发送跳过 ROM 命令与温度转换命令,延时等待转换结束,再次复位后发送读寄存器指令,读取温度高低字节拼接成 16 位原始数据,最后乘以 0.0625 换算成实际摄氏温度并返回浮点温度值,适用于单 DS18B20 测温场景。

c 复制代码
#include <reg51.h>
#include <intrins.h>
#include "ds18b20.h"
#include "delay.h"
#include "uart.h"

#define DQ_PIN_LOW 	(P3 &= ~(1 << 7))   // DQ引脚拉低
#define DQ_PIN_HIGH (P3 |= (1 << 7))  	// DQ引脚拉高
#define DQ_CHECK	((P3 & (1 << 7)) != 0)  // 判断DQ引脚为高电平

// 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;
}

// 主机发送一个字节
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;
	}
}

// 主机读取一个字节
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;
}

// 读取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;			 
}
相关推荐
艾芯微科技2 小时前
B16WS SOD-323 肖特基二极管参数、应用电路与选型踩坑指南
网络·单片机·嵌入式硬件·集成测试·51单片机
糖糖单片机设计2 小时前
基于STM32的远程宠物自动投喂系统
人工智能·stm32·51单片机·语音识别·智能硬件
Logic1013 小时前
C语言/数据结构位运算题解:异或XOR找出流水线上的“独特零件编号“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
山下梅子酒2253 小时前
洛谷-入门-B2043
c语言
神威难绷泪4 小时前
51单片机 day1
51单片机
abc light4 小时前
单片机(3)
51单片机
幼儿园蛋小黑4 小时前
【无标题】C语言变量,类型转换,运算符,输入和输出
c语言·嵌入式实时数据库
HRTOS5 小时前
HRTOS Debug 正式发布:为 8051 实时系统提供可观测、可诊断的运行状态监控能力
单片机·嵌入式硬件·51单片机
llilian_165 小时前
PTP时钟服务器时间溢出隐患解决方案 1588时钟服务器 ptp服务器
大数据·网络·单片机·嵌入式硬件·51单片机