当前位置:主页 > 查看内容

基于蓝桥杯的单片机模块练习——DS18B20温度传感器

发布时间:2021-07-08 00:00| 位朋友查看

简介:基于蓝桥杯的单片机模块练习——DS18B20温度传感器 相关知识点 1.概况 特点 1.单总线通讯 2.每个设备都有一个存储在板载只读存储器中的唯一64位串行代码所以一条通讯总线可挂多个DS18B20 3.测量范围是-55℃至125℃从-10℃到85℃有±0.5℃的精度 4.温度计分辨……

基于蓝桥杯的单片机模块练习——DS18B20温度传感器

相关知识点

1.概况
在这里插入图片描述
特点:
1.单总线通讯
2.每个设备都有一个存储在板载只读存储器中的唯一64位串行代码,所以一条通讯总线可挂多个DS18B20
3.测量范围是-55℃至+125℃,从-10℃到+85℃有±0.5℃的精度
4.温度计分辨率可由用户从9到12位选择
5.最慢在750毫秒内将温度转换为12位数字值
2.测量温度的操作
温度传感器的分辨率可由用户配置为9、10、11或12位,分别对应于0.5℃、0.25℃、0.125℃和0.0625℃的增量。上电时的默认分辨率为12位。
要启动温度测量和模数转换,主机必须发出转换[44h]命令。转换后,产生的热数据存储在暂存存储器的2字节温度寄存器中,DS18B20返回空闲状态。
温度数据在温度寄存器中存储为16位符号扩展二进制补码。如下图:
在这里插入图片描述
符号位表示温度是正还是负:对于正数,S = 0;对于负数,S = 1。
如果DS18B20配置为12位分辨率,温度寄存器中的所有位都将包含有效数据。对于11位分辨率,位0未定义。对于10位分辨率,位1和0未定义,对于9位分辨率,位2、1和0未定义。
注意:
1)我们从18B20里面读出的数据全是温度的补码形式,所以如果是正温度则不需要特殊处理,如果是负温度,那么需要把补码做一下转换。
【思考:-10.125 的补码如何写呢???】
2)温度寄存器的上电复位值为+85℃。也就是:0000 0101 0101 0000
3.温度计分辨率配置
在这里插入图片描述
在这里插入图片描述
将数据写入暂存字节2、3(TH、TL和配置寄存器)和4 :【4Eh】
该命令允许主机向DS18B20的暂存区写入3字节的数据。第一个数据字节写入TH寄存器(暂存区的字节2),第二个字节写入TL寄存器(字节3),第三个字节写入配置寄存器(字节4)。数据必须首先以最低有效位传输。主机发出复位之前,必须写入所有三个字节,否则数据可能会损坏。

void Config_18B20()
{
	init_ds18b20();
	Write_DS18B20(0xcc);//跳过ROM
	Write_DS18B20(0x4e);//写暂存器指令4E
	
	Write_DS18B20(0x7d);//写高速缓存器TH高温限值125度
	Write_DS18B20(0x00);//写高速缓存器TL低温限值0度
	Write_DS18B20(0x1f);//写配置寄存器4
						//0x1f : 0.5000°C  转换时间93.75ms
						//0x3f : 0.2000°C  转换时间187.5ms
						//0x5f : 0.1250°C  转换时间375ms
						//0x7f : 0.0625°C  转换时间750ms
	init_ds18b20();
	
}

