ds18b20详解及程序.docx

上传人:b****5 文档编号:5688780 上传时间:2022-12-31 格式:DOCX 页数:11 大小:21.80KB
下载 相关 举报
ds18b20详解及程序.docx_第1页
第1页 / 共11页
ds18b20详解及程序.docx_第2页
第2页 / 共11页
ds18b20详解及程序.docx_第3页
第3页 / 共11页
ds18b20详解及程序.docx_第4页
第4页 / 共11页
ds18b20详解及程序.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

ds18b20详解及程序.docx

《ds18b20详解及程序.docx》由会员分享,可在线阅读,更多相关《ds18b20详解及程序.docx(11页珍藏版)》请在冰豆网上搜索。

ds18b20详解及程序.docx

ds18b20详解及程序

最近都在学习和写单片机的程序,今天有空又模仿DS18B20温度测量显示实验写了一个与DS18B20基于单总线通信的程序.

DS18B20数字温度传感器(参考:

智能温度传感器DS18B20的原理与应用)是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。

因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。

DS18B20产品的特点:

(1)、只要求一个I/O口即可实现通信。

(2)、在DS18B20中的每个器件上都有独一无二的序列号。

(3)、实际应用中不需要外部任何元器件即可实现测温。

(4)、测量温度范围在-55到+125℃之间;在-10~+85℃范围内误差为±5℃;

(5)、数字温度计的分辨率用户可以从9位到12位选择。

将12位的温度值转换为数字量所需时间不超过750ms;

(6)、内部有温度上、下限告警设置。

DS18B20引脚分布图

DS18B20详细引脚功能描述:

1、GND地信号;

2、DQ数据输入出引脚。

开漏单总线接口引脚。

当被用在寄生电源下,此引脚可以向器件提供电源;漏极开路,常太下高电平.通常要求外接一个约5kΩ的上拉电阻.

3、VDD可选择的VDD引脚。

电压范围:

3~;当工作于寄生电源时,此引脚必须接地。

DS18B20存储器结构图

暂存储器的头两个字节为测得温度信息的低位和高位字节;

第3,4字节是TH和TL的易失性拷贝,在每次电复位时都会被刷新;

第5字节是配置寄存器的易失性拷贝,同样在电复位时被刷新;

第9字节是前面8个字节的CRC检验值.

配置寄存器的命令内容如下:

0

R1

R0

1

1

1

1

1

MSB                                                               LSB

R0和R1是温度值分辨率位,按下表进行配置.默认出厂设置是R1R0=11,即12位.

温度值分辨率配置表

R1

R0

分辨率

最大转换时间(ms)

0

0

9bit

(tconv/8)

0

1

10bit

(tconv/4)

1

0

11bit

375(tconv/2)

1

1

12bit

750(tconv)

4种分辨率对应的温度分辨率为0.5℃,0.25℃,0.125℃,0.0625℃(即最低一位代表的温度值)

12位分辨率时的两个温度字节的具体格式如下:

低字节:

2^3

2^2

2^1

2^0

2^-1

2^-2

2^-3

2^-4

高字节:

S

S

S

S

S

2^6

2^5

2^4

其中高字节前5位都是符号位S,若分辨率低于12位时,相应地使最低为0,如:

当分辨率为10位时,低字节为:

2^3

2^2

2^1

2^0

2^-1

2^-2

0

0

高字节不变....

一些温度与转换后输出的数字参照如下:

温度

数字输出

换成16进制

+125℃

00000111 

07D0H

+85℃

0000010101010000

0550H

+25.0625℃

00000001

0191H

+10.125℃

00000000

00A2H

+0.5℃

0000000000001000

0008H

0℃

0000000000000000

0000H

-0.5℃

FFF8H

-10.125℃

01011110

FFE5H

-25.0625℃

01101111

FF6FH

-55℃

FC90H

由上表可看出,当输出是负温度时,使用补码表示,方便计算机运算(若是用C语言,直接将结果赋值给一个int变量即可).

