ds18b20详解及程序_第1页
ds18b20详解及程序_第2页
ds18b20详解及程序_第3页
ds18b20详解及程序_第4页
ds18b20详解及程序_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、最近都在学习和写单片机的程序, 今天有空又模仿DS18B20温度测量显示实验写了一个与DS18B20基于单总线通信的程序.DS18B20 数字温度传感器(参考:智能温度传感器DS18B20的原理与应用)是DALLAS 公司生产的1Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。DS18B20 产品的特点:(1)、只要求一个I/O 口即可实现通信。(2)、在DS18B20 中的每个器件上都有独一无二的序列号。(3)、实际应用中不需要外部任何元器件即可实现测温。(4)、测量温度范围在55 到125之间; 在-1

2、0 +85范围内误差为±5;(5)、数字温度计的分辨率用户可以从9 位到12 位选择。将12位的温度值转换为数字量所需时间不超过750ms;(6)、内部有温度上、下限告警设置。DS18B20引脚分布图DS18B20 详细引脚功能描述:1、GND 地信号;2、DQ数据输入出引脚。开漏单总线接口引脚。当被用在寄生电源下,此引脚可以向器件提供电源;漏极开路, 常太下高电平. 通常要求外接一个约5k的上拉电阻.3、VDD可选择的VDD 引脚。电压范围:35.5V; 当工作于寄生电源时,此引脚必须接地。DS18B20存储器结构图暂存储器的头两个字节为测得温度信息的低位和高位字节; 第3, 4字

3、节是TH和TL的易失性拷贝, 在每次电复位时都会被刷新;第5字节是配置寄存器的易失性拷贝, 同样在电复位时被刷新;第9字节是前面8个字节的CRC检验值.配置寄存器的命令内容如下:0R1R011111MSB                                 

4、                               LSBR0和R1是温度值分辨率位, 按下表进行配置.默认出厂设置是R1R0 = 11, 即12位.温度值分辨率配置表R1R0分辨率最大转换时间(ms)009bit93.75(tconv/8)0110bit183.50(tconv/4)10

5、11bit375(tconv/2)1112bit750 (tconv)4种分辨率对应的温度分辨率为0.5, 0.25, 0.125, 0.0625(即最低一位代表的温度值)12位分辨率时的两个温度字节的具体格式如下:低字节: 232221202-12-22-32-4高字节: SSSSS262524其中高字节前5位都是符号位S, 若分辨率低于12位时, 相应地使最低为0, 如: 当分辨率为10位时, 低字节为: 232221202-12-200, 高字节不变.一些温度与转换后输出的数字参照如下:温度数字输出换成16进制+12500000111 11010000 07D0H+850000

6、0101 010100000550H+25.062500000001 100100010191H+10.12500000000 1010001000A2H+0.500000000 000010000008H000000000 000000000000H-0.511111111 11111000FFF8H-10.12511111111 01011110FFE5H-25.062511111110 01101111FF6FH-5511111100 10010000FC90H由上表可看出, 当输出是负温度时, 使用补码表示, 方便计算机运算(若是用C语言, 直接将结果赋值给一个int变量即可).DS1

7、8B20 的使用方法:由于DS18B20 采用的是1Wire 总线协议方式,即在一根数据线实现数据的双向传输,而对单片机来说,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序(dsInit()实现)、读时序(readByte()、写时序(writeByte()。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总

8、线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。DS18B20与单片机连接电路图:利用软件模拟DS18B20的单线协议和命令:主机操作DS18B20必须遵循下面的顺序1. 初始化单线总线上的所有操作都是从初始化开始的. 过程如下: 1)请求: 主机通过拉低单线480us以上, 产生复位脉冲, 然后释放该线, 进入Rx接收模式. 主机释放总线时, 会产生一个上升沿脉冲.DQ : 1 -> 0(480us+) -> 1  2)响应: DS18B20检测到该上升沿后, 延时1560us, 通过拉低总线60240us来产生应答脉冲. D

