5989|15

62

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

慕名而来,求救于牛人,望指点迷津。 [复制链接]

前段时间我做了个18B20测温的程序,我在网上查了好多资料了,发现这是一个很老的程序了,所以在这又把这个问题提出来我很是惭愧啊,废话少说,情况如下:

我用买来的板子实现了18B20单点测温,完全没问题,

但是我想测两个点的温度,一个测空气温度,一个测水温,而我觉得用读取单总线上18B20的ROM的方法的我不太懂,所以想到了这样办法,两个18B20接P3.6和P3.7,两套共阳极数码管共用位选,位选驱动我用的 是74LS138,然后两套数码管的段选分别接P0和P1,结果我在原有测一个点的程序的基础上改,改完后,接到面包板上一看,两套数码管显示的都是0,连85.0度这个都没有,

我想请高手帮忙改改程序,或者指点指点。不胜感激~~~·

最新回复

#include "ds18b20.h" #include "stcdelay.h"//这里包含延迟函数,需要根据需要自己更改 #define COMMAND_SKIP_ROM 0xcc #define COMMAND_CONVERT_TEMPERATURE 0x44 #define COMMAND_READ_SCRATCHPAD 0xbe #define COMMAND_READ_ROM 0x33 static void Init18B20() {         BYTE i = 0;         DQ_PIN = 1;         NOP();         //产生一个高电平         NOP();                                                                                        DQ_PIN = 0;         //480us        ~ 960us         for(i = 0; i < 15; i++)         {                 DelayUS(40);                 }         DQ_PIN = 1;           // releases  the  bus  and  goes  into  receive  mode         //等待15~60us后再检测         DelayUS(40);           DelayUS(30);         //初始化低电平会持续60~240us,然后会自动拉高,需持续至少480us,这里省略了检测         for(i = 0; i < 12; i++)         {                 DelayUS(40);                 } } static void SetSingleByte(BYTE byte) {         BYTE i = 0;                 /********************************************************************************************************         To generate a Write 1 time slot, after pulling the 1-Wire bus low, the bus master must release the 1-Wire         bus within 15μs. When the bus is released, the 5k pullup resistor will pull the bus high. To generate a         Write 0 time slot, after pulling the 1-Wire bus low, the bus master must continue to hold the bus low for         the duration of the time slot (at least 60μs).         *********************************************************************************************************/         for(i = 0; i < 8; i++)         {                  DQ_PIN = 0;                 if(TEST_BIT(byte, i))        //若是写入1,在1~15us内释放总线,且持续至少60us等待ds18b20读取                 {                         DelayUS(2);                         //必须大于1us后再释放总线                         DQ_PIN = 1;          //释放总线                         DelayUS(30);                         DelayUS(30);                                          }                 else //若是写入0,则保持低电平60us~120us,然后释放                 {                         DelayUS(30);                         DelayUS(30);                                                   DQ_PIN = 1;          //释放总线                     DelayUS(2);         //下一个时隙的间隔必须大于1us                                 }                         } } static BYTE GetSingleByte() {         BYTE Ret = 0;         BYTE i = 0;         /*******************************************************************************************************************                  All  read  time  slots  must  be  a  minimum  of  60μs  in  duration  with  a  minimum  of  a  1μs  recovery  time         between  slots.  A  read  time  slot  is  initiated  by  the  master  device  pulling  the  1-Wire  bus  low  for  a         minimum of 1μs and then releasing the bus (see Figure 14).  After the master initiates the read time slot,         the DS18B20 will begin transmitting a 1 or 0 on bus. The DS18B20 transmits a 1 by leaving the bus high         and transmits a 0 by pulling the bus low. When transmitting a 0, the DS18B20 will release the bus by the         end of the time slot, and the bus will be pulled back to its high idle state by the pullup resister. Output DS18B20         data from the DS18B20 is valid for 15μs after the falling edge that initiated the read time slot. Therefore,         the master must release the bus and then sample the bus state within 15μs from the start of the slot.         *********************************************************************************************************************/         for(i = 0; i < 8; i++)         {                  DQ_PIN = 0;                 //保持至少1us                 DelayUS(2);                 DQ_PIN = 1;        //释放总线                    DelayUS(5);        //在15us之内采集即可             //15u之内采集                 if(DQ_PIN)                                                                                                                          {                         SET_BIT(Ret, i);                 }                   //读写时隙必须大于60us            DelayUS(30);            DelayUS(30);                            }                return Ret; } void ConvertTemperature() {         Init18B20();         SetSingleByte(COMMAND_SKIP_ROM);         SetSingleByte(COMMAND_CONVERT_TEMPERATURE); } WORD GetTemperature() {         BYTE loTemp = 0;         BYTE hiTemp = 0;         Init18B20();         SetSingleByte(COMMAND_SKIP_ROM);         SetSingleByte(COMMAND_READ_SCRATCHPAD);         loTemp = GetSingleByte();         hiTemp = GetSingleByte();         return MAKEWORD(loTemp, hiTemp);         } 复制代码 注意:其中的延迟函数需要根据自己的需要实现,我用的是stc的片子,指令周期和c51不一样。  详情 回复 发表于 2010-4-6 22:52
点赞 关注

