【51单片机】DS18B20温度采集

一. 任务目标

1、学习单总线温度传感器原理通信时序

2、使用51单片机的一个 IO 口模拟单总线时序与温度传感器DS18B20通信,将检测的环境温度读取出来。

二、实验要求

1、 写出实验设计的主要原理。

2、使用DS18B20温度传感器、数码管显示检测的温度值,在Proteus和普中开发板实物上完成 DS18B20 的环境温度采集。

3、将上述实验成功的代码在Keil中进行仿真运行,使用虚拟逻辑分析仪显示单片机与DS18B20的DQ数据线连接引脚的波形,分析其“初始化–>写—>读”总线时序,与原理进行对比分析:
1)判断其是否符合技术要求;
2)故意在代码中把时序弄错(改延时delay的延时值),再重新运行之前的实验,看DS18B20是否能正确相应并返回温度。

三、具体实现

3.1 实验原理

DS18B20 是由 DALLAS 半导体公司推出的一种的“1-Wire bus(单总线)”接口的温度传感器。与传统的热敏电阻等测温元件相比,它是一种新型的体积小、适用电压宽、与微处理器接口简单的数字化温度传感器。

单总线构成的分布式温度监测系统
想要实现正确工作,一方面是数据,另一方面则是时序。

3.1.1 数据处理

数据方面,将数据存储在相应的RAM中,片内有9个字节的高速暂存器RAM单元,9个字节具体分布如下:
片内有9个字节的高速暂存器RAM单元,9个字节具体分布如下:
在这里插入图片描述

第1字节和第2字节是经转换所得的温度值,以两字节补码形式存放其中。
第3、4字节分别是由软件写入用户报警的上下限值TH和TL
第5个字节为配置寄存器,可对其更改DS18B20的测温分辨率,高速暂存器的
第6、7、8字节未用,为全1。
第9字节是前面所有8个字节的CRC码,用来保证正确通信。片内还有1个E2PROM为TH、TL以及配置寄存器的映像。

存好之后,要将数据进行温度转换,以下是温度转换的计算方法:

  • 当DS18B20采集的温度为+120℃时,输出十六进制数为0x0780。
    =120℃1
  • 假如当DS18B20采集的温度为-55℃时,输出为0xfc90,由于是补码,则先将11位数据取反加1得0x0370,注意符号位不变,也不参加运算,则
    =55℃在这里插入图片描述
    注意,负号则需对采集的温度进行判断后,再予以显示。

3.1.2 工作时序

 DS18B20的工作时序包括初始化时序、写时序和读时序。

1.初始化
在这里插入图片描述
粗黑线为主机。灰色细线为上拉电阻。
首先主机上拉输入,即DQ=1,延时Delay5(1);
之后DQ=0,延时480us~ 960us。
等待存在脉冲的到来,15~60us之后,存在脉冲为1个60到240us的低电平。
如果没来则按超时处理,从机接收到主机的复位脉冲。

2.写时序
在这里插入图片描述
DQ=1,1us;
DQ=0,若写入0维持不变,1则延时15us,上拉主线,即DQ=1;

3.读时序
在这里插入图片描述
DQ=1,延时1us;
释放总线,即DQ=0,读数据,如果上拉电阻,读1位数据。若为0,不用管。

3.2 代码实现

实现步骤分别为:
发送启动信号、写入跳过ROM指令、发送温度转换指令、再次启动信号、写入读取温度寄存器指令,然后读取两个字节的温度数据并计算出温度值。

3.2.1 初始化

当DS18B20工作时,首先按照1-Wire协议发送初始化序列,包括发送复位脉冲和存在脉冲。

void init_ds18b20(void)
{
	 uchar x=0; 
	 DQ =0;    
	 delay5(120); 
	 DQ =1;    
	 delay5(16);
	 delay5(80);
}

3.2.2 写入数据

向DS18B20写入一个字节的数据。根据1-Wire协议,写入“1”需要在15微秒内拉低数据线,写入“0”需要拉低60微秒。

