ds18b20详解及程序

  • 格式:pdf
  • 大小:521.89 KB
  • 文档页数:19

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~5.5V; 当⼯作于寄⽣电源时,此引脚必须接地。

DS18B20存储器结构图

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

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

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

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

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

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

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

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

⾼字节:

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

, ⾼字节不变....

由上表可看出, 当输出是负温度时, 使⽤补码表⽰, ⽅便计算机运算(若是⽤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操作命令, 如下表

3. 内存操作命令

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

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

2//通过DS18B20测试当前环境温度, 并通过数码管显⽰当前温度值

3sbit wela = P2^7; //数码管位选

4sbit dula = P2^6; //数码管段选

5sbit ds = P2^2;

6//0-F数码管的编码(共阴极)

7unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,

8 0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

9//0-9数码管的编码(共阴极), 带⼩数点

10unsigned char code tableWidthDot[]=

{0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd,

11 0x87, 0xff, 0xef};

12

13//延时函数, 例i=10,则⼤概延时10ms.

14void delay(unsigned char i)

15{

16 unsigned char j, k;

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

18 {

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

20 }

21}

22

23//初始化DS18B20

24//让DS18B20⼀段相对长时间低电平, 然后⼀段相对⾮常短时间⾼电平, 即可启动

25void dsInit()

26{

27//⼀定要使⽤unsigned int型, ⼀个i++指令的时间, 作为与DS18B20通信的⼩时间间隔

28 //以下都是⼀样使⽤unsigned int型

29 unsigned int i;30 ds = 0;

31 i = 103;

32while(i>0) i--;

33 ds = 1;

34 i = 4;

35while(i>0) i--;

36}

37

38//向DS18B20读取⼀位数据

39//读⼀位, 让DS18B20⼀⼩周期低电平, 然后两⼩周期⾼电平,

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

41bit readBit()

42{

43 unsigned int i;

44 bit b;

45 ds = 0;

46 i++;

47 ds = 1;

48 i++; i++;

49 b = ds;

50 i = 8;

51while(i>0) i--;

52return b;

53}

54

55//读取⼀字节数据, 通过调⽤readBit()来实现

56unsigned char readByte()

57{

58 unsigned int i;

59 unsigned char j, dat;

60 dat = 0;

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

62 {

63 j = readBit();

64//最先读出的是最低位数据65 dat = (j << 7) | (dat >> 1);

66 }

67return dat;

68}

69

70//向DS18B20写⼊⼀字节数据

71void writeByte(unsigned char dat)

72{

73 unsigned int i;

74 unsigned char j;

75 bit b;

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

77 {

78 b = dat & 0x01;

79 dat >>= 1;

80//写"1", 让低电平持续2个⼩延时, ⾼电平持续8个⼩延时

81if(b)

82 {

83 ds = 0;

84 i++; i++;

85 ds = 1;

86 i = 8; while(i>0) i--;

87 }

88else//写"0", 让低电平持续8个⼩延时, ⾼电平持续2个⼩延时

89 {

90 ds = 0;

91 i = 8; while(i>0) i--;

92 ds = 1;

93 i++; i++;

94 }

95 }

96}

97

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

99void sendChangeCmd()100{

101 dsInit(); //初始化DS18B20

102 delay(1); //延时1ms

103 writeByte(0xcc); //写⼊跳过序列号命令字

104 writeByte(0x44); //写⼊温度转换命令字

105}

106

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

108void sendReadCmd()

109{

110 dsInit();

111 delay(1);

112 writeByte(0xcc); //写⼊跳过序列号命令字

113 writeByte(0xbe); //写⼊读取数据令字

114}

115

116//获取当前温度值

117unsigned int getTmpValue()

118{

119 unsigned int value; //存放温度数值

120float t;

121 unsigned char low, high;

122 sendReadCmd();

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

124 low = readByte();

125 high = readByte();

126//将⾼低两个字节合成⼀个整形变量

127 value = high;

128 value <<= 8;

129 value |= low;

130//DS18B20的精确度为0.0625度, 即读回数据的最低位代表0.0625度

131 t = value * 0.0625;

132//将它放⼤10倍, 使显⽰时可显⽰⼩数点后⼀位, 并对⼩数点后第⼆2进⾏4舍5⼊133 //如t=11.0625, 进⾏计数后, 得到value =111, 即11.1 度

134 value = t * 10 + 0.5;

135return value;