回复
举报

74

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
这是我改的程序。高人请指教

[code]
//DS18B20的读写程序,数据脚P2.7                     //
//温度传感器18B20汇编程序,采用器件默认的12位转化   //
//最大转化时间750微秒,显示温度-55到+125度,显示精度 //
//为0.1度,显示采用4位LED共阳显示测温值            //
//P0口为段码输入,P34~P37为位选                       //
/***************************************************/


#include
#include                             //_nop_();延时函数用
      

#define  uchar unsigned char
#define  uint  unsigned int
sbit     DQ=P3^7;                               //温度输入口1
sbit     P17=P1^7;                              //LED小数点控制                  ]
sbit     DP=P3^6;                        //温度输入口2
sbit     P07=P0^7;                                   //led小数点控制2
uint     h;
uint     temp2;
uint     temp;


//
//
//**************温度小数部分用查表法***********//
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};


uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共阳LED段码表        "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9" "不亮" "-"              

uchar data temp_data[2]={0x00,0x00};             //读出温度暂放          
uchar data temp_dat[2]={0x00,0x00};  
uchar data display[5]={0x00,0x00,0x00,0x00,0x00};     //显示单元数据,共4个数据和一个运算暂用                 
uchar data display2[5]={0x00,0x00,0x00,0x00,0x00};

//
//
//
/*****************11us延时函数*************************/
//
void delay(uint t)
{
  for (;t>0;t--);
}
//

/****************显示扫描函数***************************/
scan()
{
  char k;
     for(k=0;k<4;k++)                     //4位LED扫描控制         
{
  P0=dis_7[display[k]];          //数据显示         
  P1=dis_7[display2[k]] ;//小数点显示          

  if (k==1){P17=0;}
  if (k==1){P07=0;}  

  P2=k;                 //位选
  delay(200);
}
}

/****************显示扫描函数2***************************/

