1wire总线的应用-DS18B20温度采集工芯片的应用.

  使用DS18B20时,请务必注意不要插错方向.否则器件可能直接烧掉...DS18B20目前市场价大约在20元左右...12bit对于一般性的温度采集,足以.

  以下是我早期所写的,程序不是很好.因为我直接用了float类型;仅此做为参考学习...float类型十分占内存,对于单片机来说内存是十分宝贵的.


#include <AT89X51.H>
/*
作者:李金浩
QQ:67260745
E-mail:LTSoft918@163.com
---------------------------
DS18b20默认设置为12位.乘0.0625就可以得到实际的温度
开发环境:6MHZ,SST89C58 in keil C 7.01 Mon,平台:恒坚HJ51/AVR开发系统
断开DS18b20的VCC引脚,温度则为85℃可用来测试是否正常
*/
#define DSDIP P3_2//P3^2作为1线采集端口
unsigned char c1,c10,c100,cDec,mark;//定义全局变量分别返回个,十,百,符号位
//0~9,如果带小数点,则高位加8就可以了,也就是8*16

//LED中的数据为共阳极显示
code unsigned char LedChar[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
                      0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//LED共阴极显示
/*const char LedChar[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
                      0xbF,0x86,0xdB,0xcF,0xe6,0xeD,0xfD,0x87,0xfF,0xeF};*/
//1~8号LED数据管地址号
code unsigned char Led[]={0x01,0x02,0x04,0x08,
                  0x10,0x20,0x40,0x80};
void display(unsigned char showbit,LedNum);
void ShowNum(unsigned char numbit,num1,num10,num100,mark);
//---------------------------------------------
//6MHZ情况下
/*
  delay(1);//60uS
  delay(2);//106uS
  delay(11);//526uS
  void delay8us(void);
  void delay34us(void);
//void delay14us(void);
*/
//------------------------------------------------
//------------------------------------------------
void delay(unsigned char times)
{
   //不精确延时,误差很大
    unsigned char i;
    for(;times>0;times--)
       for(i=0;i<255;i--);
}
//------------------------------------------------
//------------------------------------------------
void delay34us(void)
{
  unsigned char i;
  for(i=0;i<200;i--);
}

/*------------------------------------------------
             ds18b20功能实现部分
通过c1,c10,c100,cDec,mark;全局变量返回个,十,百,符号位
unsigned char  RestDS(void);//复位
unsigned char  ReadDS(void);//读取1个字节
void writeDS(unsigned char val)//写入1个字节
float ReadTemp(void)//读取温度
------------------------------------------------*/
/*-------------------------
       始化复位
--------------------------*/
unsigned char  RestDS(void)
{
 unsigned char isexist;
 DSDIP=0;
 delay(11);//526uS
 DSDIP=1;
 //等待15~60us
 delay34us();
 isexist=DSDIP;//取得ds18b20是否存在
 delay(2);//106uS
 return(isexist);
}
/*-------------------------------
         Read a byte
---------------------------------*/
unsigned char ReadDS(void)
{
 unsigned char  i,t,value=0;
 for(i=8;i>0;i--)
 {
  value>>=1;
  DSDIP=0;
  t++;//2us
  DSDIP=1;
  t++;//2us
  t++;//2us
  if(DSDIP) value|=0x80;
  t++;//2us;//读取时间间隙,在于1us
 }
 return(value);
}

/*-----------------------------
       Write a byte
-------------------------------*/
void writeDS(unsigned char val)
{
  unsigned char i;
  for(i=8;i>0;i--)
  {
  DSDIP=0;
  DSDIP=val&0x01;//每次写1位,通过val右移得到
  delay34us();//延时34us(15~60us采样时间)
  DSDIP=1;//释放总线
  val>>=1;//计算的同时会产生一个2us的时间间隙
  }
// delay8us();//2次写的时间间隙要大于1us
}
/*---------------------------------
        Read ds18b20 ID
----------------------------------*/
unsigned char ReadID(void)
{
 unsigned char ID;
  RestDS();//复位ds18b20
  writeDS(0x33);//读ROM:0x33指令
  ID=ReadDS();
  return(ID);
}
/*----------------------------------------------------
                     ds18b20读取温度
通过c1,c10,c100,cDec,mark;全局变量返回个,十,百,符号位
函数本身返回一个float类型的dTemp温度值
----------------------------------------------------*/
float ReadTemp(void)
{
  unsigned int temp;
  unsigned char lowbit,highbit;
  float dTemp=0;
  RestDS();//复位ds18b20
  writeDS(0xcc);//跳过ROM
  writeDS(0x44);//发出温度转换命令
  //------
  RestDS();
  writeDS(0xcc);//跳过ROM
  writeDS(0xBE);//读暂存存贮器
  lowbit=ReadDS();//取得低8位
  highbit=ReadDS();//取得高8位
  temp=highbit<<8;
  temp=temp+lowbit;//合成16位的二进制数
 /*
 判断前5位,是否为:
 1:负
 0:正
 */
  mark=1;//1:表示为正温度 0:负温度(mark为全局变量)
  if((highbit>>3)!=0)
  {
   //为负则求反+1
   temp=~temp+1;
   mark=0;
  }
  //---------
   dTemp=temp*0.0625;//得到带小数点的实际温度
   temp=dTemp;//temp为int型,dTemp为float型,强制去掉小数
  /*全局变量分别返回个,十,百,符号位*/
   c100=temp/100;//得到百位
   c10=(temp-c100*100)/10;//得到十位
   c1=temp-c100*100-c10*10;//得到个位
   cDec=(dTemp-temp)*10;//得到小数位
  return(dTemp);
}
//-------------------main()-----------------------
void main(void)
{
 unsigned char dsID;
 while (1)
 {
  dsID=ReadID();
  ReadTemp();//取得ds18b20温度
  ShowNum(mark,c100,c10,c1,cDec);//显示采集到的温度
 }
}
/*-----------------------------------------------------------------
                      显示函数
showmark,num100,num10,num1,numDec
符号位    百位  十位   个位  小数位
-----------------------------------------------------------------*/
void ShowNum(unsigned char showmark,num100,num10,num1,numDec)
{
  unsigned char DT=50;
  display(1,numDec);//小数位
  delay(DT);
  display(2,num1+10);//个位
  delay(DT);
  display(3,num10);//十位
  delay(DT);
  display(4,num100);//百位
  delay(DT);
  //只有当为负温度时才显示符号位
  if(showmark==0)
  {
   display(5,0xBF);//符号位(负)
   delay(DT);
  }
}
/*
单位输出
showbit:选择输出的LED管子
LedNum:要输出的数据
*/
void display(unsigned char showbit,LedNum)
{
  P2_7=0;//P2_7不知道干什么用,恒坚没有告诉我,根据实际情况估计是片选信号
  P0=Led[showbit-1]; //给P2_6一个脉冲,选择在哪个LED上显示
  P2_6=1;
  P2_6=0;
 //-------------
  P0=LedChar[LedNum];//给P2_5一个脉冲,将要显示的数据显示缓冲区中
  P2_5=1;
  P2_5=0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lijinjie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值