1.DS18D20是单总线器件,在一根通信线上可以挂很多这样的数字温度传感器。
2.DS18D20特点 : 通信采用1-Wire接口
唯一的64位序列码储存在板载ROM中
可从数据线供电,电压3.0~5.5
可测温度-55~125摄氏度
-10~85摄氏度范围内精确度为正负0.5
温度计分辨率可设置为9~12位,12位对应0.0625摄氏度
3.因为是单总线所以时序要求很严格
单总线限号类型:复位脉冲,存在脉冲,写0,写1,读0,读1
数据传输是从最低位开始
4.关于时序,老规矩,自己去查数据手册
5.忽略ROM指令(CCh)
温度转换指令 (44h)
读暂存器指令 (BEh)
写暂存器指令 (4Eh)
拷贝暂存器指令(48h)
#include<reg52.h>
#include<intrins.h>
#define MAIN_Fosc 11059200UL//宏定义主时钟
sbit DS = P2^2;//DS18B20单总线
sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
typedef unsigned char INT8U;//使用typedef给已有的数据类型取别名
typedef unsigned char uchar;
typedef unsigned char u8;
typedef unsigned int INT16U;
typedef unsigned int uint;
typedef unsigned int u16;
uchar code Segment[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};//数码管段选
uchar code Position[] = {0xfe, 0xfd, 0xfb , 0xf7};//数码管位选码
void Delay_Ms(INT16U ms)//12T 51单片机自适应主时钟毫秒级延时函数
{
INT16U i;
do{
i = MAIN_Fosc/96000;
while(--i);
} while(--ms);//96T per loop 每一条自减语句需要96个时钟周期,需要96个脉冲
}
/*进入一次延时函数要11.95,执行一次us--要6.5us*/
void Delay_us(INT8U us)
{
while(us--);
}
/*数码管显示函数*/
void display(INT16U Value)
{
DU = 0;//关闭段选
P0 = Segment[Value/100];//百位
DU = 1;//打开段
DU = 0;//关闭段
WE = 0;//关闭位
P0 = Position[0];//点亮第一个数码管
WE = 1;//打开位
WE = 0;//关闭位
Delay_Ms(2);
DU = 0;
P0 = Segment[Value%100/10]|0x80;
DU = 1;
DU = 0;
WE = 0;
P0 = Position[1];
WE = 1;
WE = 0;
Delay_Ms(2);
DU = 0;
P0 = Segment[Value%10];
DU = 1;
DU = 0;
WE = 0;
P0 = Position[2];
WE = 1;
WE = 0;
Delay_Ms(2);
}
/*初始化时序包括复位DS18B20和接收DS18B20返回的存在信号*/
bit DS_Init()
{
bit i;
DS = 1;
_nop_();
DS = 0;
Delay_us(75);//拉低总线499.45us,挂接在总线上的18B20将会被复位
DS = 1;//释放总线
Delay_us(4);//延时37,95us,等待18B20发回存在信号
i = DS;
Delay_us(20);//延时141.95us
DS = 1;
_nop_();
return (i);
}
/*写时序,一个字节*/
void Write_Byte(uchar DAT)
{
uchar i ;
for(i=0;i<8;i++)
{
DS = 0;
_nop_();//产生写时序
DS = DAT&0x01;
Delay_us(10);//76.95us
DS = 1;//释放总线准备下一次数据写入
_nop_();
DAT>>=1;
}
}
/*读时序,一个字节*/
uchar Read_Byte()
{
uchar i,j,DAT;
for(i=0;i<8;i++)
{
DS = 0;
_nop_();//产生读时序
DS = 1;
_nop_(); //释放总线
j = DS;
Delay_us(10);//76.95us
DS = 1;
_nop_();
DAT = (j<<7)|(DAT>>1);
}
return(DAT);
}
void main()
{
uint i;
uchar L,M;
while(1)
{
DS_Init();//初始化
Write_Byte(0xcc);//发送跳跃ROM指令
Write_Byte(0x44);//发送温度转换指令
DS_Init();//初始化
Write_Byte(0xcc);//发送跳跃ROM指令
Write_Byte(0xbe);//读取DS18B20暂存器指令
L = Read_Byte();
M = Read_Byte();
i = M;
i<<=8;
i|= L;
i = i*0.0625*10+0.5;
display(i);
}
}