共阳极显示后应在显示结束后给予高电平0xFF并保持一定时间,共阴极应给0x00并保持一定时间!
P1=temp>>1; //是将temp右移一位赋给P1,右移并不改变temp的状态。
P1=temp>>=1;//是先将temp右移一位赋给temp,再讲移位后的temp赋值给P1,此操作改变了temp的状态!
简述DS18B20 一·DS18B20的概述.DS18B20是美国DALLAS半导体公司推出的第一片支持“一线总线”接口的温度传感器,它具有微型化,低功耗,高性能,抗干扰能力强,易配微处理器等优点,可直接将温度转化成数字信号处理器处理。测量的温度范围是—55~125℃,测温误差0.5℃。可编程分辨率9~12位,对应的可分辨温度分别为0.5℃,0.25℃,0.125℃和0.0625℃。相较热电偶传感器而言可实现高精度测温。 对热电偶温度传感器来说该项目实现的过程为:靠光敏电阻检测光照的大小,光的改变最终改变电阻的大小,给电阻外加一个电压,就改变了电压的大小,再用PCF8951AD转换器件检测电压的变化并转换为数字信号,再传到单片机上作一定的处理后去控制相应的数码管显示出当时的温度。而对DS18B20来说过程则简单的多了,热电偶电阻传感器一直到单片机之前的部分都可以用一个DS18B20来代替了,真正的实现了数字化。单片机后面的部分则两者是一样的! DS18B20与热电阻温度传感器相比价格上,来说要贵出很多!所以在温度的测量精度要求不是很高的话可以选择热电阻温度传感器,实验者应则情而定。 二.DS18B20的硬件介绍.1.硬件实物图及硬件原理图如下. 三脚TO-92实物图: 硬件原理图: 八脚soic贴片式DS18B20: 2.两种管脚排列图: 3. 型号规格 型号 范围 螺纹 电缆长度 适用管道 TS-18B20 -55~125 无 1.5 m TS-18B20A -55~125 M10X1 1.5m DN15~25 TS-18B20B -55~125 1/2”G 接线盒 DN40~ 60 4存储器 DS18B20的存储器包括高速暂存器RAM和可电擦除RAM,可电擦除RAM又包括温度触发器TH和TL,以及一个配置寄存器。存储器能完整的确定一线端口的通讯,数字开始用写寄存器的命令写进寄存器,接着也可以用读寄存器的命令来确认这些数字。当确认以后就可以用复制寄存器的命令来将这些数字转移到可电擦除RAM中。当修改过寄存器中的数时,这个过程能确保数字的完整性。 高速暂存器RAM是由8个字节的存储器组成;。用读寄存器的命令能读出第九个字节,这个字节是对前面的八个字节进行校验 5. 64-位光刻ROM 64位光刻ROM的前8位是DS18B20的自身代码,接下来的48位为连续的数字代码,最后的8位是对前56位的CRC校验。64-位的光刻ROM又包括5个ROM的功能命令:读ROM,匹配ROM,跳跃ROM,查找ROM和报警查找。 6. DS18B20外部电源的连接方式 DS18B20可以使用外部电源VDD,也可以使用内部的寄生电源。当VDD端口接3.0V—5.5V的电压时是使用外部电源;当VDD端口接地时使用了内部的寄生电源。无论是内部寄生电源还是外部供电,I/O口线要接5KΩ左右的上拉电阻。 7. DS18B20引脚定义: (1)DQ为数字信号输入/输出端; (2)GND为电源地; (3)VDD为外接供电电源输入端(在寄生电源接线方式时接地)。 8. 内部结构图:  三.工作过程.DS18B20控制方法(DS18B20有六条控制命令): 温度转换 44H 启动DS18B20进行温度转换 读暂存器 BEH 读暂存器9位二进制数字 写暂存器 4EH 将数据写入暂存器的TH、TL字节 复制暂存器 48H 把暂存器的TH、TL字节写到E2RAM中 重新调E2RAM B8H 把E2RAM中的TH、TL字节写到暂存器TH、TL字节 读电源供电方式 B4H 启动DS18B20发送电源供电方式的信号给主CPU Void delay_18B20(us) { While(us--); } 1. 初始化 (1) 先将数据线置高电平“1”。 (2) 延时(该时间要求的不是很严格,但是尽可能的短一点)
(3) 数据线拉到低电平“0”。
(4) 延时750微秒(该时间的时间范围可以从480到960微秒)。
(5) 数据线拉到高电平“1”。
(6) 延时等待(如果初始化成功则在15到60微妙时间之内产生一个由DS18B20所返回的低电平“0”。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。 (7) 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。 (8) 将数据线再次拉高到高电平“1”后结束。
void ds1820rset() //ds1820复位
{
DQ = 1; //DQ复位
delay_18B20(4); //延时
DQ = 0; //DQ拉低
delay_18B20(100); //精确延时大于480us
DQ = 1; //拉高
delay_18B20(40);
}
2. 写数据操作 (1) 数据线先置低电平“0”。 (2) 延时确定的时间为15微秒。
(3) 按从高位到低位的顺序发送字节(一次只发送一位)。D7到D0的次序
(4) 延时时间为45微秒。
(5) 将数据线拉到高电平。
(6) 重复上(1)到(6)的操作直到所有的字节全部发送完为止。
(7) 最后将数据线拉高。
void ds1820wrdata(uchar wdata) /*写数据*/
{
unsigned char I,temp=0x00;
for (i=8;i>0;i--)
{ DQ=0; delay_18B20(15) temp=1<<i-1; DQ=wdata&temp;
delay_18B20(45);
DQ=1;
}
}
3. 读数据操作 (1)将数据线拉高“1”。
(2)延时2微秒。
(3)将数据线拉低“0”。
(4)延时3微秒。
(5)将数据线拉高“1”。
(6)延时5微秒。
(7)读数据线的状态得到1个状态位,并进行数据处理。
(8)延时60微秒。
读一位二进制数
bit ds_read_bit(void)
{
bit dat;
DQ=0;
delay_18B20(2);
DQ=1;
delay_18B20(3);
dat=DQ;
delay_18B20(100);
return(dat);
}
读一个字节,8位二进制数
uchar ds1820readdata() //读数据
{
unsiged char i,j,value=0;
for(i=0;i<8;i++)
{ j=ds_read_bit(); value |=j<<7-i; } return(value);
}
四.DS18B20的主要特性(1)、适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数 据线供电
(2)、独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯 (3)、 DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温 (4)、DS18B20在使用中不需要任何外围元件,全部 传感元件及转换电路集成在形如一只三极管的集成电路内 (5)、温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃
(6)、可编程 的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温 (7)、在9位分辨率时最多在 93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快 (8)、测量结果直接输出数字温度信号,以"一 线总线"串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力 (9)、负压特性:电源极性接反时,芯片不会因发热而烧毁, 但不能正常工作。
五.工作原理:DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s 减为750ms。温度系数晶振 随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对 低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重 新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即 为所测温度。
六.4个主要的数据部件:(1)光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位 (28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。光刻ROM的作用 是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。  (2)DS18B20中的温度传感器可完成对温度的测量,以12位转化为例:用16位符号扩展的二进制补码读数形式提供,以 0.0625℃/LSB形式表达,其中S为符号位。 S18B20温度值格式表: S18B20温度数据表:  (4)配置寄存器 该字节各位的意义如下: 配置寄存器结构: 低五位一直都是"1",TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。在DS18B20出厂时该位被设置为0,用 户不要去改动。R1和R0用来设置分辨率,如下表所示:(DS18B20出厂时被设置为12位) 温度分辨率设置表: R1 | R0 | 分辨率 | 温度最大转换时间 | 0 | 0 | 9位 | 93.75ms | 0 | 1 | 10位 | 187.5ms | 1 | 0 | 11位 | 375ms | 1 | 1 | 12位 | 750ms |
DS18B20暂存寄存器分布: 寄存器内容 | 字节地址 | 温度值低位 (LS Byte) | 0 | 温度值高位 (MS Byte) | 1 | 高温限值(TH) | 2 | 低温限值(TL) | 3 | 配置寄存器 | 4 | 保留 | 5 | 保留 | 6 | 保留 | 7 | CRC校验值 | 8 | |
根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行 复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。复位要求主CPU将数据线下拉500微秒,然后 释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。 ROM指令表: 指 令 | 约定代码 | 功 能 | 读ROM | 33H | 读DS1820温度传感器ROM中的编码(即64位地址) | 符合 ROM | 55H | 发出此命令之后,接着发出 64 位 ROM 编码,访问单总线上与该编码相对应的 DS1820 使之作出响应,为下一步对该 DS1820 的读写作准备。 | 搜索 ROM | 0FOH | 用于确定挂接在同一总线上 DS1820 的个数和识别 64 位 ROM 地址。为操作各器件作好准备。 | 跳过 ROM | 0CCH | 忽略 64 位 ROM 地址,直接向 DS1820 发温度变换命令。适用于单片工作。 | 告警搜索命令 | 0ECH | 执行后只有温度超过设定值上限或下限的片子才做出响应。 |
RAM指令表: 指 令 | 约定代码 | 功 能 | 温度变换 | 44H | 启动DS1820进行温度转换,12位转换时最长为750ms(9位为93.75ms)。结果存入内部9字节RAM中。 | 读暂存器 | 0BEH | 读内部RAM中9字节的内容 | 写暂存器 | 4EH | 发出向内部RAM的3、4字节写上、下限温度数据命令,紧跟该命令之后,是传送两字节的数据。 | 复制暂存器 | 48H | 将RAM中第3 、4字节的内容复制到EEPROM中。 | 重调 EEPROM | 0B8H | 将EEPROM中内容恢复到RAM中的第3 、4字节。 | 读供电方式 | 0B4H | 读DS1820的供电模式。寄生供电时DS1820发送“ 0 ”,外接电源供电 DS1820发送“ 1 ”。 |
DS18B20的外部电源供电方式 在外部电源供电方式下,DS18B20工作电源由VDD引脚接入,此时I/O线不需要强上拉,不存在电源电流不足的问题,可以保证 转换精度,同时在总线上理论可以挂接任意多个DS18B20传感器,组成多点测温系统。注意:在外部供电的方式下,DS18B20的GND引脚不能悬空 ,否则不能转换温度,读取的温度总是85℃。 


#include <reg51.h> //调用51单片机的头文件
#include <Intrins.h>
sbit ds18b20=P1^2;
unsigned char TT,temp1;
unsigned char temp2;
unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xff};
//---------------------------------------
//名称:复位DS18B20函数
//---------------------
bit Reset(void)
{
unsigned int i;
bit k;
ds18b20=0; //拉低DQ总线开始复位
i=95; //保持DQ低大约870uS,符合不低于48US的要求
while(i--); //保持DQ低大约870uS,符合不低于48US的要求
//保持DQ低大约870uS,符合不低于48US的要求
ds18b20=1; //拉高准备接收数据
i=9; //大约80uS后
while(i--); //大约80uS后
//大约80uS后
k=ds18b20; //读出数据并保存
i=55; //维持约490US,符合总读时隙不低于480US的要求
while(i--); //维持约400US,符合总读时隙不低于480US的要求
//维持约400US,符合总读时隙不低于480US的要求
return k; //k=0为复位成功,k=1为复位失败
}
//---------------------------------------
//名称:读一字节函数
//---------------------------------------
unsigned char ReadByte(void)
{
unsigned int i;
unsigned char j,buf=0;
for(j=0;j<8;j++) //接收8次还原一个字节数据
{
buf=buf>>1; //接收前,想将接收缓冲区右移
ds18b20=0; //拉低
_nop_(); //维持2US,符合大于1US小于15US的规范
_nop_(); //维持2US,符合大于1US小于15US的规范
ds18b20=1; //拉高,为读数据做准备
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
if(ds18b20==1)
buf|=0x80; //读出1位数据保存于buf中
i=7; //维持约52US,符合总读时隙不低于60US的要求
while(i--); //维持约52US,符合总读时隙不低于60US的要求
//维持约52US,符合总读时隙不低于60US的要求
}
return buf; //退出的同时将接收缓冲区参数返回
}
//---------------------------------------
//名称:写一字节函数
//---------------------------------------
void WriteByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
for(j=0;j<8;j++)
{
if(dat&0x01) //如果写1
{
ds18b20=0; //拉低
_nop_(); //维持2US,符合大于1US小于15US的规范
_nop_(); //维持2US,符合大于1US小于15US的规范
ds18b20=1; //拉高
i=7; //维持约63US,符合不低于60US的要求
while(i--); //维持约63US,符合不低于60US的要求
}
else //如果写0
{
ds18b20=0; //拉低
i=7; //维持约63US,符合不低于60US的要求
while(i--); //维持约63US,符合不低于60US的要求
ds18b20=1; //拉高
_nop_(); //维持2US,符合大于1US的规范
_nop_(); //维持2US,符合大于1US的规范
}
dat=dat>>1; //写入字节右移1位
}
}
//---------------------------------------
//名称:DS18B20温度转换函数
//---------------------------------------
bit Convert(void)
{
if(Reset()==0) //复位DS18B20成功
{
WriteByte(0xcc); //写入跳过序列号命令字 Skip Rom
WriteByte(0x44); //写入温度转换命令字 Convert T
return 1; //启动温度转换成功
}
else //失败
{
return 0; //启动温度转换失败
}
}
//---------------------------------------
//名称:转换结束处理函数
//---------------------------------------
void ReadFlash(void)
{
unsigned char Lsb,Msb;
if(Reset()==0) //复位DS18B20成功
{
WriteByte(0xcc); //写入跳过序列号命令字 Skip Rom
WriteByte(0xbe); //写入读取数据令字 Read Scratchpad
Lsb=ReadByte(); //读出第一个字节暂存于LSB
Msb=ReadByte(); //读出第二个字节暂存于MSB
temp1=Lsb; //temp1内装温度参数的小数部分
temp2=Msb;//>>4)|(Lsb<<4);//temp2内装温度参数的整数部分
}
else
{
temp1=0; //如果复位失败,温度参数清零
temp2=0; //如果复位失败,温度参数清零
}
}
//---------------------------------------
void main(void) //主函数,单片机开机后就是从这个函数开始运行
{
unsigned char TT;
while(1) //死循环,单片机初始化后,将一直运行这个死循环
{
if(Convert()==1) //启动转换
{
ReadFlash(); //读取温度
TT=(temp2<<4)|(temp1>>4);
P3=tab[TT/10]; //温度整数部分个位
P2=tab[TT%10]; //温度整数部分十位
}
}
}

