蓝桥杯--DS18B20温度模块的学习

1-Wire操作


单总线操作对时序要求好像非常严格,这里用到的延时函数在底部。对延时函数的时间不了解又想了解的话可以参考STC的1T单片机的软件延时时间的计算

初始化

总线初始化时序

bit Init_DS18B20()
{
	bit InitFlag;
	EA = 0;		//禁止中断响应
	DQ = 1;
	delay(1);
	DQ = 0;
	delay(365);//480
	DQ = 1;
	delay(45);//60
	InitFlag = DQ;
	EA = 1;		//使能中断
	delay(180);//240
	return InitFlag;
}
读/写

写时序

  • 写: All write time slots must be a minimum of 60µs in duration with a minimum of a 1µs recovery time between individual write slots. Both types of write time slots are initiated by the master pulling the 1-Wire bus low.

每个写时序必须持续60us并且有1us的恢复时间。每个写时序都是由主机拉低总线初始化的。

写1:在将总线拉低(超过1us)之后,必须在15us之内释放总线。

写0:在将总线拉低之后,在整个时段主设备一直拉低总线。(60-120us)

DS18B20将在写初始化后的15~60us之间进行采样,一般会在30us时。所以每个写时段都将数据放在线上60us。

void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	DQ = 1;
	for(i=0;i<8;i++)
	{
		//EA = 0;
		DQ = 0;	 	//拉低总线
		delay(1);	//2us
		DQ = dat&0x01;
		dat >>= 1;
		delay(50);	//60us
		DQ = 1;		//释放总线
        delay(1);	//2us
		//EA = 1;
	}
	
}

读时序

读: All read time slots must be a minimum of 60µs in duration with a minimum of a 1µs recovery time
between slots. A read time slot is initiated by the master device pulling the 1-Wire bus low for a minimum of 1µs and then releasing the bus。

每个读时段必须持续60us并且有1us的恢复时间。每个读时段都是由主机拉低总线超过1us然后释放来初始化的。

初始化后要尽快释放总线,然后在15us内对总线上数据采样。

unsigned char Read_DS18B20()
{
	unsigned char temp,i;
	DQ = 1;
	for(i=0;i<8;i++)
	{
		//EA = 0;
		temp >>= 1;
		DQ = 0;
		delay(1);		//2
		DQ = 1;
		delay(2);		//4
		if(DQ)
			temp |= 0x80;
		delay(45);		//60
		DQ = 1;			
        delay(1);		//
		//EA = 1;
	}
	return temp;
}

读时序的时间说明

Figure15: 初始化时间+释放总线时间+采样时间 < 15us

Figure16: 初始化时间和释放总线时间越小越好,但初始化时间必须大于1us;


总线ROM命令


 总线初始化后 写入的命令,对总线上的设备进行查询,操作,控制。

SKIP ROM [CCh]----这个用的多,几乎只用这一个

 跳过ROM,CT107D板子上的DS18B20一般就用这个命令了。

SERACH ROM [F0h]

  识别总线上所有从设备的ROM编码

READ ROM [33h]

 当总线上只有一个从设备时才可以使用。不需要搜索命令就可以读取从设备的64为ROM编码。

MATCH ROM [55h]

 该命令后紧接着发送64位设备号,只有与之匹配的从设备才可以响应。

ALARM SEARCH [ECh]

报警搜索


DS18B20操作


 每次对DS18B20操作时,都需要进行下面操作:总线初始化----写ROM命令(跳过0xCC)----对DS18B20进行操作

DS18B20的寄存器

 下图为DS18B208的内存结构。其中Byte2,3,4可以的内容可以储存到EEPROM,掉电不会丢失,上电会自动载入。
DS18B20的内存

Byte0和Byte1

温度暂存器
​    *上电复位 寄存器中的数值为+85℃

 这里显示的是精度为12位时的寄存器内容。当精度为11位时,BIT0无定义。当精度为10位时,BIT0,BIT1无定义。当精度为9位时,BIT0,BIT1,BIT2无定义。

Byte2和Byte3

温度报警界限暂存器
 温度报警的上限和下限。每次温度转换完成后,会与该暂存器中上下界进行比较,超过则会置位温度报警位(比赛用不到,我也用不到,就没仔细研究)

Byte4

配置暂存器
这里的R1和R0决定温度转换精度,可以通过更改配置寄存区更改转换精度。

R1和R0对转换精度的控制

DS18B20功能命令


CONVERT T [44h]

 温度转换,转换结果存储在寄存器中。在寄生电源供电模式,在此命令的10us内必须强制拉高数据线。

WRITE SCRATCHPAD [4Eh]

 写入暂存寄存器,主设备向DS18B20写入3个字节的数据。第一个字节TH,第二个为TL,第三个为配置寄存器。低位在前。三个字节必须在复位之前全部写完,否则数据会损坏。

