51单片机4(温度传感器DS18B20)

1.DS18B20工作原理

DS18B20数字温度计提供九位温度度数,指示器件的温度。

(单片机上的接口) (DS18B20模块)

按照IO<--->DQ链接,即可实现单片机对其的控制。

1.1DS18B20命令集

1.2DS18B20操作流程

(1)复位
(2)51单片机发送0xCC,代表跳过ROM
(3)51单片机发送0x44,代表ds18b20开启温度转换
(4)延时等待(1s)
(5)复位
(6)51单片机发送0xCC,代表跳过ROM
(7)51单片机发送0xBE,代表读取ds18b20发送过来的温度值
(8)读取温度数据

每次和ds18b20通信前必须先复位!

1.2.1复位时序

最开始是高电平,主机将其由高电平拉低为低电平,持续480-960微秒,意味着单片机向ds18b20发送了一个复位信号,询问其是否存在。主机再将电平拉高,等待15-60微秒。若引脚一直为高电平,则表示ds18b20不存在,若电平被ds18b20拉低,则表示其存在。

根据时序图,我们可以写出复位函数:

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

#define DQ_HIGH ((P3 |= (1 << 7)))//P37置高电平
#define DQ_DOWN ((P3 &= ~(1 << 7)))
#define DQ_CHECK ((P3 & (1 << 7)) != 0)

// ds18b20 复位函数
int ds18b20_Reset(void)
{
   int t = 0;

   DQ_DOWN;
   Delay10us(70);
   DQ_HIGH;
   Delay10us(5);

   // 等待ds18b20发送存在脉冲:低电平到来
   while (DQ_CHECK && t < 30)
   {
   	   Delay10us(1);
	   t++;
   }
   if (t >= 30)
   {
   		return 0;
   }

   // 等待ds18b20将DQ引脚拉高: 高电平到来
   t = 0;
   while (!DQ_CHECK && t < 30)
   {
   	   Delay10us(1);
	   t++;
   }
   if (t >= 30)
   {
   		return 0;
   }

   	return 1;
}

1.2.2写时序

(写0和写1)

写0:单片机将电平拉低,ds18b20采样到低电平,说明单片机向传感器写入1

写1:单片机先将电平拉低至少1us后再缓慢拉高,ds18b20检测到高电平,说明单片机向传感器写入0

由写时序编写代码:

cs 复制代码
// 向ds18b20发送一个字节数据
void write_ds18b20(unsigned char dat)	
{
	  int i = 0;

	  // 循环判断要发送的数据中的8bit是1还是0
	  for (i = 0; i < 8; i++)
	  {
	  		if (dat & 1)	//bit1	  
			{
			   DQ_DOWN;
			   _nop_();
			   _nop_();
			   DQ_HIGH;
			   Delay10us(5);
			}
			else	  		// bit0
			{
			  	DQ_DOWN;
				Delay10us(5);
				DQ_HIGH;
			}

			dat >>= 1;
	  }
}

1.2.3读时序

(读0和写0)

读0:单片机将高电平拉低,15us内单片机采样,若检测到低电平,则单片机读取到0

读1:单片机将高电平拉为低电平至少1us,再将电平拉高,15us内单片机采样,若检测到高电平则读取到1

由读时序编写代码:

cs 复制代码
// 从ds18b20读取一个字节数据
unsigned char read_ds18b20(void)
{
	int i = 0;
	unsigned char ret = 0;

	for (i = 0; i < 8; i++)
	{
		DQ_DOWN;		  
		_nop_();
		_nop_();
		DQ_HIGH;
		_nop_();
		_nop_();
		_nop_();

		if (DQ_CHECK)	    // ds18b20发送一个bit1
		{
			ret |= (1 << i);	
		}
	   Delay10us(5);
	}

	return ret;
}

1.2.4获取ds18b20采集到的温度:

cs 复制代码
// 获取ds18b20采集到的温度
float get_temp(void)
{
  	short ret = 0;
	unsigned char tl = 0;
	unsigned char th = 0;

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

	tl = read_ds18b20();
	th = read_ds18b20();

	ret = th << 8;
	ret |= tl;

	return ret * 0.0625;//分辨率0.0625
}

我们在主函数中调用看看结果:

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

int main(void)
{
	float ret = 0;
	xdata char s[20];

	Uart_Init();

	while (1)
	{
	   ret = get_temp();
	   sprintf(s, "%f\n", ret);
	   Uart_SendStr(s);
	}

	return 0;
}

可以接收到温度

相关推荐
白帽攻防录8 小时前
SRC 挖洞:PostScript 打印机驱动双 RCE,打印服务器怎么变成内网跳板
开发语言·网络安全·php·内网安全
十年Java程序媛8 小时前
Java枚举Enum完整教程|替代静态常量,开发与面试要点
java·开发语言·spring boot·后端·面试
2603_965148118 小时前
电商选品调研:通过关键词搜索API获取市场热销商品,结合商品详情API分析竞品卖点与定价
开发语言·数据库·人工智能·python·信息可视化
生态学者9 小时前
Global Change Biology | 森林越“步调一致”,反而越怕干旱?树木生长与叶片活动的同步之谜
大数据·人工智能·算法·r语言·微信公众平台
xixiaoyunya9 小时前
Python 异步编程入门:用 asyncio 轻松实现并发任务
开发语言·python·php
lsswear9 小时前
Agent 框架新手入门与实战部署指南
大数据·人工智能·算法
学逆向的9 小时前
C 循环结构的执行效率分析
c语言·开发语言·数据结构·网络安全
G***技10 小时前
杰和科技亮相中国工博会:嵌入式边缘AI驱动自动化场景落地
嵌入式硬件·边缘ai·工博会
小坏讲微服务10 小时前
刚发布一个月的JDK 27,为什么我建议你立刻升级?
java·开发语言·spring boot·spring·架构·求职招聘·springboot4
Data analyse45611 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析