9、Q: 1(1560us) -> 0(60240us)3)接收响应: 主机接收到从机的应答脉冲后, 说明有单线器件在线. 至此, 初始化完成.DQ: 02. ROM操作命令当主机检测到应答脉冲, 便可发起ROM操作命令. 共有5类ROM操作命令, 如下表 命令类型 命令字节功能Read Rom   读ROM   33H读取激光ROM中的64位,只能用于总线上单个DS18B20器件情况, 多挂时会发生数据冲突Match Rom匹配ROM55H此命令后跟64位ROM序列号,寻址多挂总线上的对应DS18B20.只有序列号完全匹配的DS1

10、8B20才能响应后面的内存操作命令,其他不匹配的将等待复位脉冲.可用于单挂或多挂两种情况.Skip Rom   跳过ROMCCH可无须提供64位ROM序列号即可运行内存操作命令, 只能用于单挂.Search Rom搜索ROMF0H通过一个排除法过程, 识别出总线上所有器件的ROM序列号Alarm Search告警搜索ECH命令流程与Search Rom相同, 但DS18B20只有最近的一次温度测量时满足了告警触发条件的, 才会响应此命令.3. 内存操作命令在成功执行ROM操作命令后, 才可使用内存操作命令. 共有6种内存操作命令:命令类型命令字节功能Write Scratc

11、hpad写暂存器4EH写暂存器中地址2地址4的3个字节(TH,TL和配置寄存器)在发起复位脉冲之前,3个字节都必须要写.Read Scratchpad读暂存器BEH读取暂存器内容,从字节0一直到字节8, 共9个字节,主机可随时发起复位脉冲,停止此操作,通常我们只需读前5个字节.Copy Scratchpad复制暂存器48H将暂存器中的内容复制进EERAM, 以便将温度告警触发字节存入非易失内存. 如果此命令后主机产生读时隙, 那么只要器件还在进行复制都会输出0, 复制完成后输出1.Convert T 温度转换44H开始温度转换操作. 若在此命令后主机产生时隙, 那么只要器件还在进行温

12、度转换就会输出0, 转换完成后输出1.Recall E2    重调E2暂存器B8H将存储在EERAM中的温度告警触发值和配置寄存器值重新拷贝到暂存器中,此操作在DS18B20加电时自动产生.Read Power Supply读供电方式B4H主机发起此命令后每个读数时隙内,DS18B20会发信号通知它的供电方式:0寄生电源, 1外部供电.4. 数据处理DS18B20要求有严格的时序来保证数据的完整性. 在单线DQ上, 有复位脉冲, 应答脉冲, 写0, 写1, 读0, 读1这6种信号类型. 除了应答脉冲外, 其它都由主机产生. 数据位的读和写是通过读、写时隙实现的.

13、1) 写时隙: 当主机将数据线从高电平拉至低电平时, 产生写时隙.所有写时隙都必须在60us以上, 各写时隙间必须保证1us的恢复时间.写"1" : 主机将数据线DQ先拉低, 然后释放15us后, 将数据线DQ拉高;写"0" : 主机将DQ拉低并至少保持60us以上.2)读时隙: 当主机将数据线DQ从高电平拉至低电平时, 产生读时隙. 所有读时隙最短必须持续60us, 各读时隙间必须保证1us的恢复时间.读: 主机将DQ拉低至少1us,. 此时主机马上将DQ拉高, 然后就可以延时15us后, 读取DQ即可.源代码: (测量范围: 0 99度)DS18B2

14、0  1#include <reg51.H>  2/通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值  3sbit wela = P27;  /数码管位选  4sbit dula = P26;  /数码管段选  5sbit ds = P22;  6/0-F数码管的编码(共阴极)  

15、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, 0xe