READ SCRATCHPAD [BEh]

 读取暂存寄存器中存储的值。数据从 Byte 0 的低位开始传送直到第 9个字节(Byte 8 - CRC)读取完毕。主设备若只需要暂存寄存器中的部分数据,则可以在读取数据中通过复位来终止。

COPY SCRATCHPAD [48h]

 该命令为将暂存寄存器中的 TH、TL 及配置寄存器(Byte 2,Byte 3 和 Byte 4)的值拷贝至EEPROM 中。如果该设备采用的“寄生电源”供电模式,在该命令发送后 10us(最大)内主设备必须强制拉高 1-Wire 总线超过 10ms。

RECALL E 2 [B8h]

 该命令将温度报警触发值(TH 和 TL)及配置寄存器的数据从 EEPROM 中召回至暂存寄存器中的 Byte 2,Byte 3 和 Byte4 中。主设备可以在召回 EEPROM 命令之后执行读取数据时序,若DS18B20 正在进行召回 EEPROM 则会响应 0 电平,召回 EEPROM 完成则响应 1 电平。召回数据操作在上电初始化后会自动执行一次,所以设备在上电期间暂存寄存器中一直会有有效的数据。

READ POWER SUPPLY [B4h]

 主设备通过执行该命令之后再执行读取数据时序来确定总线上的 DS18B20 是否是由“寄生电源”供电。在读取数据时序中,“寄生电源”供电的 DS18B20 将会拉低总线,外部电源独立供电模式的 DS18B20 则会释放总线让其保持在高电平。

流程

  • 总线初始化

  • ROM命令

  • DS18B20命令(紧跟着数据的传送)

例1:温度转换并读取
Init_DS18B20();		//初始化
Write_DS18B20(0xCC);//ROM命令     	//跳过
Write_DS18B20(0x44);//DS18B20命令 	//转换温度
//等待温度转换(750ms)
//这里可以用定时器来计时
Init_DS18B20();		//初始化
Write_DS18B20(0xCC);//ROM命令			//跳过
Write_DS18B20(0xBE);//DS18B20命令		//读取暂存器
LSB = Read_DS18B20();//数据的传送		//Byte0   LSB
MSB = Read_DS18B20();//数据的传送		//Byte1   MSB
//这里DS18B20会继续发送,但是我们不需要了,这里停止就好了。再次初始化就会停止。
例2:更改暂存器的值
Init_DS18B20();			//初始化
Write_DS18B20(0xCC);	//ROM命令
Write_DS18B20(0x4E);	//DS18B20命令
Write_DS18B20(TL);		//写TL给寄存器TL
Write_DS18B20(TH);		//写TH给寄存器TH
Write_DS18B20(Con_g);	//写Con_g给配置寄存器
//上面三个字节必须在下次初始化之前写完。
//更改精度为9位时,Con_g = 0x1f;
/*****当把这些数据写入暂存器之后,
//****还可以通过命令将这三位数据存入EEPROM*****/
Init_DS18B20();
Write_DS18B20(0xCC);	//ROM
Write_DS18B20(0x48);	//DS18B20命令,写入EEPROM
//此命令之后需要在10us内将总线拉高,持续10ms。
//当然也可以从EEPROM中读取,命令为[0xB8]

另外注意:
数据手册截图 大概说的是在:使用寄生电源时,温度转换和数据传送(写入EEPROM)时,总线必须在命令后10us内拉高,并且在这期间转换时间或10ms内总线不能有其他行为。
 还有,前面说到单总线对时间要求严格,所以最后在初始化、数据传输时候关闭中断,但数据传输中,位与位之前对时间没有要求,这里可以使能中断,响应中断。

 头一次以这种方式记笔记,希望复习的时候我自己还能看懂自己写的什么。如有不对的地方,也请大佬们指正。
  • 附上代码
#include "stc15.h"//STC15的头文件
sbit DQ = P1^4;
void delay(unsigned int t) //t*1.35us
{
	while(t--);
}
bit Init_DS18B20()
{
	bit InitFlag;
	//EA = 0;	//禁止中断响应
	DQ = 1;
	delay(1);
	DQ = 0;
	delay(365);//480
	DQ = 1;
	delay(45);//60
	InitFlag = DQ;
	//EA = 1;	//使能中断
	delay(180);//240
	return InitFlag;
}
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	DQ = 1;
	for(i=0;i<8;i++)
	{
		//EA = 0;
		DQ = 0;
		delay(1);//2us
		DQ = dat&0x01;
		dat >>= 1;
		delay(50);	//60us
		DQ = 1;		//释放总线
		delay(1);		//2us
		//EA = 1;
	}
}

unsigned char Read_DS18B20()
{
	unsigned char temp,i;
	DQ = 1;
	for(i=0;i<8;i++)
	{
		//EA = 0;
		temp >>= 1;
		DQ = 0;
		delay(1);			//2us
		DQ = 1;
		delay(2);			//2us
		if(DQ)
			temp |= 0x80;
		delay(45);		//60us
		DQ = 1;
		//EA = 1;
	}
	return temp;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值