void writebyte(uchar dat) 			//函数功能:写1字节
{
 uchar i=0;
 for(i=8;i>0;i--)
 {
	  DQ =0;
	  DQ =dat&0x01;				//写"1" 在15µs内拉低
	  delay5(12);	   			//写"0" 拉低60µs
	  DQ = 1;	   
	  dat>>=1;
	  delay5(5);
	  }
}

3.2.3 读数据

从DS18B20读取一个字节的数据。通过发送时钟信号并在15微秒内读取数据线状态来完成每一位的读取。

uchar readbyte(void) 			//函数功能:读取1字节数据
{
	uchar i=0;
	uchar date=0;
	for (i=8;i>0;i--)
	{
		  DQ =0;
		  delay5(1);
		  DQ =1;			//15µs内拉释放总线
		  date>>=1;
		  if(DQ)
		  date|=0x80;
		  delay5(11);
	 }
 	return(date);
}

3.2.4 完整代码

主函数:首先调用delay5函数进行延时,然后进入一个无限循环,在循环中不断地调用retemp函数读取温度,并将其显示在数码管上。通过分时控制两个数码管显示温度的十位和个位。

#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int 
#define out P0
sbit smg1=out^4;
sbit smg2=out^5;
sbit DQ=P3^7;
void delay5(uchar);
void init_ds18b20(void);
uchar readbyte(void);
void writebyte(uchar);
uchar retemp(void);

void main(void)
{
uchar i,temp;
delay5(1000);
while(1)
	{
	 temp=retemp();	
	 for(i=0;i<10;i++)	//连续扫描数码管10次
	 {
	 out=(temp/10)&0x0f;
	 smg1=0;
	 smg2=1;
	 delay5(1000);	//延时5ms
	 out=(temp%10)&0x0f;
	 smg1=1;
	 smg2=0;
	 delay5(1000);	//延时5ms
	 }
	}

}

 /*--------------精确延时5us子程序---------*/	
void delay5(uchar n)
{
	 do
	 {
	 _nop_();
	 _nop_();
	 _nop_();
	 n--;
	 }
	 while(n);
}
/*--------------初始化函数--------------------*/
void init_ds18b20(void)
{
	 uchar x=0; 
	 DQ =0;    
	 delay5(120); 
	 DQ =1;    
	 delay5(16);
	 delay5(80);
}
/*--------------读取一字节函数----------------*/
uchar readbyte(void)
{
	uchar i=0;
	uchar date=0;
	for (i=8;i>0;i--)
	 {
		  DQ =0;
		  delay5(1);
		  DQ =1;	//15微秒内拉释放总线
		  date>>=1;
		  if(DQ)
		  date|=0x80;
		  delay5(11);
	 }
 	return(date);
}
/*--------------写一字节函数------------------*/
void writebyte(uchar dat)
{
 uchar i=0;
 for(i=8;i>0;i--)
	 {
	  DQ =0;
	  DQ =dat&0x01;//写"1" 在15微秒内拉低
	  delay5(12);	   //写"0" 拉低60微秒
	  DQ = 1;	   
	  dat>>=1;
	  delay5(5);
	  }
}
/*--------------读取温度函数------------------*/
uchar retemp(void)
{
	uchar a,b,tt;
	uint t;
	init_ds18b20();
	writebyte(0xCC); 
	writebyte(0x44);
	init_ds18b20();
	writebyte(0xCC); 
	writebyte(0xBE); 
	a=readbyte();
	b=readbyte();
	t=b;
	t<<=8;
	t=t|a;
	tt=t*0.0625;
	return(tt);
}

3.2.5 仿真结果

在这里插入图片描述

3.3 时序分析

3.3.1 波形图

在这里插入图片描述
经过分析后发现符合符合技术要求。

3.3.2 更改时序