16、6, 0xed, 0xfd,  11    0x87, 0xff, 0xef; 12 13/延时函数, 例i=10,则大概延时10ms. 14void delay(unsigned char i) 15 16    unsigned char j, k; 17    for(j 

17、= i; j > 0; j-) 18     19        for(k = 125; k > 0; k-); 20     21 22 23/初始化DS18B20 24/让DS18B20一段相对长时间低电平, 然后一段相对非常短时间

18、高电平, 即可启动 25void dsInit() 26 27    /一定要使用unsigned int型, 一个i+指令的时间, 作为与DS18B20通信的小时间间隔 28    /以下都是一样使用unsigned int型 29    unsigned int i;   30   &

19、#160;ds = 0; 31    i = 103; 32    while(i>0) i-; 33    ds = 1; 34    i = 4; 35    while(i>0) i-; 36 37 3

20、8/向DS18B20读取一位数据 39/读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,  40/之后DS18B20则会输出持续一段时间的一位数据 41bit readBit() 42 43    unsigned int i; 44    bit b; 45    ds = 0; 46

21、60;   i+; 47    ds = 1;  48    i+; i+; 49    b = ds; 50    i = 8;  51    while(i>0) i-; 52  

22、  return b; 53 54 55/读取一字节数据, 通过调用readBit()来实现 56unsigned char readByte() 57 58    unsigned int i; 59    unsigned char j, dat; 60    dat =&#

23、160;0; 61    for(i=0; i<8; i+) 62     63        j = readBit(); 64        /最先读出的是最低位数据 65       &#

24、160;dat = (j << 7) | (dat >> 1); 66     67    return dat; 68 69 70/向DS18B20写入一字节数据 71void writeByte(unsigned char dat) 72 73    

25、unsigned int i; 74    unsigned char j; 75    bit b; 76    for(j = 0; j < 8; j+) 77     78        

26、b = dat & 0x01; 79        dat >>= 1; 80        /写"1", 让低电平持续2个小延时, 高电平持续8个小延时 81        if(b)  

27、  82         83            ds = 0; 84            i+; i+; 85       

28、;     ds = 1; 86            i = 8; while(i>0) i-; 87         88        else  

29、/写"0", 让低电平持续8个小延时, 高电平持续2个小延时 89         90            ds = 0; 91            i = 8;&

30、#160;while(i>0) i-; 92            ds = 1; 93            i+; i+; 94         95   &#

31、160; 96 97 98/向DS18B20发送温度转换命令 99void sendChangeCmd()100101    dsInit();    /初始化DS18B20102    delay(1);    /延时1ms103    writeByte(0xcc); /写入跳过序列号命令字104   &

32、#160;writeByte(0x44); /写入温度转换命令字105106107/向DS18B20发送读取数据命令108void sendReadCmd()109110    dsInit();111    delay(1);112    writeByte(0xcc); /写入跳过序列号命令字113    writeByte(0xbe); /写入读取数据令字114115116/获取当前温度值1

33、17unsigned int getTmpValue()118119    unsigned int value; /存放温度数值120    float t;121    unsigned char low, high;122    sendReadCmd();123    /连续读取两个字节数据124&#

34、160;   low = readByte(); 125    high = readByte();126    /将高低两个字节合成一个整形变量127    value = high;128    value <<= 8;129    value |=&#

35、160;low;130    /DS18B20的精确度为0.0625度, 即读回数据的最低位代表0.0625度131    t = value * 0.0625;132    /将它放大10倍, 使显示时可显示小数点后一位, 并对小数点后第二2进行4舍5入133    /如t=11.0625, 进行计数后, 得到value = 

36、111, 即11.1 度134    value = t * 10 + 0.5;135    return value;136137138/显示当前温度值, 精确到小数点后一位139void display(unsigned int v) 140141    unsigned char count;142 &

37、#160;  unsigned char datas = 0, 0, 0;143    datas0 = v / 100;144    datas1 = v % 100 / 10;145    datas2 = v % 10;146  &#