//
//
/****************DS18B20复位函数1************************/
ow_reset(void)
{
char presence=1;
while(presence)
{
  while(presence)
   {
DQ=1;_nop_();_nop_();//从高拉倒低  
DQ=0;                                       
delay(50);           //550 us
DQ=1;                                       
delay(6);            //66 us
presence=DQ;         //presence=0 复位成功,继续下一步         
   }
   delay(45);            //延时500 us
   presence=~DQ;         
}
DQ=1;                   //拉高电平
}
/***********DS18B20复位函数2**************/
ow_reset2(void)
{
char presence2=1;
while(presence2)
{
  while(presence2)
   {
    DP=1;_nop_();_nop_();//从高拉倒低  
DP=0;                                       
delay(50);           //550 us
DP=1;                                       
delay(6);            //66 us
presence2=DP;         //presence=0 复位成功,继续下一步         
   }
   delay(45);            //延时500 us
   presence2=~DP;         
}
DP=1;                   //拉高电平
}
//
//
/****************DS18B20写命令函数************************/
//向1-WIRE 总线上写1个字节
void write_byte(uchar val)
{
  uchar i;
  for(i=8;i>0;i--)
  {
   DQ=1;_nop_();_nop_();                  //从高拉倒低  
   DQ=0;_nop_();_nop_();_nop_();_nop_();  //5 us
   DQ=val&0x01;                           //最低位移出  
   delay(6);                              //66 us
   val=val/2;                             //右移1位
   }
   DQ=1;
   delay(1);
}
/****************DS18B20写命令函数2************************/
//向1-WIRE 总线上写1个字节          
void write_byte2(uchar valu)
{
  uchar j;
  for(j=8;j>0;j--)
  {
   DP=1;_nop_();_nop_();                  //从高拉倒低  
   DP=0;_nop_();_nop_();_nop_();_nop_();  //5 us
   DP=valu&0x01;                           //最低位移出  
   delay(6);                              //66 us
   valu=valu/2;                             //右移1位
   }
   DP=1;
   delay(1);
}
//
/****************DS18B20读1字节函数************************/
//从总线上取1个字节          
uchar read_byte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
  DQ=1;_nop_();_nop_();
  value>>=1;
  DQ=0;_nop_();_nop_();_nop_();_nop_();         //4 us
  DQ=1;_nop_();_nop_();_nop_();_nop_();         //4 us
  if(DQ)value|=0x80;
  delay(6);                                     //66 us
}
DQ=1;
return(value);
}
/****************DS18B20读1字节函数2************************/
//从总线上取1个字节          
uchar read_byte2(void)
{
uchar i;
uchar valued=0;
for(i=8;i>0;i--)
{
  DP=1;_nop_();_nop_();
  valued>>=1;
  DP=0;_nop_();_nop_();_nop_();_nop_();         //4 us
  DP=1;_nop_();_nop_();_nop_();_nop_();         //4 us
  if(DP)valued|=0x80;
  delay(6);                                     //66 us
}
DP=1;
return(valued);
}
//
/****************读出温度函数************************/
//
uint read_temp()
{
  ow_reset();                  //总线复位
  delay(200);
  write_byte(0xcc);            //发命令
  write_byte(0x44);            //发转换命令         
  ow_reset();
  delay(1);
  write_byte(0xcc);            //发命令
  write_byte(0xbe);
  temp_data[0]=read_byte();    //读温度值的第字节  
  temp_data[1]=read_byte();    //读温度值的高字节  
  temp=temp_data[1];
  temp<<=8;                                               
  temp=temp|temp_data[0];      // 两字节合成一个整型变量。         
  return temp;                 //返回温度值
}
/****************读出温度函数2************************/
//
uint read_temp2()
{
  ow_reset2();                  //总线复位
  delay(200);
  write_byte2(0xcc);            //发命令
  write_byte2(0x44);            //发转换命令         
  ow_reset2();
  delay(1);
  write_byte2(0xcc);            //发命令
  write_byte2(0xbe);
  temp_dat[0]=read_byte2();    //读温度值的第字节  
  temp_dat[1]=read_byte2();    //读温度值的高字节  
  temp2=temp_dat[1];
  temp2<<=8;                                               
  temp2=temp2|temp_dat[0];      // 两字节合成一个整型变量。         
  return temp2;                //返回温度值
}
//
/****************温度数据处理函数************************/

//二进制高字节的低半字节和低字节的高半字节组成一字节,这个                 
//字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩             
//下的低字节的低半字节转化成十进制后,就是温度值的小数部分                 

/********************************************************/
work_temp(uint tem)
{
uchar n=0;
if(tem>6348)                        // 温度值正负判断   
     {tem=65536-tem;n=1;}            // 负温度求补码,标志位置1          
      display[4]=tem&0x0f;           // 取小数部分的值         
  display[0]=ditab[display[4]];  // 存入小数部分显示值          
      display[4]=tem>>4;             // 取中间八位,即整数部分的值          
  display[3]=display[4]/100;     // 取百位数据暂存  
  display[2]=display[4]/10%10;      // 取十位数据暂存   
  display[1]=display[4]%10;                  // 取个位数据暂存   
/******************符号位显示判断**************************/
  if(!display[3])
  {
    display[3]=0x0a;           //最高位为0时不显示
    if(!display[2])
{
   display[2]=0x0a;        //次高位为0时不显示
}
  }
  if(n){display[3]=0x0b;}      //负温度时最高位显示"-"
}

/****************温度数据处理函数2************************/

//二进制高字节的低半字节和低字节的高半字节组成一字节,这个                 
//字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩             
//下的低字节的低半字节转化成十进制后,就是温度值的小数部分                 