找到初始化函数,更改delay5函数的变量。
在这里插入图片描述
结果如下:
在这里插入图片描述
我们发现,更改数据后,无法正确相应并返回温度。因此,时序对于DS18B20采集环境是至关重要的。

四、实验总结

通过实验,我们发现时序对于DS18B20采集环境是至关重要的。
当我们觉察到温度采集的滞后时,可以尝试更改delay相关参数。

以上则是我此次实验过程,如有错误请各位大佬多多指教。

<think>好的,我现在需要帮助用户查找与DS18B20相关的程序或代码示例。用户提到了参考站内引用中的两篇文章,一个是关于STC_51单片机的驱动示例,另一个是AVR单片机的C程序。首先,我需要确认DS18B20的基本知识,确保代码示例的正确性。 DS18B20是常用的数字温度传感器,使用单总线协议通信。根据用户提供的引用,STC_51和AVR都有相关的示例代码。我应该先整理这两个平台的代码结构,确保代码符合用户的查询需求。同时,用户可能还需要了解如何初始化和读取温度数据,因此需要包含这些步骤的详细说明。 接下来,检查用户提供的引用内容,引用[1]提到了STC_51单片机的驱动示例,包括初始化和显示温度的方法。引用[2]则是AVR单片机的C程序,特别是显示十六进制数据的函数。需要将这些内容整合到回答中,提供两个不同单片机的代码示例。 此外,用户可能对单总线协议和时序控制不太熟悉,因此在代码中需要注释关键部分,比如延时函数、复位脉冲、读写操作等。同时,确保代码语法正确,符合LaTeX格式要求,例如行内公式用$...$,独立公式用$$...$$。 生成相关问题时要考虑用户可能的后续需求,比如时序调整、精度优化、多传感器应用等。确保问题具体且相关,帮助用户进一步探索DS18B20的应用。 最后,验证所有代码示例的正确性,确保没有语法错误,并正确标注引用来源,末尾自然添加引用标识。保持回答结构清晰,分步骤说明,使用中文,符合用户的要求。</think>以下是关于DS18B20温度传感器的代码示例及实现原理说明: ### DS18B20驱动实现原理 DS18B20采用单总线协议(1-Wire),通信时序需精确控制。关键步骤包括初始化、发送命令(如跳过ROM指令$CCh$、启动温度转换$44h$)、读取数据等[^1]。 ### STC51单片机示例代码 ```c #include <STC89C5xRC.H> sbit DQ = P1^0; // 单总线数据引脚 // 延时函数(12MHz晶振) void delay_us(unsigned int t) { while(t--); } // 初始化DS18B20 unsigned char init_ds18b20() { unsigned char flag; DQ = 0; delay_us(480); // 480μs复位脉冲 DQ = 1; delay_us(60); // 等待传感器响应 flag = DQ; delay_us(420); return flag; // 0=初始化成功 } // 读取一个字节 unsigned char read_byte() { unsigned char i, dat = 0; for(i=0; i<8; i++) { DQ = 0; dat >>= 1; DQ = 1; if(DQ) dat |= 0x80; delay_us(30); } return dat; } // 主程序读取温度 float read_temperature() { unsigned char LSB, MSB; init_ds18b20(); write_byte(0xCC); // 跳过ROM write_byte(0x44); // 启动温度转换 delay_ms(750); // 等待转换完成 init_ds18b20(); write_byte(0xCC); write_byte(0xBE); // 读取暂存器 LSB = read_byte(); MSB = read_byte(); return ((MSB << 8) | LSB) * 0.0625; } ``` [^1] ### AVR单片机示例(LCD显示部分) ```c void lcd_puthex(unsigned char byte_data) { unsigned char nibble = (byte_data >> 4) & 0x0F; lcd_putchar(nibble > 9 ? nibble + 'A' - 10 : nibble + '0'); nibble = byte_data & 0x0F; lcd_putchar(nibble > 9 ? nibble + 'A' - 10 : nibble + '0'); } // 温度值通过该函数转换为十六进制显示[^2] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值