C51之数字温度传感器DS18D20

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);
   }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值