硬件基础4

ds18b20 数字温度传感器

1.参数指标

(1)量程(温度测量范围): -55℃----125℃

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

(3)分辨率(传感器对温度变化的敏感程度):

9位:0.5℃

10位:0.25℃

11位:0.125℃

12位(默认):0.0625℃

(4)工作电压:3v---5.5v

2.ds18b20通信(半双工,串行,异步):

GPIO One-wire:GPIO单总线通信,通过一根GPIO信号线来进行通信

3.ds18b20芯片内部结构

(1)可以通过内部电源给芯片供电

(2)64位ROM和单总线接口;

(3)存储器控制逻辑模块:协调芯片内部各模块工作

(4)暂存器(SCRATCHPAD):存放温度,配置参数

(5)温度传感器:采集温度

(6)高温触发阈值与低温触发阈值(可配置)

(7)8位CRC校验生成器:生成CRC校验

4.上拉电阻

上拉电阻 是数字电路中非常基础但极其重要的元件,用于确保信号线在"空闲"时有确定的电平状态

51和ds18b20都释放总线时,总线能够呈现高电平,释放总线 (需要作为数据的接收方)

任何一方拉低总线,整个总线都变低

5.dsl8b20读数

16位、符号扩展的二进制补码,通过单总线DQ串行发出

6.读取数据流程

(1)复位

(2)发送0xCC,跳过ROM

(3)发送0x44,开启温度转换

(4)延时750ms

(5)复位

(6)发送0xCC,跳过ROM

(7)发送0xBE,读取温度

(8)读取两个字节的温度数据

复制代码
float get_temp(void)
{
	unsigned char temp_low=0;
	unsigned char temp_high=0;
	short temp=0;

	ds18b20_reset();
	write_ds18b20(0xCC);
	write_ds18b20(0x44);
	Delay1ms(1000);
	ds18b20_reset();
	write_ds18b20(0xCC);
	write_ds18b20(0xBE);

	temp_low=read_ds18b20();
	temp_high=read_ds18b20();

	temp=temp_high << 8;
	temp |= temp_low;

	return temp * 0.0625;
}

DS18B20 返回的温度数据是16位的 ,但单片机一次只能读取8位(1个字节),所以必须分两次读取。

要遵循LSB读取顺序

复制代码
// DS18B20 先发送低字节(LSB),再发送高字节(MSB)
temp_low  = read_ds18b20();   // 先读低字节
temp_high = read_ds18b20();   // 后读高字节

// 如果顺序错了:
// temp_high = read_ds18b20();   // ❌ 先读高字节 → 数据错乱
// temp_low  = read_ds18b20();

7.时序逻辑

(1)复位时序

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

2.主机释放总线,交出控制权,总线呈现高水平

3.ds18b20检测到总线为高水平后,等待15---60us

4.ds18b20将总线拉低60---240us,回复响应脉冲,向主机应答

5.ds18b20释放总线,总线呈现高水平,告诉主机执行完毕

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

#define DQ_PIN_LOW 	 (P3 &=~(1<<7))
#define DQ_PIN_HIGH  (P3 |=(1<<7))
#define DQ_PIN_CHECK 	((P3 & (1<<7))!=0)	// 检测DQ引脚是否为高电平

int ds18b20_reset(void)
{
    int time=0;

	 // 主机向ds18b20发送复位脉冲
	DQ_PIN_LOW;
	Delay10us(70);
	DQ_PIN_HIGH;
	Delay10us(5);

	// 等待低电平到来,ds18b20拉低总线
	while(DQ_PIN_CHECK && time<30)
	{
		Delay10us(1);
		time++;
	}
	if (time >= 30)
    {
   		uart_sendstr("wait ds18b20_low timeout!\r\n");
   		return -1;
    }

	// 等待高电平到来,ds18b20释放总线
    time = 0;
    while (!DQ_PIN_CHECK && time < 30)
    {
   		Delay10us(1); 
		time++;  	
    }
    if (time >= 30)
    {
   		uart_sendstr("wait ds18b20_high timeout!\r\n");
		return -2;
    }

	return 1;
}	