note:上电默认值为R0 = 1,R1 = 1 (12位分辨率)
4.访问DS18B20的顺序
注意:每次访问DS18B20时都要遵循这个顺序,这一点非常重要,因为如果序列中的任何步骤丢失或顺序错误,DS18B20将不会响应。
step1.初始化
单线总线上的所有事务都以初始化序列开始。初始化序列由总线主机发送的复位脉冲和从机发送的存在脉冲组成。存在脉冲让总线主设备知道从设备(如DS18B20)在总线上,并准备运行。
step2.发送ROM指令
总线主控器检测到存在脉冲后,可以发出只读存储器命令。这些命令对每个从设备的唯一64位只读存储器代码进行操作,如果单线总线上有多个从设备,允许主设备选择一个特定的设备。这些命令还允许主机确定总线上有多少设备和什么类型的设备,或者是否有任何设备出现报警情况。ROM命令有5个,每个命令8位长。在发出DS18B20功能命令之前,主设备必须发出适当的只读存储器命令。
step3.跳过ROM【CCh】
主机可以使用该命令同时寻址总线上的所有设备,而无需发送任何只读存储器代码信息。例如,主机可以通过发出跳过只读存储器命令,然后发出转换T [44h]命令,使总线上的所有DS18B20s同时执行温度转换。
step4.开始温度转换【44h】
该命令启动单次温度转换。转换后,产生的热数据存储在暂存存储器的2字节温度寄存器中,DS18B20返回低功耗空闲状态。
step5.读取温度【BEh】
该命令允许主机读取温度数据。数据传输从字节0的最低有效位开始,相继通过暂存区,直到读取完所有字节数据。如果只需要部分数据,主机可以随时发出复位以终止读取。在这里插入图片描述

注意,只有当总线上只有一个从设备时,读暂存[BEh]命令才能跟随跳过只读存储器命令。在这种情况下,通过允许主机从从机读取而不发送设备的64位只读存储器代码,可以节省时间。如果有一个以上的从机,跟随读暂存命令的跳过只读存储器命令将导致总线上的数据冲突,因为多个设备将试图同时传输数据。

5.单总线通讯相关时序图及如何用程序模拟
1.初始化
在这里插入图片描述
与DS18B20的所有通信都从初始化序列开始,该序列由来自主机的复位脉冲和来自DS18B20的存在脉冲组成。当DS18B20响应复位发送存在脉冲时,它向主机指示它在总线上,准备工作。
在初始化序列期间,总线主设备通过将单线总线拉低至少480秒来发送复位脉冲。然后,总线主设备释放总线并进入接收模式。当总线释放时,5k的上拉电阻将单线总线拉高。当DS18B20检测到该上升沿时,它会等待15秒至60秒,然后通过将单线总线拉低60秒至240秒来发送存在脉冲。

//-----------------------------------------------------
//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;//作为返回数值
  //	EA = 0;防止中断打扰时序
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);//480~960 us
  	DQ = 1;//释放总线
  	Delay_OneWire(10); //15~60  DS18B20会来拉低总线
    initflag = DQ;     //读取18B20的复位应答信号
  	Delay_OneWire(5);//等待60~240us总线释放
	//EA = 1;
  
  	return initflag;//应答信号为低电平,表示复位成功
}

2.写入时序
在这里插入图片描述
所有写入时隙的持续时间必须至少为60us,各个写入时隙之间的恢复时间至少为1us。两种类型的写入时隙都是由主机拉低单线总线来启动的。为了产生写1时隙,在将单线总线拉低后,总线主设备必须在15us内释放单线总线。当总线被释放时,5k的上拉电阻将把总线拉高。要生成写0时隙,在将单线总线拉低后,总线主设备必须在时隙期间(至少60us)继续保持总线低电平。
DS18B20在主机启动写入时隙后持续15us至60us的时间内对单线总线进行采样。如果在采样窗口期间总线为高电平,则向DS18B20写入1。如果线路为低电平,则向DS18B20写入0。

//===============================================
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	//EA = 0;
	for(i=0;i<8;i++)
	{
		DQ = 0;//迅速拉低总线10~15us
		DQ = dat&0x01;//要写入的这一位是1,DQ就=1,要写入的这位是0,DQ就等于0
		Delay_OneWire(5);//延时一会20~45us,等待DS18来读
		DQ = 1;//释放总线
		dat >>= 1;//开始准备写下一位
	}
	
	Delay_OneWire(5);
	//EA = 1;
}
//===============================================