DS18B20的使用方法:

由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对单片机来说,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。

由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。

DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。

该协议定义了几种信号的时序:

初始化时序(dsInit()实现)、读时序(readByte())、写时序(writeByte())。

所有时序都是将主机作为主设备,单总线器件作为从设备。

而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。

数据和命令的传输都是低位在先。

DS18B20与单片机连接电路图:

利用软件模拟DS18B20的单线协议和命令:

主机操作DS18B20必须遵循下面的顺序

1.初始化

单线总线上的所有操作都是从初始化开始的.过程如下:

1)请求:

主机通过拉低单线480us以上,产生复位脉冲,然后释放该线,进入Rx接收模式.主机释放总线时,会产生一个上升沿脉冲.

DQ:

1->0(480us+)->1 

2)响应:

DS18B20检测到该上升沿后,延时15~60us,通过拉低总线60~240us来产生应答脉冲.

DQ:

1(15~60us)->0(60~240us)

3)接收响应:

主机接收到从机的应答脉冲后,说明有单线器件在线.至此,初始化完成.

DQ:

0

2.ROM操作命令

当主机检测到应答脉冲,便可发起ROM操作命令.共有5类ROM操作命令,如下表

 命令类型 

命令字节

功能

ReadRom  读ROM  

33H

读取激光ROM中的64位,只能用于总线上单个DS18B20器件情况,多挂时会发生数据冲突

MatchRom匹配ROM

55H

此命令后跟64位ROM序列号,寻址多挂总线上的对应DS18B20.只有序列号完全匹配的DS18B20才能响应后面的内存操作命令,其他不匹配的将等待复位脉冲.可用于单挂或多挂两种情况.

SkipRom  跳过ROM

CCH

可无须提供64位ROM序列号即可运行内存操作命令,只能用于单挂.

SearchRom搜索ROM

F0H

通过一个排除法过程,识别出总线上所有器件的ROM序列号

AlarmSearch告警搜索

ECH

命令流程与SearchRom相同,但DS18B20只有最近的一次温度测量时满足了告警触发条件的,才会响应此命令.

3.内存操作命令

在成功执行ROM操作命令后,才可使用内存操作命令.共有6种内存操作命令:

命令类型

命令字节

功能

WriteScratchpad

写暂存器

4EH

写暂存器中地址2~地址4的3个字节(TH,TL和配置寄存器)在发起复位脉冲之前,3个字节都必须要写.

ReadScratchpad

读暂存器

BEH

读取暂存器内容,从字节0~一直到字节8,共9个字节,主机可随时发起复位脉冲,停止此操作,通常我们只需读前5个字节.

CopyScratchpad

复制暂存器

48H

将暂存器中的内容复制进EERAM,以便将温度告警触发字节存入非易失内存.如果此命令后主机产生读时隙,那么只要器件还在进行复制都会输出0,复制完成后输出1.

ConvertT 

温度转换

44H

开始温度转换操作.若在此命令后主机产生时隙,那么只要器件还在进行温度转换就会输出0,转换完成后输出1.

RecallE2   

重调E2暂存器

B8H

将存储在EERAM中的温度告警触发值和配置寄存器值重新拷贝到暂存器中,此操作在DS18B20加电时自动产生.

ReadPowerSupply

读供电方式

B4H

主机发起此命令后每个读数时隙内,DS18B20会发信号通知它的供电方式:

0寄生电源,1外部供电.

4.数据处理

DS18B20要求有严格的时序来保证数据的完整性.在单线DQ上,有复位脉冲,应答脉冲,写0,写1,读0,读1这6种信号类型.除了应答脉冲外,其它都由主机产生.数据位的读和写是通过读、写时隙实现的.

1)写时隙:

当主机将数据线从高电平拉至低电平时,产生写时隙.所有写时隙都必须在60us以上,各写时隙间必须保证1us的恢复时间.

