打印

请教DS18B20

[复制链接]
3220|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kingshen23|  楼主 | 2009-12-3 15:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
高手们帮帮忙。我对单个18B20操作的指令顺序是怎么样的·自己编的指令顺序是:1初始化,2跳过ROM(写0xcc),3存储器操作命令(写温度变换0x44),4再初始化,5再跳过ROM(写0xcc),6存储器操作命令(写存储器0xbe)。对其初始化后,18B20返回了个存在信号。
#include"intrins.h"
#include"ABSACC.H"
#include"reg51.h"
#define uchar unsigned char
#define uint  unsigned int
sbit TM=P1^1;
/*延时*/
void delyms(unsigned int n)
{unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<164;j++);
}
void NOP(uchar n)
{uchar i;
for(i=0;i<n;i++)
{
_nop_();
}
}
uchar start(void)
{uchar r;
TM=0;
NOP(60);
TM=1;
NOP(2);
r=TM;
return(r);
}
void w_byte(uchar byte)
{uchar i;
for(i=0;i<8;i++)
{
TM=1;
_nop_();
_nop_();
TM=0;
if(byte&0x01){TM=1;}
NOP(6);
byte=byte>>1;
}
TM=0;
}
uint r_byte(void)
{uchar byte=0,i;
for(i=0;i<16;i++)
{
TM=1;
_nop_();
_nop_();
TM=0;
_nop_();
_nop_();
_nop_();
_nop_();
TM=1;
if(TM==1){byte=byte|0x80;}
byte=byte>>1;
NOP(6);
}
return(byte);
TM=0;
}

void main(void)
{uint temp1;
restart:if(start()){goto restart;}
w_byte(0xcc);
w_byte(0x44);
delyms(500);
if(start()){goto restart;}
w_byte(0xcc);
w_byte(0xbe);
temp1=r_byte();
}
沙发
headwolf_83| | 2009-12-3 16:15 | 只看该作者
网络上有不少现成的,拿一个抄着改吧。

使用特权

评论回复
板凳
andy2003hu| | 2009-12-3 16:22 | 只看该作者
我给你一个,给我分

使用特权

评论回复
地板
不亦心| | 2009-12-3 21:03 | 只看该作者
怎么跑PIC来了

使用特权

评论回复
5
backupyan| | 2009-12-21 19:16 | 只看该作者
本帖最后由 backupyan 于 2009-12-21 19:25 编辑

请严格注意时序。例如延时60us,15us等延时。因为DS18B20与单片机之间不是同步的。参考程序压缩包(MPLAB+Proteus+PICC PIC18B20.rar (135.57 KB)
参考程序如下:
//*********************************************************
// 实现的功能:数码管显示实时温度,支持负温度
// 芯片PIC16F877
// XT:4MHZ
//*********************************************************
#include <pic.h>       //包含单片机内部资源预定义
#define LVP 0x3f39
// 晶振:XT;代码:没有代码保护;上电延时定时器关闭;
// 低电压复位禁止;看门狗关闭 ;低电压编程禁止
__CONFIG (XT & UNPROTECT & PWRTDIS & BORDIS & WDTDIS & LVP);
#define  uch  unsigned char                     //给unsigned char起别名 uch
#define DQ RA2                                //定义18B20数据端口
#define DQ_DIR TRISA2                         //定义18B20D口方向寄存器
#define DQ_HIGH() DQ_DIR =1                   //设置数据口为输入
#define DQ_LOW() DQ_DIR = 0;DQ = 0            //设置数据口为输出
void init_port(void)
{
  RBPU=0;
//  PORTB=0xFF;
  TRISB=0xFF;
  PORTD=0x00;           //
  TRISC=0x00;           //C口控制LED指示灯,设置成输出
  TRISD=0;            //D口当作数码管段,设置成输出
  ADCON1=0x07;         //使A口,E口全为数字I/O口
  TRISE=0x00;    //E口当作数码管位选择控制脚,设置成输出   
  PORTE=0x00;
}
//*********************************************************
//  延时程序
//*********************************************************
void delay(char x,char y)
{
  char z;
  do{
      z=y;
      do{;}while(--z);
     }while(--x);
}
//复位DS18B20函数
void reset(void)
{
  uch presence=1;
  while(presence)
  {
    DQ_LOW() ;                                //主机拉至低电平
    delay(2,90);                              //延时>480503us
    DQ_HIGH();                                //释放总线等电阻拉高总线,并保持15~60us
    delay(2,8);                               //延时>60us
    if(DQ==1) presence=1;                     //没有接收到应答信号,继续复位
    else presence=0;                          //接收到应答信号
    delay(2,70);                              //延时>240us
   }
  }
//-----------------------------------------------
//写18b20写字节函数
void write_byte(uch val)
{
uch i;
uch temp;
for(i=8;i>0;i--)
{
   temp=val&0x01;                            //最低位移出
   DQ_LOW();
   NOP();
   NOP();
   NOP();
   NOP();
   NOP();                                    //从高拉至低电平,产生写时间隙
   if(temp==1)  DQ_HIGH();                   //如果写1,拉高电平
   delay(2,7);                               //延时63us
   DQ_HIGH();
   NOP();
   NOP();
   val=val>>1;                               //右移一位
  }
}
void get_temp()
{
int i;
DQ_HIGH();
reset();                                 //复位等待从机应答
write_byte(0XCC);                        //忽略ROM匹配
write_byte(0X44);                        //发送温度转化命令  
for(i=10;i>0;i--)
    {   
        delay(201,132);                       
    }   
reset();                                 //再次复位,等待从机应答
write_byte(0XCC);                        //忽略ROM匹配
write_byte(0XBE);                        //发送读温度命令
TLV=read_byte();                  //读出温度低8位
THV=read_byte();                  //读出温度高8位
DQ_HIGH();                               //释放总线
                                          
TZ=(TLV>>4)|(THV<<4);           //温度整数部分
TX=TLV<<4;                      //温度小数部分,注意TX的后四位无效码
binary_temp(TX, TZ );   //将相应的温度二进制值转换成十进制数
}

使用特权

评论回复
6
paulful| | 2013-6-23 09:21 | 只看该作者
backupyan 发表于 2009-12-21 19:16
请严格注意时序。例如延时60us,15us等延时。因为DS18B20与单片机之间不是同步的。参考程序压缩包(MPLAB+P ...

你这个DQ_HIGH() DQ_DIR =1  设置数据口为输入  怎么又变成拉高电平了呀

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

29

帖子

0

粉丝