1-Wire单总线—DS18B20学习总结

本文记录了笔者通过对DS18B20温度传感器的学习,进一步学习1-Wire单总线通信协议的过程和学习总结。

DS18B20的封装

DS18B20只有两种封装,一是To-92,二是8-pin SOIC(150mil)。通常我们学习和使用的多为To-92封装。
1-Wire单总线—DS18B20学习总结_第1张图片

DS18B20的特性

根据官方文档,我摘取了几点我觉得重要的特性。
1、采用1-Wire通信协议,只需要一个引脚就可以通信。
2、可由数据线供电(寄生电源),供电范围为3.0V至5.5V。
3、测量温度从-55°C到125°C。华氏当量为-67°F至257°F。
4、在-10°C到85°C温度范围内,测量误差为±0.5°C。
5、温度计分辨率可从9位到12位编程。
6、在12位分辨率下,转换时间不超过750ms。

DS18B20的组成

DS18B20有四个主要的数据组件:
1、64位激光ROM
2、温度传感器
3、非易失性温度报警触发TH和TL
4、配置寄存器

温度与数据转换关系

DS18B20在执行温度转换后,其温度数据以16位带符号扩展的二进制补码格式存储在Scratchpad内存中。
在12位分辨率下,内部数据与温度转换关系如下图。
举个例子,如-25.0625°C。
其二进制码为1111 1110 0110 1111,因为该数据为补码,所以原数据按位取反后再加一得到原码为0000 0001 1001 0001。然后代入各位的权得到1x24+1x23+1x20+1x2-4x0.0625=25.0625。
1-Wire单总线—DS18B20学习总结_第2张图片

1-Wire单总线协议程序

该协议由几种类型的信号组成:复位脉冲,存在脉冲,写0,写1,读0,读1。所有这些信号,除了存在脉冲,其他主机发起。
复位脉冲与存在脉冲统称初始化。主机对从机进行每个操作前,均需要初始化。
初始化的时序图如下。
1-Wire单总线—DS18B20学习总结_第3张图片
1-Wire单总线通信协议的DQ线既作为输出线也作为输入线。
在通信过程中,要随时切换引脚工作模式,在STM32中可通过库函数很方便地改变模式。当总线作为输出时,需引脚设置为推挽输出模式,当总线作为输入时,需将引脚设置为上拉输入模式(相关程序参考自野火拓展模块DS18B20温度传感器实验例程)。

static void DS18B20_Rst(void)
{
	DS18B20_Mode_Out_PP();//将DQ引脚设置为推挽输出模式
	DS18B20_DQ_0;//拉低DQ引脚
	Delay_us(750);//延时750us 480~960us
	DS18B20_DQ_1;//拉高DQ引脚
	Delay_us(15);//等待从机响应时间 15~60us
}
static uint8_t DS18B20_Presence(void)
{
	uint8_t pulse_time = 0;
	DS18B20_Mode_IPU();//将DQ引脚设置为上拉输入模式
	
	while( DS18B20_DQ_IN() && pulse_time<100 )//等待低电平脉冲到来时间 15~60us
	{
		pulse_time++;
		Delay_us(1);
	}	
	if( pulse_time >=100 )//等待时间超时
		return 1;
	else
		pulse_time = 0;
	while( !DS18B20_DQ_IN() && pulse_time<240 )//低电平脉冲持续时间 60~240us
	{
		pulse_time++;
		Delay_us(1);
	}	
	if( pulse_time >=240 )//低电平持续时间超时
		return 1;
	else
		return 0;
}

1-Wire单总线—DS18B20学习总结_第4张图片

static uint8_t DS18B20_ReadBit(void)//读取一个bit
{
	uint8_t dat;
	DS18B20_Mode_Out_PP();//将DQ引脚设置为推挽输出模式
	DS18B20_DQ_0;
	Delay_us(10);//进行读数据操作前,需由主机产生不超过15us的低电平脉冲
	DS18B20_Mode_IPU();//将DQ引脚设置为上拉输入模式
	
	if( DS18B20_DQ_IN() == SET )
		dat = 1;
	else
		dat = 0;
		
	Delay_us(45);//整个读数据时间(60~120us)减去前面低电平脉冲时间 
	return dat;
}

static uint8_t DS18B20_ReadByte(void)//读取一个byte 低位先行
{
	uint8_t i, j, dat = 0;	
	for(i=0; i<8; i++) 
	{
		j = DS18B20_ReadBit();		
		dat = (dat) | (j<<i);
	}
	
	return dat;
}

