萬用電路板

----纯属爱好,谁与共鸣

« 【图】LED3216“大屏电子钟”V1.0发布【图】爱好者仿制作品-LED3216(3) »

用DS18B20测温度,同时测出所使用的DS18B20的序列号

/**********************************************
程序名称:DS18B20应用程序,LCD1602显示
简要说明:DS18B20测温驱动,同时可以测出所使用的DS18B20的序列号
程序作者:1986zhaofeng <1986zhaofeng@163.com>
**********************************************/

#include<reg52.h>

#define uchar unsigned char
#define uint unsigned int
//定义1602指令集//
#define   CMD_clear  0x01             // 清除屏幕
#define   CMD_back  0x02             // DDRAM回零位,数据指针清零
#define   CMD_dec1  0x04             // 读入后AC(指针)减1,向左写
#define   CMD_add1  0x06             // 读入后AC(指针)加1,向右写
#define   CMD_dis_gb1  0x0f             // 开显示_开光标_开光标闪烁
#define   CMD_dis_gb2  0x0e             // 开显示_开光标_关光标闪烁
#define   CMD_dis_gb3  0x0c             // 开显示_关光标_关光标闪烁
#define   CMD_OFF_dis  0x08             // 关显示_关光标_关光标闪烁

sbit DQ= P2^0;
sbit lcden=P3^4;
sbit rs=P3^5;
uchar fCode[8];
uchar flg;

uchar num;
void delay(uint z)
{
 uint x,y;
 for (x=z;x>0;x--)
  for(y=110;y>0;y--);
}
void w_com(uchar com)
{
 rs=0;
 P0=com;
 delay(5);
 lcden=1;
 delay(5);
 lcden=0;
 
}
void w_data(uchar date)
{
 rs=1;
 P0=date;
 delay(5);
 lcden=1;
 delay(5);
 lcden=0;
 
}
void init()
{
 lcden=0;
 w_com(0x38);
 w_com(CMD_dis_gb3);
 w_com(0x06);
 w_com(0x01);
 w_com(0x80);
 
}
void print(uchar a,uchar *str){
  w_com(a);
  while(*str != '\0'){
   w_data(*str++);
        }
  *str = 0;
}
void print2(uchar a,uchar t){//设置写入地址和数据//
  w_com(a);
  w_data(t);
}


//===============================DS18B20驱动==============================//
                     // 定义DS18B20数据线

/**************************************************************************/
void Delay1(int num)//延时函数.
{
 while(num--) ;  //对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于为8us


/**************************************************************************/
void Init_DS18B20(void)//初始化ds1820
{
 unsigned char x=0;
 DQ = 1;    //DQ复位
 Delay1(8);  //稍做延时
 DQ = 0;    //单片机将DQ拉低
 Delay1(80); //精确延时 大于 480us
 DQ = 1;    //拉高总线
 Delay1(14);
 x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失,
 Delay1(20);
}
/**************************************************************************/
unsigned char ReadOneChar(void)//读一个字节
{
 unsigned char i=0;
 unsigned char dat = 0;
 for (i=8;i>0;i--)
 {
  DQ = 0; // 给脉冲信号
  dat>>=1;
  DQ = 1; // 给脉冲信号
  if(DQ)
  dat|=0x80;
  Delay1(4);
 }
 return(dat);
}

/**************************************************************************/
void WriteOneChar(unsigned char dat)//写一个字节
{
 unsigned char i=0;
 for (i=8; i>0; i--)
 {
  DQ = 0;
  DQ = dat&0x01;
  Delay1(5);
  DQ = 1;
  dat>>=1;
 }
}
/**************************************************************************/
unsigned int ReadTemperature(void)//读取温度
{
 unsigned char a=0;
 unsigned char b=0;
 int t=0;
 float tt=0;
 flg=0;
 Init_DS18B20();
 WriteOneChar(0xCC); // 跳过读序号列号的操作
 WriteOneChar(0x44); // 启动温度转换
 Init_DS18B20();
 WriteOneChar(0xCC); //跳过读序号列号的操作
 WriteOneChar(0xBE); //读取温度寄存器
//连续读取两个字节数据
 a=ReadOneChar();  //读低8位
 b=ReadOneChar(); //读高8位
//将高低两个字节合成一个整形变量
//计算机中对于负数是利用补码来表示的

 t=b;
 t<<=8;
 t=t|a;
//若是负值, 读取出来的数值是用补码表示的

 if(b&0x80)
  { 
   flg=1;
   t=(~t+1);
  }
//使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度

 tt=t*0.0625;
 t= tt*10+0.5; //放大10倍输出并四舍五入
 return(t);
}
/**************************************************************************/
void printTemperature(void){//写一个字节
  int i=0;
 unsigned char a=0,b=0,c=0;

 i=ReadTemperature();//读温度并送显
 print2(0x80,' ');
 if(flg)
  print2(0x80,'-');
 a=i/100;
 if(a > 0x09){
  print(0x81,"--.-");
 }else
 { 
  print2(0x81,a+0x30); //显示温度十位
  b=i/10-a*10;
  print2(0x82,b+0x30); //个位
  print(0x83,".");  //"."
  c=i-a*100-b*10;
  print2(0x84,c+0x30); //小位1位
 }  
 print2(0x85,0xdf); //度C
 print2(0x86,0x43);  
}
/**********************************************************
*系列号显示子程序
*显示顺序(从左到右)8位CRC编码->48位序列号->8位产品系列编码
**********************************************************/
void DispCode()
{
 unsigned char i,temp;
 w_com(0x80+0x40);
 for (i=8;i>0;i--)
  {
 //显示高4位
 temp = fCode[i-1]>>4;
  if (temp<10) //ASCII码转换
    w_data(temp += 0x30);
  else
    w_data(temp += 0x37);
 //显示低4位
  temp = fCode[i-1]&0x0f;
  if (temp<10) //ASCII码转换
    w_data(temp += 0x30);
  else
    w_data(temp += 0x37);
  }
}
void main()
{ uchar i;
 init();
 Init_DS18B20();
 WriteOneChar(0x33);
 for (i=0;i<8;i++)
 {//读取64位系列号
  fCode[i] =  ReadOneChar();
 }
 Init_DS18B20();
 DispCode();
 while(1) 
 {
  printTemperature();
 }
}

  • quote 1.susfly
  • 那请问下一根线上挂两个的时候,发读序列号指令时到底两个温度传感器是怎么工作的?这时候这跟线上取得的序列号是哪个的序列号?
  • 2009-2-8 19:15:18 回复该留言

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

赞助商广告

最近发表

热文排行

最新评论及回复

广告

图标汇集

Powered By Z-Blog 1.8 Walle Build 100427

Copyright 2008-2011 JiangX.com 萬用電路板 All Rights Reserved.
鄂ICP备08003060号 [login]