(2)写0时间片与写1时间片

写0时序

1.主机首先将总线拉低小于15us,告诉从机开始写数据,然后持续拉低60us,驱动 '0' 的低电平到总线上

2.ds18b20在30us---60us内进行采样,此时总线如果是低水平,则ds18b20读0

3.主机释放总线,呈现高水平

写1时序

1.主机将总线拉低小于15us,告诉从机开始写数据,然后释放总线,呈现高水平,驱动"1"电平到总线上,从机此时释放总线

2.ds18b20在拉高后45us内进行采样,此时总线如果是高水平,则ds18b20读1

复制代码
void write_ds18b20(unsigned char dat)
{
	int i=0;
	for(i=0;i<8;i++)
	{
		if(dat & 1)
		{
			DQ_PIN_LOW;
			_nop_();
			_nop_();
			DQ_PIN_HIGH;
			Delay10us(5);
		}
		else
		{
			DQ_PIN_LOW;
			Delay10us(6);
			DQ_PIN_HIGH;
		}
		dat >>= 1;
	}	
}	

(3)读0时间片与读1时间片

读0时序

1.主机拉低总线,持续1us,释放总线

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

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

读1时序

1.主机拉低总线,持续1us,释放总线

2..ds18b20释放总线,总线由上拉电阻拉为高电平

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

复制代码
unsigned char read_ds18b20(void)
{
	unsigned char dat = 0;
	int i = 0;

	for (i = 0; i < 8; i++)
	{
		DQ_PIN_LOW;
 		_nop_();
		_nop_();
          //主机发起读时序,告诉 DS18B20 "我要读数据了"
		DQ_PIN_HIGH;					
 		_nop_();
		_nop_();
 		_nop_();
           //释放总线,让 DS18B20 驱动数据线
        DS18B20 会在主机释放总线后:
       - 在 1-3μs 内驱动数据线
       - 发送 '0':拉低总线(低电平)
       - 发送 '1':释放总线(高电平)
		
		if (DQ_PIN_CHECK)  // 读到ds18b20发送的'1'
		{
			 dat |= (1 << i);
		}		
	
		Delay10us(6);		
	}

	return dat;
}
相关推荐
极客 - L U2 小时前
卡尔曼滤波从零到精通
c语言·数据结构·单片机·嵌入式硬件·mcu
谙弆悕博士4 小时前
用 C 写了个 Windows 聊天室,踩了几个多线程和控制台的坑
c语言·开发语言·c++·windows·网络编程·聊天室
水饺编程4 小时前
第2章:Linux 基础,删除用户
linux·c语言·汇编
小鱼仙官6 小时前
使用Qt封装C/C++ 动态库 用于第三方调用
c语言·c++·qt
FLJwu8 小时前
运动相机图像传感器选型实战|第二篇:参数看着一模一样,为什么骑行录像疯狂果冻、拖影翻车?
android·c语言·开发语言·数码相机·运动相机·oem 量产
Escalating_xu8 小时前
【C语言项目实战】贪吃蛇(下):移动、碰撞与计分,完成一局可玩的游戏
c语言·开发语言·游戏
C++ 老炮儿的技术栈9 小时前
机器人的坐标,像 XYZ 的坐标值,是用单精度浮点还是用双精度浮点?
c语言·c++·人工智能·单片机·c
lhbweilai1 天前
分析FreeRTOS内核对象API的源码实现(八)
c语言·开发语言·stm32·单片机
艾络迅Acceleronix1 天前
环境监测终端:STM32+EG800Z AT+ 艾络迅平台实战|多传感器采集联动全流程
c语言·stm32·单片机·嵌入式硬件·物联网·1024程序员节
Zwawa1 天前
一只按键不只“按下”:短按、长按和连按如何共存
c语言·单片机·嵌入式