51单片机 - 读写DS18B20


1> 实验目的

1

实现51单片机,读写单个DS18B20,并将温度值,通过串口输出到电脑;


2> DS18B20-灵魂4问?


2.1> 长啥样?


21


2.2> 能干哈?

DS18B20 数字温度计,测量范围-55°C ~ +125°C

22


2.3> 咋干的?

31

DS18B20 内部自带温度传感器,能将温度值转为2Byte的数据,提供单总线接口(1-Wire);
主控制器可以通过简单命令进行读写,从而获取温度值;

1

自己理解:类似于DS18B20的这种功能模块,
他们如同大学食堂的每个窗口,你不需要太了解内部加工过程,只需简单的,说“老板,刀削面来一碗”这样的命令;


2.4> 咋用他?

2个方面:硬件设计和程序设计;


2.4.1> 硬件设计

2

DQ引脚必须有上拉电阻;


2.4.2> 读1个DS18B20流程图

1


2.4.3> 控制命令

44

命令或数据,都是从最低有效位开始发送;
All data and commands are transmitted least significant bit(LSB) first over the 1-Wire bus.


2.4.4> 数据格式

温度分辨率:9~12位可选, 默认12位(0.0625°);
温度测量范围:-55°~+125°;

32

0b’11111010000 = 2000;
2000 * 0.0625 = 125°

负温度:是以二进制【补码】形式存放,正好符合C与语言有符号类型;



3> 单总线(1-Wire)通信协议


3.1> 读1个DS18B20的温度值

流程图:
1

字节流-时序图:
31


3.2> 复位脉冲/ 存在脉冲

初始化DS18B20, 确定DS18B20准备好;

1

空闲态: DQ保持高电平;
复位脉冲:主控制器将DQ拉低>=480us后,释放;
延时:DQ保持高电平,15~60us;
存在脉冲:DS18B20将DQ拉低60~240us,释放; // 表示准备好;


3.3> 写1-bit数据

42主控制器对DS18B20 : 写‘0’

写0:将总线DQ拉低60~120us;

主控制器对DS18B20 : 写‘1’

第1步:将DQ拉低0~15us; // 最多15us,一般设置成5-10us;
第2步:将DQ拉高,释放总线;

!注意:写0与写1之间,需要间隔1us;


3.4> 读1-bit数据

43 读‘0’

第1步:主控制器将DQ拉低>=1us;
第2步:主控制器将DQ拉高,释放总线;
第3步:DS18B20将DQ拉低,14us内释放总线;完成写0;
注意: 主控制器要读,只能在DS18B20拉低期间去采样;

读‘1’

第1步:主控制器将DQ拉低>=1us;
第2步:主控制器将DQ拉高,释放总线;
第3步:DS18B20将DQ拉高,14us内释放总线;完成写1;
注意: 主控制器要读,只能在DS18B20拉高期间去采样;

!注意:读DS18B20,采样时间段都是在前15us;

为什么后45us无效呢,DS18B20这么设计,可能是为了降低功耗;



4> 程序设计


4.1> 编程思路

51


4.2> 代码实现

底层时序相关:


#include "bsp.h"

/**
 * @brief:Initiallization Timing
 */
void DS18B20_Init(void)
{
	DS18B20_DQ = 1;
	
	DS18B20_DQ = 0;	// Reset Pulse
	Delay500us();
	
	DS18B20_DQ = 1;
	/* 判断DS18B20是否发送存在脉冲 */
	Delay500us();
}

/**
 * @brief:MCU Write 1bit 0 to DS18B20
 */
void DS18B20_Write_0(void)
{
	DS18B20_DQ = 0;
	Delay60us();	//写0
	DS18B20_DQ = 1; //释放DQ
}



/**
 * @brief:MCU Write 1bit 1 to DS18B20
 */
void DS18B20_Write_1(void)
{
	DS18B20_DQ = 0;
	Delay10us();	//0~15us;
	
	DS18B20_DQ = 1; 
	Delay60us();	//写1	
}


/**
 * @brief	: MCU Write 1Byte command
 * @cmd		: 1Byte DS18B20 ROM command or function command 
 */
void DS18B20_Write_Byte(uchar8_t cmd)
{
	uchar8_t i = 0;
	
	for (i = 0; i < 8; i++) {
		if ((cmd & 0x01) == 1) {
			DS18B20_Write_1();
		} else {
			DS18B20_Write_0();
		}
		
		_nop_();		//位与位间隔>=1us
		cmd = cmd >> 1;
	}
}

/**
 * @brief	: MCU Read 1Byte dat from DS18B20
 * @retval	: 1Byte dat from DS18B20 
 */
uchar8_t DS18B20_Read_Byte(void)
{
	uchar8_t i = 0;
	uchar8_t dat = 0;
	uchar8_t temp = 0;
	
	for (i = 0; i < 8; i++) {
		DS18B20_DQ = 0;
		_nop_();
		DS18B20_DQ = 1;
		
		Delay10us();
		
		temp = DS18B20_DQ; 				// 采样	
		dat = (temp << 7) | (dat >> 1);	// 低位先发送
		
		Delay60us();
	}
	
	return dat;
}

BSP级函数相关:

/**
 * @brief	: MCU Read 2Byte Temperature data from DS18B20
 * @retval	: Celseius temperature 
 */
float DS18B20_Read(void)
{
	float c_val = 0; 		// 存放摄氏度℃ 
	short16_t c_Hex	= 0x0;	// 存放2Byte二进制数据
	
	uchar8_t temp_L = 0x0;	
	
	
	// 阶段1
	DS18B20_Init();
	DS18B20_Write_Byte(0xCC);
	DS18B20_Write_Byte(0x44);
	
	// 阶段2
	DS18B20_Init();
	DS18B20_Write_Byte(0xCC);
	DS18B20_Write_Byte(0xBE);
	temp_L = DS18B20_Read_Byte();	// Byte 0:LSB
	c_Hex = DS18B20_Read_Byte();	// Byte 1:MSB
	
	// 转换温度
	c_Hex = temp_L | (c_Hex << 8);
	c_val = c_Hex * 0.0625;
	
	printf("temp = %g 度\n\r", c_val);	 // Debug
	
	return c_val;
}

5> 逻辑分析仪-测试波形


5.1> 复位脉冲 和 存在脉冲

51

复位脉冲 = 500us;
DS18B20延时 = 29us;
存在脉冲 = 113.4us;


5.2> 写1字节

52

写“1”拉低时间设置为10us,不要超过15us;


5.3> 读2字节

2Byte数据:
53

低位先发,所以DS18B20发送顺序是:1010 0101 1000 0000

低字节数据(Byte0):
53

观察波形,可以算出
DS18B20输出1bit数据的时长为:28.9-1.1 = 27.8us;
所以51单片机要在这段时间采样,数据手册给出的是15us;


6> 视频链接

🔗 B站视频教程-DS18B20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值