写"1":

主机将数据线DQ先拉低,然后释放15us后,将数据线DQ拉高;

写"0":

主机将DQ拉低并至少保持60us以上.

2)读时隙:

当主机将数据线DQ从高电平拉至低电平时,产生读时隙.所有读时隙最短必须持续60us,各读时隙间必须保证1us的恢复时间.

读:

主机将DQ拉低至少1us,.此时主机马上将DQ拉高,然后就可以延时15us后,读取DQ即可.

源代码:

(测量范围:

0~99度)

DS18B20

  1#include <>

  23f4f7f6f7c 14void delay(unsigned char i)

 15{

 16    unsigned char j, k;

 17    for(j = i; j > 0; j--)

 18    {

 19        for(k = 125; k > 0; k--);

 20    }

 21}

 22

 23 18void delay(unsigned int i)

 19{

 20    unsigned int j;

 21    while(i--)

 22    {

 23        for(j = 0; j < 125; j++);

 24    }

 25}

 26

 27//初始化DS18B20

 28//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动

 29void dsInit()

 30{

 31    //对于时钟, unsigned int型的i, 作一个i++操作的时间大于为8us

 32    unsigned int i;  

 33    ds = 0;

 34    i = 100;   //拉低约800us, 符合协议要求的480us以上

 35    while(i>0) i--;

 36    ds = 1;    //产生一个上升沿, 进入等待应答状态

 37    i = 4;

 38    while(i>0) i--;

 39}

 40

 41void dsWait()

 42{

 43     unsigned int i;

 44     while(ds);  

 45     while(~ds);  //检测到应答脉冲

 46     i = 4;

 47     while(i > 0) i--;

 48}

 49

 50//向DS18B20读取一位数据

 51//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平, 

 52//之后DS18B20则会输出持续一段时间的一位数据

 53bit readBit()

 54{

 55    unsigned int i;

 56    bit b;

 57    ds = 0;

 58    i++;   //延时约8us, 符合协议要求至少保持1us

 59    ds = 1; 

 60    i++; i++;  //延时约16us, 符合协议要求的至少延时15us以上

 61    b = ds;

 62    i = 8; 

 63    while(i>0) i--;  //延时约64us, 符合读时隙不低于60us要求

 64    return b;

 65}

 66

 67//读取一字节数据, 通过调用readBit()来实现

 68unsigned char readByte()

 69{

 70    unsigned int i;

 71    unsigned char j, dat;

 72    dat = 0;

 73    for(i=0; i<8; i++)

 74    {

 75        j = readBit();

 76        //最先读出的是最低位数据

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

 78    }

 79    return dat;

 80}

 81

 82//向DS18B20写入一字节数据

 83void writeByte(unsigned char dat)

 84{

 85    unsigned int i;

 86    unsigned char j;

 87    bit b;

 88    for(j = 0; j < 8; j++)

 89    {

 90        b = dat & 0x01;

 91        dat >>= 1;

 92        //写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1

 93        if(b)   

 94        {

 95            ds = 0;

 96            i++; i++;  //拉低约16us, 符号要求15~60us内

 97            ds = 1;    

 98            i = 8; while(i>0) i--;  //延时约64us, 符合写时隙不低于60us要求

 99        }

100        else  //写"0", 将DQ拉低60us~120us

101        {

102            ds = 0;

103            i = 8; while(i>0) i--;  //拉低约64us, 符号要求

104            ds = 1;

105            i++; i++;  //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了

106        }

107    }

108}

109

110//向DS18B20发送温度转换命令

111void sendChangeCmd()

112{

113    dsInit();    //初始化DS18B20, 无论什么命令, 首先都要发起初始化

114    dsWait();   //等待DS18B20应答

115    delay

(1);    //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号

116    writeByte(0xcc); //写入跳过序列号命令字 Skip Rom

117    writeByte(0x44); //写入温度转换命令字 Convert T

118}