3.读出时序
在这里插入图片描述
所有读取时隙的持续时间必须至少为60us,时隙之间的恢复时间至少为1us。通过主设备将单线总线拉低至少1us,然后释放总线,启动读取时隙。在主机启动读取时隙后,DS18B20将开始在总线上传输1或0。DS18B20通过保持总线高电平传输1,通过拉低总线传输0。当传输0时,DS18B20将在时隙结束时释放总线,总线将被上拉电阻拉回到其高空闲状态。
DS18B20的数据在启动读取时隙的下降沿后15us内有效。因此,主机必须释放总线,然后在从插槽开始的15us内对总线状态进行采样。

//===============================================
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;//储存读取到的数据
  //EA = 0;
	for(i=0;i<8;i++)
	{
		DQ = 0;//迅速拉低
		dat >>= 1;//这是从最高位写的,所以要相佑方移动到第一位
		DQ = 1;//把这个置低,才能让DS18来决定他便成1还是0
		if(DQ)//如果读到1,则把最高位写1,其他位不变
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);//延时45us左右,在读取下一位
	}
//	EA = 1;
	return dat;
}
//-----------------------------------------------------

6.比赛时需要改写onewire驱动

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include "onewire.h"
#include <intrins.h>


unsigned int t_data = 0x0000;
//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t *= 12;//需要把延时扩大为原来的12倍
	while(t--);
}

//===============================================
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	//EA = 0;
	for(i=0;i<8;i++)
	{
		DQ = 0;//迅速拉低总线10~15us
		DQ = dat&0x01;//要写入的这一位是1,DQ就=1,要写入的这位是0,DQ就等于0
		Delay_OneWire(5);//延时一会20~45us,等待DS18来读
		DQ = 1;//释放总线
		dat >>= 1;//开始准备写下一位
	}
	
	Delay_OneWire(5);
	//EA = 1;
}
//===============================================
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;//储存读取到的数据
  //EA = 0;
	for(i=0;i<8;i++)
	{
		DQ = 0;//迅速拉低
		//_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
		dat >>= 1;//这是从最高位写的,所以要相佑方移动到第一位
		DQ = 1;//把这个置高,才能让DS18来决定他便成1还是0
		if(DQ)//如果读到1,则把最高位写1,其他位不变
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);//延时45us左右,在读取下一位
	}
//	EA = 1;
	return dat;
}
//-----------------------------------------------------
//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;//作为返回数值
  //	EA = 0;防止中断打扰时序
//  	DQ = 1;
//  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);//480~960 us
  	DQ = 1;//释放总线
  	Delay_OneWire(10); //15~60  DS18B20会来拉低总线
    initflag = DQ;     //读取18B20的复位应答信号
  	Delay_OneWire(5);//等待60~240us总线释放
	//EA = 1;
  
  	return initflag;//应答信号为低电平,表示复位成功
}

 void rd_temperature()
{
	
  //unsigned char i;
	unsigned char LSB = 0X00, MSB = 0X00;
	init_ds18b20();
	Write_DS18B20(0xcc);//跳过ROM
	Write_DS18B20(0x44);//开始温度转换
	
//	for(i = 125; i > 0; i--)//延时750ms
//	{
//		Display();
//	}
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);//读取温度
	LSB = Read_DS18B20();
	MSB = Read_DS18B20();
	init_ds18b20();
	t_data = MSB;
	t_data <<= 8;
	t_data = t_data | LSB;
	if((t_data & 0xf800) == 0x0000)
	{
		t_data >>= 4;
		t_data *= 10;
		t_data = t_data + (LSB & 0x0f) * 0.625;
	}
	
	
	
}





头文件onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#include "stc15f2k60s2.h"
#include "SEG.h"
sbit DQ = P1^4;  //单总线接口

void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
void rd_temperature();

#endif

;原文链接:https://blog.csdn.net/qq_53971060/article/details/115675688
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