1-Wire单总线—DS18B20学习总结_第5张图片

static void DS18B20_WriteByte(uint8_t dat)//写入一个byte 低位先行
{
	uint8_t i, testb;
	DS18B20_Mode_Out_PP();//将DQ引脚设置为推挽输出模式
	for( i=0; i<8; i++ )
	{
		testb = dat&0x01;
		dat = dat>>1;//写1/0时间 高低电平持续时间 60~120us		
		if (testb)
		{			
			DS18B20_DQ_0;
			Delay_us(8);//写入1前 需要先拉低总线 1~15us
			DS18B20_DQ_1;
			Delay_us(70);
		}		
		else
		{			
			DS18B20_DQ_0;
			Delay_us(70);
			DS18B20_DQ_1;			
			Delay_us(2);//恢复到下一个周期 需重信拉高总线 1us~无穷 
		}
	}
}

FUNCTIONS VALUE
Read ROM 0x33
Match ROM 0x55
Skip ROM 0xCC
Search ROM 0xF0
Alarm Search 0xEC
Write Scratchpad 0x4E
Read Scratchpad 0xBE
Copy Scratchpad 0x48
Convert T 0x44
Recall E2 0xB8
Read Power Supply 0xB4
static void DS18B20_SkipRom ( void )
{
	DS18B20_Rst();	   
	DS18B20_Presence();	 
	DS18B20_WriteByte(0XCC);//写入0xCC 执行skipROM操作
	
}
float DS18B20_GetTemp_SkipRom ( void )
{
	uint8_t tpmsb, tplsb;
	short s_tem;
	float f_tem;
	
	
	DS18B20_SkipRom ();
	DS18B20_WriteByte(0X44);//转换命令
	DS18B20_SkipRom ();
    DS18B20_WriteByte(0XBE);//读取命令
	
	tplsb = DS18B20_ReadByte();//低位先行		 
	tpmsb = DS18B20_ReadByte(); 
	s_tem = tpmsb<<8;
	s_tem = s_tem | tplsb;
	
	if( s_tem < 0 )
		f_tem = (~s_tem+1) * (-0.0625);//负数二进制补码 取反加一后为原码
	else
		f_tem = s_tem * 0.0625;
	
	return f_tem; 	
}

另外在存在多个从机的情况下,可以采用Match ROM的模式与不同从机进行通信。其64位激光ROM组成为:
在这里插入图片描述
在匹配ROM模式下,读取温度数据步骤如下。

static void DS18B20_MatchRom ( void )
{
	DS18B20_Rst();
	DS18B20_Presence();
	DS18B20_WriteByte(0X55);//匹配ROM命令	
}
float DS18B20_GetTemp_MatchRom ( uint8_t * ds18b20_id )
{
	uint8_t tpmsb, tplsb, i;
	short s_tem;
	float f_tem;
	
	DS18B20_WriteByte(0x33);//读ROM命令 低位先行
	for ( i = 0; i < 8; i ++ )
	  ds18b20_id [ uc ] = DS18B20_ReadByte();
	
	DS18B20_MatchRom ();//匹配ROM          
	for(i=0;i<8;i++)
		DS18B20_WriteByte ( ds18b20_id [ i ] );	//写入ID数据
	
	DS18B20_WriteByte(0X44);//转换命令
	
	DS18B20_MatchRom ();//匹配ROM  
	for(i=0;i<8;i++)
		DS18B20_WriteByte ( ds18b20_id [ i ] );	//写入ID数据
	
	DS18B20_WriteByte(0XBE);
	tplsb = DS18B20_ReadByte();		 
	tpmsb = DS18B20_ReadByte(); 
	
	s_tem = tpmsb<<8;
	s_tem = s_tem | tplsb;
	
	if( s_tem < 0 )
		f_tem = (~s_tem+1) * (-0.0625);	
	else
		f_tem = s_tem * 0.0625;
	
	return f_tem; 		
}

DS18B20可通过改变便笺存储器中一个8bits大小的配置寄存器中对应两位二进制的值,进而改变分辨率大小。
便笺存储器的结构如下图。
1-Wire单总线—DS18B20学习总结_第6张图片
配置寄存器的结构如下图。
1-Wire单总线—DS18B20学习总结_第7张图片
R1R0值对应分辨率如下表。
1-Wire单总线—DS18B20学习总结_第8张图片

你可能感兴趣的:(1-Wire单总线—DS18B20学习总结)