#include <reg51.h> //调用51单片机的头文件
#include <Intrins.h>
sbit ds18b20=P1^2;
sbit gw=P1^0;
sbit sw=P1^1;
unsigned char TT,temp1;
unsigned char temp2;
unsigned char code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xff};
//---------------------------------------
//名称:复位DS18B20函数
//---------------------
void delay(int ms)
{
int i;
while(ms--)
for(i=0;i<120;i++);
}
//---------------------------------------
//名称:复位DS18B20函数
//---------------------
bit Reset(void)
{
unsigned int i;
bit k;
ds18b20=0; //拉低DQ总线开始复位
i=95; //保持DQ低大约870uS,符合不低于48US的要求
while(i--); //保持DQ低大约870uS,符合不低于48US的要求
//保持DQ低大约870uS,符合不低于48US的要求
ds18b20=1; //拉高准备接收数据
i=9; //大约80uS后
while(i--); //大约80uS后
//大约80uS后
k=ds18b20; //读出数据并保存
i=55; //维持约490US,符合总读时隙不低于480US的要求
while(i--); //维持约400US,符合总读时隙不低于480US的要求
//维持约400US,符合总读时隙不低于480US的要求
return k; //k=0为复位成功,k=1为复位失败
}
//---------------------------------------
//名称:读一字节函数
//---------------------------------------
unsigned char ReadByte(void)
{
unsigned int i;
unsigned char j,buf=0;
for(j=0;j<8;j++) //接收8次还原一个字节数据
{
buf=buf>>1; //接收前,想将接收缓冲区右移
ds18b20=0; //拉低
_nop_(); //维持2US,符合大于1US小于15US的规范
_nop_(); //维持2US,符合大于1US小于15US的规范
ds18b20=1; //拉高,为读数据做准备
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
_nop_(); //维持6US,符合大于1US小于15US的规范
if(ds18b20==1)
buf|=0x80; //读出1位数据保存于buf中
i=7; //维持约52US,符合总读时隙不低于60US的要求
while(i--); //维持约52US,符合总读时隙不低于60US的要求
//维持约52US,符合总读时隙不低于60US的要求
}
return buf; //退出的同时将接收缓冲区参数返回
}
//---------------------------------------
//名称:写一字节函数
//---------------------------------------
void WriteByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
for(j=0;j<8;j++)
{
if(dat&0x01) //如果写1
{
ds18b20=0; //拉低
_nop_(); //维持2US,符合大于1US小于15US的规范
_nop_(); //维持2US,符合大于1US小于15US的规范
ds18b20=1; //拉高
i=7; //维持约63US,符合不低于60US的要求
while(i--); //维持约63US,符合不低于60US的要求
}
else //如果写0
{
ds18b20=0; //拉低
i=7; //维持约63US,符合不低于60US的要求
while(i--); //维持约63US,符合不低于60US的要求
ds18b20=1; //拉高
_nop_(); //维持2US,符合大于1US的规范
_nop_(); //维持2US,符合大于1US的规范
}
dat=dat>>1; //写入字节右移1位
}
}
//---------------------------------------
//名称:DS18B20温度转换函数
//---------------------------------------
bit Convert(void)
{
if(Reset()==0) //复位DS18B20成功
{
WriteByte(0xcc); //写入跳过序列号命令字 Skip Rom
WriteByte(0x44); //写入温度转换命令字 Convert T
return 1; //启动温度转换成功
}
else //失败
{
return 0; //启动温度转换失败
}
}
//---------------------------------------
//名称:转换结束处理函数
//---------------------------------------
void ReadFlash(void)
{
unsigned char Lsb,Msb;
if(Reset()==0) //复位DS18B20成功
{
WriteByte(0xcc); //写入跳过序列号命令字 Skip Rom
WriteByte(0xbe); //写入读取数据令字 Read Scratchpad
Lsb=ReadByte(); //读出第一个字节暂存于LSB
Msb=ReadByte(); //读出第二个字节暂存于MSB
temp1=Lsb; //temp1内装温度参数的小数部分
temp2=Msb;//>>4)|(Lsb<<4);//temp2内装温度参数的整数部分
}
else
{
temp1=0; //如果复位失败,温度参数清零
temp2=0; //如果复位失败,温度参数清零
}
}
//---------------------------------------
void display(unsigned char ddd)
{
gw=1;
sw=0;
P2=tab[ddd/10];
delay(2);
P2=0x00;
delay(1);
gw=0;
sw=1;
P2=tab[ddd%10];
delay(2);
P2=0x00;
delay(1);
}
void main(void) //主函数,单片机开机后就是从这个函数开始运行
{
unsigned char TT;
while(1) //死循环,单片机初始化后,将一直运行这个死循环
{
if(Convert()==1) //启动转换
{
ReadFlash(); //读取温度
TT=(temp2<<4)|(temp1>>4);
display(TT);
}
}
}
|