119

120//向DS18B20发送读取数据命令

121void sendReadCmd()

122{

123    dsInit();

124    dsWait();

125    delay

(1);

126    writeByte(0xcc); //写入跳过序列号命令字 Skip Rom

127    writeByte(0xbe); //写入读取数据令字 Read Scratchpad

128}

129

130//获取当前温度值

131int getTmpValue()

132{

133    unsigned int tmpvalue;

134    int value; //存放温度数值

135    float t;

136    unsigned char low, high;

137    sendReadCmd();

138    //连续读取两个字节数据

139    low = readByte(); 

140    high = readByte();

141    //将高低两个字节合成一个整形变量

142    //计算机中对于负数是利用补码来表示的

143    //若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value

144    tmpvalue = high;

145    tmpvalue <<= 8;

146    tmpvalue |= low;

147    value = tmpvalue;

148    

149    //使用DS18B20的默认分辨率12位, 精确度为度, 即读回数据的最低位代表度

150    t = value * ;

151    //将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入

152    //如t=, 进行计数后, 得到value = 1106, 即 度

153    //如t=, 进行计数后, 得到value = -1106, 即 度

154    value = t * 100 + (value > 0   :

 ; //大于0加, 小于0减

155    return value;

156}

157

158unsigned char const timeCount = 3; //动态扫描的时间间隔

159//显示当前温度值, 精确到小数点后一位

160//若先位选再段选, 由于IO口默认输出高电平, 所以当先位选会使数码管出现乱码

161void display(int v) 

162{

163    unsigned char count;

164    unsigned char datas[] = {0, 0, 0, 0, 0};

165    unsigned int tmp = abs(v);

166    datas[0] = tmp / 10000;

167    datas[1] = tmp % 10000 / 1000;

168    datas[2] = tmp % 1000 / 100;

169    datas[3] = tmp % 100 / 10;

170    datas[4] = tmp % 10;

171    if(v < 0)

172    {

173        //关位选, 去除对上一位的影响

174        P0 = 0xff; 

175        wela = 1; //打开锁存, 给它一个下降沿量

176        wela = 0;

177        //段选

178        P0 = 0x40; //显示"-"号

179        dula = 1;  //打开锁存, 给它一个下降沿量

180        dula = 0;

181

182        //位选

183        P0 = 0xfe; 

184        wela = 1; //打开锁存, 给它一个下降沿量

185        wela = 0;

186        delay(timeCount); 

187    }

188    for(count = 0; count !

= 5; count++)

189    {

190        //关位选, 去除对上一位的影响

191        P0 = 0xff; 

192        wela = 1; //打开锁存, 给它一个下降沿量

193        wela = 0;

194        //段选

195        if(count !

= 2)

196        {

197        /*    if((count == 0 && datas[count] == 0) 

198                || ((count == 1 && datas[count] == 0) && (count == 0 && datas[count - 1] == 0)))

199            {

200                P0 = 0x00; //当最高位为0时, 不作显示

201            }

202            else*/

203                P0 = table[datas[count]];  //显示数字

204        }

205        else

206        {

207            P0 = tableWidthDot[datas[count]]; //显示带小数点数字

208        }

209        dula = 1;  //打开锁存, 给它一个下降沿量

210        dula = 0;

211

212        //位选 

213        P0 = _crol_(0xfd, count); //选择第(count + 1) 个数码管

214        wela = 1; //打开锁存, 给它一个下降沿量

215        wela = 0;

216        delay(timeCount); 

217    }

218}

219

220void main()

221{

222    unsigned char i;

223    

224    while

(1)

225    {

226        //启动温度转换

227        sendChangeCmd();

228        //显示5次

229        for(i = 0; i < 40; i++)

230        {

231            display(tempValue);

232        }

233        tempValue = getTmpValue();

234    }

235}

改进后的效果图:

只有一位小数

 

两位小数, 并消除下一位对上一位的影响

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1