/********************************************************/
work_temp2(uint ten)
{
uchar n=0;
if(ten>6348)                        // 温度值正负判断   
     {ten=65536-ten;n=1;}            // 负温度求补码,标志位置1          
      display2[4]=ten&0x0f;           // 取小数部分的值         
  display2[0]=ditab[display2[4]];  // 存入小数部分显示值          
      display2[4]=ten>>4;             // 取中间八位,即整数部分的值          
  display2[3]=display2[4]/100;     // 取百位数据暂存  
  display2[2]=display2[4]/10%10;      // 取十位数据暂存   
  display2[1]=display2[4]%10;                  // 取个位数据暂存   
/******************符号位显示判断**************************/
  if(!display2[3])
  {
    display2[3]=0x0a;           //最高位为0时不显示
    if(!display2[2])
{
   display2[2]=0x0a;        //次高位为0时不显示
}
  }
  if(n){display2[3]=0x0b;}      //负温度时最高位显示"-"
}
//
//
/****************主函数************************/
void main()
{
P0=0xff;
P1=0xff;                 //初始化端口         
P2=0xff;
  for(h=0;h<4;h++)              //开机显示"0000"
      {display[h]=0;
           display2[h]=0;}
  for(h=0;h<100;h++)            //开机显示"0000"
      {scan();}

  ow_reset();                 //开机先转换一次   
  write_byte(0xcc);             //Skip ROM         
  write_byte(0x44);             //发转换命令   
  delay(150);
  ow_reset2();
  write_byte2(0xcc);             //Skip ROM         
  write_byte2(0x44);
    while(1)
  {

  work_temp(read_temp());     //处理温度数据          
  delay(100);
  work_temp2(read_temp2());   
                  
  }       

  scan();        //显示温度值  
                                              
}
//***********************结束**************************//
 
 

回复

90

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
这种调试需要软硬同步调的,应设置断点,在不影响通讯的情况下,截取各步骤获得的数据,进而判断是哪里出了问题。
另外需要注意的问题则是通讯电路的端口设置以及上拉或下拉的功率是否过大或过小,从而影响通讯结果
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

4
 
while(1)
{

work_temp(read_temp()); //处理温度数据
delay(100);
work_temp2(read_temp2());

}

scan(); //显示温度值

}
显示结果的函数在While(1)之外?
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

5
 
引用 2 楼 c_rabbit 的回复:
这种调试需要软硬同步调的,应设置断点,在不影响通讯的情况下,截取各步骤获得的数据,进而判断是哪里出了问题。
另外需要注意的问题则是通讯电路的端口设置以及上拉或下拉的功率是否过大或过小,从而影响通讯结果
没怎么看懂啊,您是虾米意思啊,我是菜鸟。能简单点说吗,
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

6
 
你先试试把

while(1)
{

work_temp(read_temp()); //处理温度数据
delay(100);
work_temp2(read_temp2());

}

scan(); //显示温度值

}
这里改成

while(1)
{

work_temp(read_temp()); //处理温度数据
delay(100);
work_temp2(read_temp2());
scan(); //显示温度值

}

}
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

7
 
18B20的时序比较严格,具体要求楼主自己看一下芯片手册吧。
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

8
 
引用 5 楼 c_rabbit 的回复:
你先试试把

while(1)
{

work_temp(read_temp()); //处理温度数据
delay(100);
work_temp2(read_temp2());

}

scan(); //显示温度值

}
这里改成

