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;