×
单片机 > 单片机程序设计 > 详情

STC89C52MCU -- DS18B20温度传感器

发布时间:2020-05-18 发布时间:
|

DS18B20温度传感器采用“单总线”串行传输方式

目前单片机数据传输的串行总线主要由Inter IC Bus, SPI和SCI。其中IIC总线以同步串行二线方式进行通信(一条数据线、一条时钟线),SPI总线则是以同步串行三线方式进行通信(一条时钟线,一条数据输入线,一条数据输出线),而SCI总线是以异步方式进行通信(一条输入线,一条输出线)。DS18B20采用单条信号线,既可以传输时钟又可以传输数据,而且数据是双向传输,因而这种总线技术具有线路简单,硬件开销少、陈本低廉,便于总线扩展等优点。单总线适用于单主机系统,能够控制一个或者多个从机设备。

设备(主机或者从机)通过一个漏极开路或三态端口连接至数据线,以允许设备在不发送数据时能够释放总线,而让求他设备使用总线。单总线通常要求外接一个约为5Kohm的上拉电阻。

工作原理


64位光刻ROM各位定义
8位CRC码48位序列号8位产品类型标号


首先是DS18B20的控制命令

1. 33H - 读ROM。读取DS18B20温度传感器ROM中的编码(64位地址)

2. 55H- 匹配ROM。发出此命令后,接着发出64位ROM码,访问单总线上相对应的DS18B20并使之作出响应,为下一步对该模块读写做准备;

3. F0H- 搜索ROM。用于确定挂载在同一总线上DS18B20的个数,识别64位ROM地址,位操作和期间做准备。

4. CCH - 跳过ROM。忽略64位ROM地址,直接向18B20发温度变换指令,适用于一个从几工作形式

5. ECH - 告警搜索命令。执行后只有温度超多设定值上限或者下线的时候芯片才做出响应。


64位光刻ROM中的序号是粗长前就被可好的,他可以看作该模块的地址序列号。光刻ROM的作用就是使每个DS18B20都具有不一样的序列号,这样就可以实现在一条总线上挂载多个DS18B20的目的。

常见模式:当主机需要与众多在线DS18B20中某一个连接时,首先将主机逐个与DS18B20挂载,读出器序列号,然后再将所有的DS18B20挂载到总线上,单片机发出匹配ROM命令(55H),紧接着主机提供64位序列号之后的操作就只针对此DS18B20。

如果主机只与一个DS18B20进行操作,就不需要读取ROM编码,以及匹配编码,只要用跳过ROM指令,就可以进行如下的温度转化和读取操作。

1. 44H -- 温度转换。启动DS18B20进行温度转换,12转换时间长度为750ms(9位时长93.75ms)。结果存入内部RAM中。

2. BEH -- 读暂存器。读内部RAM中的9字节的温度数据 

3. 4EH -- 写暂存器;发出向内部RAM的第2,3字节写上、下限数温度数据命令,紧跟该命令之后,是传输两字节数据。

4. 48H-- 复制暂存器;将RAM中的第2、3字节内容复制到EEPROM中。

5.B8H -- 重调EEPROM。将EEPROM的内容复制到RAM中的第3、4字节。

6. B4H -- 读取供电方式。读DS18B20的供电模式,寄生供电时,DS18B20发送0;外接电源供电时,DS18B20发送1;

高速暂存RAM


高速暂存RAM
寄存器内容字节地址
温度值低位(LSB)0
温度值高位(MSB)1
高温限制(TH)2
低温限制(LH)3
配置寄存器4
保留5
保留6
CRC校验值8

少了一个保留至在第七位

温度数据在高速暂存寄存器的第0、1字节中存储格式


温度数据存储格式
D7D6D5D4D3D2D1D0








D15D14D13D12D11D10D9D8








DS18B20在出厂默认设置是12位精度,其中最高位为符号位,即温度值共11位,单片机在读取数据时,一次会读取两字节共16位,读完后将低11位的二进制数转化为十进制数后,再乘以0..625便为所测量的实际温度。另外需要判断温度的正负值、前五位数字为符号位,着5位同时变化。同时为1时候,读取的温度为负值,且测量到的温度需要取反加一再乘以0.0625才可以得到正确温度值,前五位为0时,读取温度为正值,直接乘以0.0625即可。

DS18B20编程例子

sbit ds = P2^2;

//DS18B20复位操作, 信号线由低电平到高电平启动DS18B20,高低电平时间需要满足时间

void dsreset()

{

uint i;

ds =0;

i =103;

while(i)

i--;

ds =1;

i=4;

while(i)

i--;

}


//读取1位数据函数(1->0->1)

bit tempreadbit(void)

{

uint i;

bit dat;

ds = 0;

i++;

ds = 1;

i++; i++;

dat = da;

i = 8;

while(i>0)

i--;

return dat;

}


//读取一个字节函数

uchar tempream(void)

{

uchar i,j,dat;

dat =0;

while(i=0;i<8;i++)

{

j = tempreadbit();

dat = (j<<7)|(dat>>1);

}

return dat;

}


//向DS18B20写一个字节

void tempwritebyte(uchar dat)

{

uint i;

uchar j;

bit testb;

for(j=1;j<=8;j++)

{

testb = dat &0x01;

dat = dat<<1;

if(testb)

{

ds = 0;

i++;i++;

ds =1;

i =8;while(i) i--;

}

else

{

ds =0;

i =8;while(i) i--;

ds =1;

i++;i++;

}

}

}

//获取温度并转换

void tempchange()

{

dsreset();

delay(1);

tempwritebyte(0xcc);//跳过ROM指令

tempwritebyte(0x44);//写温度转换指令

}

//读取寄存器中存储的温度数据

uint_temp()

{

uchar a,b;

dsreset();

delay(1);

tempwritebyte(0xcc);

tempwritebyte(0xbe);

a = tempread();//低88位

b = tempread();//高8位

temp = b;

temp <<=8;

temp = temp | a ;

f_temp = temp * 0.0625;//温度在寄存器中为12位

temp = f_temp * 10+ 0.5;//乘以10表示小数点后面只去一位,加上0.5是四舍五入

f_temp =  f_temp + 0.05;

return temp;

}




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈AVR中定时器几种工作模式