38、160; for(count = 0; count < 3; count+)147    148        /片选149        wela = 0; 150        P0 = (

39、0xfe << count) | (0xfe >> (8 - count); /选择第(count + 1) 个数码管151        wela = 1; /打开锁存, 给它一个下降沿量152        wela = 0;153

40、        /段选154        dula = 0;155        if(count != 1)156        157        &#

41、160;   P0 = tabledatascount;  /显示数字158        159        else160        161           

42、0;P0 = tableWidthDotdatascount; /显示带小数点数字162        163        dula = 1;  /打开锁存, 给它一个下降沿量164        dula = 0;165   

43、     delay(5); /延时5ms, 即亮5ms166167        /清除段先, 让数码管灭, 去除对下一位的影响, 去掉高位对低位重影168        /若想知道影响效果如何, 可自行去掉此段代码169        /因为数码

44、管是共阴极的, 所有灭的代码为: 00H170        dula = 0;171        P0 = 0x00;  /显示数字172        dula = 1; /打开锁存, 给它一个下降沿量173  &

45、#160;     dula = 0;174    175176177void main()178179    unsigned char i;180    unsigned int value;181    while(1)182    183   

46、;     /启动温度转换184        sendChangeCmd();185        value = getTmpValue();186        /显示3次187        for(i

47、 = 0; i < 3; i+)188        189            display(value);190        191    192显示效果: 流程图:改进代码: 扩大测量范围,

48、使可测量范围为: -55度 +125度, 严格按照上面的流程进行软件设计3.15 1:34 修正display()函数中的下一位显示对上一位的影响改进代码  1#include <reg51.H>  2#include<intrins.h>  3#include <math.H>  /要用到取绝对值函数abs()  4/通过DS18B20测试当前环境温度, 并通过数码管显示当前温度值, 目前显示范围: -55&

49、#160;+125度  5sbit wela = P27;  /数码管位选  6sbit dula = P26;  /数码管段选  7sbit ds = P22;  8int tempValue;  9 10/0-F数码管的编码(共阴极) 11unsigned char code table=0x3f,0x0

50、6,0x5b,0x4f,0x66, 12    0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71; 13/0-9数码管的编码(共阴极), 带小数点 14unsigned char code tableWidthDot=0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd,  15   

51、60;0x87, 0xff, 0xef; 16 17/延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms. 18void delay(unsigned int i) 19 20    unsigned int j; 21    while(i-) 22     23 

52、0;      for(j = 0; j < 125; j+); 24     25 26 27/初始化DS18B20 28/让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动 29void dsInit() 30 31    /对于11.0592MHz

53、时钟, unsigned int型的i, 作一个i+操作的时间大于为8us 32    unsigned int i;   33    ds = 0; 34    i = 100;   /拉低约800us, 符合协议要求的480us以上 35    

54、while(i>0) i-; 36    ds = 1;    /产生一个上升沿, 进入等待应答状态 37    i = 4; 38    while(i>0) i-; 39 40 41void dsWait() 42 43   

55、0; unsigned int i; 44     while(ds);   45     while(ds);  /检测到应答脉冲 46     i = 4; 47     while(i > 0) i-; 48 

56、;49 50/向DS18B20读取一位数据 51/读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,  52/之后DS18B20则会输出持续一段时间的一位数据 53bit readBit() 54 55    unsigned int i; 56    bit b; 57    ds = 0;&

57、#160;58    i+;   /延时约8us, 符合协议要求至少保持1us 59    ds = 1;  60    i+; i+;  /延时约16us, 符合协议要求的至少延时15us以上 61    b = ds; 62   

58、60;i = 8;  63    while(i>0) i-;  /延时约64us, 符合读时隙不低于60us要求 64    return b; 65 66 67/读取一字节数据, 通过调用readBit()来实现 68unsigned char readByte() 69 70   

59、60;unsigned int i; 71    unsigned char j, dat; 72    dat = 0; 73    for(i=0; i<8; i+) 74     75        j

60、60;= readBit(); 76        /最先读出的是最低位数据 77        dat = (j << 7) | (dat >> 1); 78     79    return 

61、dat; 80 81 82/向DS18B20写入一字节数据 83void writeByte(unsigned char dat) 84 85    unsigned int i; 86    unsigned char j; 87    bit b; 88    fo

62、r(j = 0; j < 8; j+) 89     90        b = dat & 0x01; 91        dat >>= 1; 92     &

63、#160;  /写"1", 将DQ拉低15us后, 在15us60us内将DQ拉高, 即完成写1 93        if(b)    94         95            ds

64、 = 0; 96            i+; i+;  /拉低约16us, 符号要求1560us内 97            ds = 1;     98    &#

65、160;       i = 8; while(i>0) i-;  /延时约64us, 符合写时隙不低于60us要求 99        100        else  /写"0", 将DQ拉低60us120us101 &

66、#160;      102            ds = 0;103            i = 8; while(i>0) i-;  /拉低约64us, 符号要求104  &#

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

68、;108109110/向DS18B20发送温度转换命令111void sendChangeCmd()112113    dsInit();    /初始化DS18B20, 无论什么命令, 首先都要发起初始化114    dsWait();   /等待DS18B20应答115    delay(1);    /延时1ms, 因为D

69、S18B20会拉低DQ 60240us作为应答信号116    writeByte(0xcc); /写入跳过序列号命令字 Skip Rom117    writeByte(0x44); /写入温度转换命令字 Convert T118119120/向DS18B20发送读取数据命令121void sendReadCmd()122123    dsInit();124   

70、 dsWait();125    delay(1);126    writeByte(0xcc); /写入跳过序列号命令字 Skip Rom127    writeByte(0xbe); /写入读取数据令字 Read Scratchpad128129130/获取当前温度值131int getTmpValue()132133    unsigned 

71、int tmpvalue;134    int value; /存放温度数值135    float t;136    unsigned char low, high;137    sendReadCmd();138    /连续读取两个字节数据139    low = 

72、;readByte(); 140    high = readByte();141    /将高低两个字节合成一个整形变量142    /计算机中对于负数是利用补码来表示的143    /若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value144    tmpvalue = high;145 &

73、#160;  tmpvalue <<= 8;146    tmpvalue |= low;147    value = tmpvalue;148    149    /使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度150    t&

74、#160;= value * 0.0625;151    /将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入152    /如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度153    /如t=-11.0625, 进行计数后, 得到value = -1106,&

75、#160;即-11.06 度154    value = t * 100 + (value > 0 ? 0.5 : -0.5); /大于0加0.5, 小于0减0.5155    return value;156157158unsigned char const timeCount = 3; /

76、动态扫描的时间间隔159/显示当前温度值, 精确到小数点后一位160/若先位选再段选, 由于IO口默认输出高电平, 所以当先位选会使数码管出现乱码161void display(int v) 162163    unsigned char count;164    unsigned char datas = 0, 0, 0, 0, 0;165 &#

77、160;  unsigned int tmp = abs(v);166    datas0 = tmp / 10000;167    datas1 = tmp % 10000 / 1000;168    datas2 = tmp % 1000 / 100;16

78、9    datas3 = tmp % 100 / 10;170    datas4 = tmp % 10;171    if(v < 0)172    173        /关位选, 去除对上一位的影响174 

79、       P0 = 0xff; 175        wela = 1; /打开锁存, 给它一个下降沿量176        wela = 0;177        /段选178 

80、60;      P0 = 0x40; /显示"-"号179        dula = 1;  /打开锁存, 给它一个下降沿量180        dula = 0;181182      

81、0; /位选183        P0 = 0xfe; 184        wela = 1; /打开锁存, 给它一个下降沿量185        wela = 0;186       &

82、#160;delay(timeCount); 187    188    for(count = 0; count != 5; count+)189    190        /关位选, 去除对上一位的影响191        P0

83、60;= 0xff; 192        wela = 1; /打开锁存, 给它一个下降沿量193        wela = 0;194        /段选195        if(count != 2)196  

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论