while(1)
{

work_temp(read_temp()); //处理温度数据
delay(100);
wor……


谢谢噢,我试试
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

9
 
............路过
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

10
 
从51单片机白痴到51单片机高手的快速成长

推荐一个不错的51单片机学习视频教程(高清晰版本)电驴下载   也可以用迅雷下载
飞龙教程------51单片机
需要更多单片信息请与我联系
飞龙QQ:9086074
希望认识更多的单片机开发朋友一起交流   第一次做教程不好多多见谅

博客BLOG   :           http://hi.baidu.com/alalmn

推荐一个不错的51单片机学习视频教程
飞龙教程------51单片机
飞龙QQ:9086074
51单片机=====单片机的学习
http://v.ku6.com/show/2HAQ5tLXh4rUFyto.html
51单片机=====最小51系统
http://v.ku6.com/show/mUa5kbLA1kQe1DSV.html
51单片机=====跑马灯(LED)
http://v.ku6.com/show/ki1nwsD0YCYnrQX7.html
51单片机=====色环电阻识别方法
http://v.ku6.com/show/9ZxwxSeT2WdxebAS.html
51单片机=====蜂鸣器、
http://v.ku6.com/show/xHdmQxBPAAmjQMSx.html
51单片机===== 数码管
http://v.ku6.com/show/bkN2UtqwhQwRZwFa.html
51单片机===按键(独立按键/矩阵键盘)
http://v.ku6.com/show/6ziTdd5-WdbeqxMS.html、
51单片机===ds18B20数字温度计
http://v.ku6.com/show/dGBIWAKC_ON8tPKG.html
51单片机=====STC串口下载(MAX232)
http://v.ku6.com/show/c1Xa2EjQ8_A-6yES.html
51单片机=====1602液晶
http://v.ku6.com/show/Xlw3YhdfHtr-4b6X.html
51单片机=====nokia5110屏幕
http://v.ku6.com/show/F3R_wbFim8OHU2J7.html



推荐一个不错的51单片机学习视频教程(高清晰版本)电驴下载   也可以用迅雷下载
飞龙教程------51单片机
飞龙QQ:9086074
51单片机=====单片机的学习
2010-3-14鍗曠墖鏈虹殑瀛︿範.rar (42.98 MB)
51单片机=====最小51系统
2010-3-23鏈灏51绯荤% 9F.rar (123.95 MB)
51单片机=====跑马灯(LED)
2010.3.6--LED.rar (132.8 MB)
51单片机=====色环电阻识别方法
2010-3-6鐢甸樆.rar (64.21 MB)
51单片机=====蜂鸣器、
2010-3-8铚傞福鍣.rar (163.68 MB)
51单片机===== 数码管
2010-3-11鏁扮爜绠.rar (315.21 MB)
51单片机===按键(独立按键/矩阵键盘)
2010-3-17鎸夐敭.rar (62.88 MB)
51单片机===ds18B20数字温度计
2010-3-19-ds18B20娓╁害.rar (45.4 MB)
51单片机=====STC串口下载(MAX232)
2010-3-21-STC涓插彛涓嬭浇.rar (155.15 MB)
二,十,十六,进制转换--问题
浜岋紝鍗侊紝鍗佸叚锛岃繘鍒惰浆鎹--闂.rar (11.23 MB)
51单片机=====1602液晶
2010-3-28-1602娑叉櫠.rar (71.77 MB)
 
 
 

回复

50

帖子

0

TA的资源

一粒金砂(初级)

11
 
看贴子,跟跟贴,是我的美德,呵呵
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

12
 
delay()
问题所在
每次调用这个函数所需要的保护现场、传递参数、恢复现场所需要的时间你没有考虑进去,实际延时时间应该要加上一个固定长度。
这导致delay(6)实际上延时可能是好几倍。
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

13
 
   帮顶个。。。。
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

14
 
5555555555555555555555555555555555555555
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

15
 
18b20时序要求比较严格(在几十微秒内的误差),所以对其进行操作时一定要禁止中断。下面是我的代码,完全可用。

  1. #ifndef _DS18B20_H_
  2. #define _DS18B20_H_
  3. #include "const.h"


  4. //更改为合适的引脚
  5. #define DQ_PIN P1_7

  6. /********************************************************************************
  7.                                  bit 7    bit 6   bit 5   bit 4   bit 3   bit 2    bit 1   bit 0
  8. LS Byte          2^3      2^2     2^1     2^0     2^-1    2^-2     2^-3    2^-4

  9.                                bit 15   bit 14  bit 13  bit 12  bit 11  bit 10   bit 9   bit 8
  10. MS Byte          S        S       S       S       S       2^6      2^5     2^4
  11. **********************************************************************************/
  12. //调用时需要禁止中断,最高位是符号,十进制
  13. void ConvertTemperature();
  14. WORD GetTemperature();

  15. ////////////////////////////////////
  16. //以下为内部函数
  17. static void Init18B20();
  18. static void SetSingleByte(BYTE byte);
  19. static BYTE GetSingleByte();


  20. #endif
复制代码
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

16
 

  1. #include "ds18b20.h"
  2. #include "stcdelay.h"//这里包含延迟函数,需要根据需要自己更改


  3. #define COMMAND_SKIP_ROM 0xcc
  4. #define COMMAND_CONVERT_TEMPERATURE 0x44
  5. #define COMMAND_READ_SCRATCHPAD 0xbe
  6. #define COMMAND_READ_ROM 0x33




  7. static void Init18B20()
  8. {

  9.         BYTE i = 0;

  10.         DQ_PIN = 1;
  11.         NOP();         //产生一个高电平
  12.         NOP();                               
  13.        
  14.                                        
  15.         DQ_PIN = 0;

  16.         //480us        ~ 960us
  17.         for(i = 0; i < 15; i++)
  18.         {
  19.                 DelayUS(40);        
  20.         }

  21.         DQ_PIN = 1;           // releases  the  bus  and  goes  into  receive  mode

  22.         //等待15~60us后再检测
  23.         DelayUS(40);  
  24.         DelayUS(30);



  25.         //初始化低电平会持续60~240us,然后会自动拉高,需持续至少480us,这里省略了检测

  26.         for(i = 0; i < 12; i++)
  27.         {
  28.                 DelayUS(40);        
  29.         }

  30. }

  31. static void SetSingleByte(BYTE byte)
  32. {
  33.         BYTE i = 0;
  34.        

  35.         /********************************************************************************************************
  36.         To generate a Write 1 time slot, after pulling the 1-Wire bus low, the bus master must release the 1-Wire
  37.         bus within 15μs. When the bus is released, the 5k pullup resistor will pull the bus high. To generate a
  38.         Write 0 time slot, after pulling the 1-Wire bus low, the bus master must continue to hold the bus low for
  39.         the duration of the time slot (at least 60μs).
  40.         *********************************************************************************************************/

  41.         for(i = 0; i < 8; i++)
  42.         {

  43.                  DQ_PIN = 0;

  44.                 if(TEST_BIT(byte, i))        //若是写入1,在1~15us内释放总线,且持续至少60us等待ds18b20读取
  45.                 {

  46.                         DelayUS(2);
  47.                         //必须大于1us后再释放总线
  48.                         DQ_PIN = 1;          //释放总线

  49.                         DelayUS(30);
  50.                         DelayUS(30);                         
  51.                 }
  52.                 else //若是写入0,则保持低电平60us~120us,然后释放
  53.                 {

  54.                         DelayUS(30);
  55.                         DelayUS(30);
  56.                          
  57.                         DQ_PIN = 1;          //释放总线

  58.                     DelayUS(2);         //下一个时隙的间隔必须大于1us
  59.                
  60.                 }
  61.                
  62.         }


  63. }

  64. static BYTE GetSingleByte()
  65. {
  66.         BYTE Ret = 0;
  67.         BYTE i = 0;

  68.         /*******************************************************************************************************************         
  69.         All  read  time  slots  must  be  a  minimum  of  60μs  in  duration  with  a  minimum  of  a  1μs  recovery  time
  70.         between  slots.  A  read  time  slot  is  initiated  by  the  master  device  pulling  the  1-Wire  bus  low  for  a
  71.         minimum of 1μs and then releasing the bus (see Figure 14).  After the master initiates the read time slot,
  72.         the DS18B20 will begin transmitting a 1 or 0 on bus. The DS18B20 transmits a 1 by leaving the bus high
  73.         and transmits a 0 by pulling the bus low. When transmitting a 0, the DS18B20 will release the bus by the
  74.         end of the time slot, and the bus will be pulled back to its high idle state by the pullup resister. Output DS18B20
  75.         data from the DS18B20 is valid for 15μs after the falling edge that initiated the read time slot. Therefore,
  76.         the master must release the bus and then sample the bus state within 15μs from the start of the slot.
  77.         *********************************************************************************************************************/

  78.         for(i = 0; i < 8; i++)
  79.         {

  80.                  DQ_PIN = 0;

  81.                 //保持至少1us
  82.                 DelayUS(2);


  83.                 DQ_PIN = 1;        //释放总线

  84.                    DelayUS(5);        //在15us之内采集即可

  85.             //15u之内采集
  86.                 if(DQ_PIN)                                                                                                         
  87.                 {
  88.                         SET_BIT(Ret, i);

  89.                 }
  90.        
  91.           //读写时隙必须大于60us
  92.            DelayUS(30);
  93.            DelayUS(30);
  94.                   
  95.         }       

  96.         return Ret;

  97. }


  98. void ConvertTemperature()
  99. {
  100.         Init18B20();

  101.         SetSingleByte(COMMAND_SKIP_ROM);
  102.         SetSingleByte(COMMAND_CONVERT_TEMPERATURE);

  103. }

  104. WORD GetTemperature()
  105. {
  106.         BYTE loTemp = 0;
  107.         BYTE hiTemp = 0;

  108.         Init18B20();


  109.         SetSingleByte(COMMAND_SKIP_ROM);
  110.         SetSingleByte(COMMAND_READ_SCRATCHPAD);


  111.         loTemp = GetSingleByte();
  112.         hiTemp = GetSingleByte();


  113.         return MAKEWORD(loTemp, hiTemp);


  114.        
  115. }


复制代码


注意:其中的延迟函数需要根据自己的需要实现,我用的是stc的片子,指令周期和c51不一样。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表