DS18B20温度测量(2)实际制做

这个扩展,电路很简单,板子就不用做了吧!把电路焊好就行了。 

这个是原理图: 
DS18B20温度测量(2)实际制做 - 少占鱼-网易 - 少占鱼
实际接线图如下: 
DS18B20温度测量(2)实际制做 - 少占鱼-网易 - 少占鱼 
接好的实物图如下: 

DS18B20温度测量(2)实际制做 - 少占鱼-网易 - 少占鱼 


接下来就是写程序了,我们还是一步步地来完成: 
① 向总线发出复位信号: 
sbit TMDAT=P1^1;   //设P1.1为TMDAT 

  void tmreset(void) 

uint i; 
TMDAT=0;     //将总线拉低 
i=103; 
while(i>0) i--;    //延时700微秒 
TMDAT=1;      //释放总线 
i=4; 
while(i>0) i--;    //延时40微秒 

② 检测总线上是否有器件应答(是否有存在信号): 
void tmpre(void) 

uint i; 
while(TMDAT);     //检测低电平的存在。否则一直循环。 
while(~TMDAT); //检测高电平的存在。否则一直循环。 
i=4; 
while(i>0) i--;     //延时 

这段程序就是检测一个先低后高的脉冲的存在。说明有器件应答了。 
③ 从DS18B20上读一个bit 
bit tmrbit(void) 

uint i; 
bit dat; 
TMDAT=0;   //先将总线拉低 
i++;              //延时一微秒 
TMDAT=1;   //释放总线 
i++; 
i++;            //延时两微秒 
dat=TMDAT;    //读取总线 
i=8; 
while(i>0) i--;     //延时 
return(dat); 


④ 向总线写一个bit 
void tmwbit(bit testb) 

if(testb)                    //如果是1 
       { TMDAT=0;     //先拉低总线 
         i++; i++;            //延时2微秒 
         TMDAT=1;     //释放总线 
         i=8; 
         while(i>0) i--;   //延时40微秒 
       } 
     else                     //如果是0 
       { TMDAT=0;     //先拉低总线 
         i=8; 
         while(i>0) i--;   //延时40微秒 
         TMDAT=1;      //释放总线 
         i++; i++;          //延时2微秒 
       } 

我这么写大家能看懂吧! 
与单片机连接图: 
DS18B20温度测量(2)实际制做 - 少占鱼-网易 - 少占鱼 



好!现在上完整的程序:(要慢慢的读了) //LCD12864 
//********************************************************** 
//连线表: CPU=89C51    SysClock=12MHz                     * 
//RS=P2.0   R/W=P2.1    E=P2.2    CS1=P2.3    CS2=P2.4     * 
//DB0-DB7=P3.0-P3.7       /Reset=InBoard                   * 
//********************************************************** 
//DS18B20 //********************************************************** 
//连线表: CPU=89C51    SysClock=12MHz                     * 
//单总线: TMDAT=P1.1 
//                 
//********************************************************** 
#include <reg52.h> 
#include <stdlib.h> 
#include <intrins.h> 
#include <stdio.h> 
#include <math.h> 
#define uchar unsigned char 
#define uint unsigned int 
/********************LCD引脚定义********************/ 
#define DataPort P3     //LCD128*64 I/O 信号管脚 
sbit    RS =P2^0;      //数据指令 
sbit    RW =P2^1;      //读写 
sbit    E   =P2^2;      //使能 
sbit    CSL =P2^3;      //左片选 
sbit    CSR =P2^4;      //右片选 
uchar Page;             //页 地址 
uchar Col;              //列 地址 
uchar co de ASC_5x7[];   //5×7阵点字模 
uchar str[4];           //char的值转换成字符串 
/********************DS18B20引脚定义********************/ 
sbit TMDAT=P1^1; 
/********************DS18B20函数定义*******************/ 
void dmsec(uint count);//延时(count)毫秒 
void tmreset(void);    //产生复位信号 
void tmpre(void);      //检测器件应答信号 
bit tmrbit(void);      //从总线读一个bit 
uchar tmrbyte(void);   //从总线读一个字节 
void mwbyte(uchar dat);//向总线写一个字节 
void tmstart(void);    //启动一次温度转换 
uchar tmrtemp(void);   //读取温度数据 
/********************LCD函数定义*******************/ 
void BusyL(void);          //左屏检测忙 
void BusyR(void);          //右屏检测忙 
void CheckBusy(void);      //读取忙信号 
void Delay(uint MS);       //延时 
void Locatexy(void);       //将屏幕横向0-12纵向0-7转换成左、右屏的的X、Y 
void WriteCommandL( uchar CommandByte );    //向左屏写入指令 
void WriteCommandR( uchar CommandByte );    //向右屏写入指令 
uchar ReadData( void );       //读数据 
void WriteData( uchar DataByte );    //写数据 
void LcmClear( void );       //清屏 
void LcmInit( void );        //初始化 
uchar * uchartostr(unsigned char unm);            //将值转成字符串 
void LcmPutAsc( uchar asc );     //显示一个5×7的ASC字符 
void LcmPutstr( uchar row,uchar y,uchar * str );       //在设定位置显示字符串 

/*****************DS18B20函数体定义****************/ 
void dmsec(uint count) 

uint i; 
while(count--) 
   { for(i=0;i<125;i++){} 
   } 

void tmreset(void) 

uint i; 
TMDAT=0; 
i=103; 
while(i>0) i--; 
TMDAT=1; 
i=4; 
while(i>0) i--; 

void tmpre(void) 

uint i; 
while(TMDAT); 
while(~TMDAT); 
i=4; 
while(i>0) i--; 

bit tmrbit(void) 

uint i; 
bit dat; 
TMDAT=0; 
i++; 
TMDAT=1; 
i++; 
i++; 
dat=TMDAT; 
i=8; 
while(i>0) i--; 
return(dat); 

uchar tmrbyte(void) 

uchar i,j,dat; 
dat=0; 
for(i=1;i<=8;i++) 
{ j=tmrbit(); 
    dat=(j<<7)|(dat>>1); 

return(dat); 

void tmwbyte(uchar dat) 

uint i; 
uchar j; 
bit testb; 
for(j=1;j<=8;j++) 
   { testb=dat & 0x01; 
     dat=dat>>1; 
     if(testb) 
       { TMDAT=0; 
         i++; i++; 
         TMDAT=1; 
         i=8; 
         while(i>0) i--; 
       } 
     else 
       { TMDAT=0; 
         i=8; 
         while(i>0) i--; 
         TMDAT=1; 
         i++; i++; 
       } 
   } 

void tmstart(void) 

tmreset(); 
tmpre(); 
dmsec(1); 
tmwbyte(0xcc); 
tmwbyte(0x44); 

uchar tmrtemp(void) 

uchar a,b,y1,y2,y3; 
tmreset(); 
tmpre(); 
dmsec(1); 
tmwbyte(0xcc); 
tmwbyte(0xbe); 
a=tmrbyte(); 
b=tmrbyte(); 
y1=a>>4; 
y2=b<<4; 
y3=y1|y2; 
return(y3); 



/************LCD12864函数体***************/ 
/***************************/ 
/*检查Busy                 */ 
/***************************/ 
void BusyL(void) 

        CSL= 1; 
        CSR= 0; 
        CheckBusy(); 

void BusyR(void) 

        CSL= 0; 
        CSR= 1; 
        CheckBusy(); 

void CheckBusy(void) 

        RS = 0;         //指令 
        RW = 1; 
DataPort= 0xFF;      //输出0xff以便读取正确 
        E = 1; 
        _nop_(); 
        while(0);//DataPort & 0x80);       //Status Read Bit7 = BUSY 
        E = 0; 
        _nop_(); 

/********************************************************/ 
/*根据设定的坐标数据,定位LCM上的下一个操作单元位置     */ 
/********************************************************/ 
void Locatexy(void) 

        uchar x,y; 
        switch (Col&0xc0)       /* col.and.0xC0        */ 
        {                       /*条件分支执行          */ 
                case 0:         {BusyL();break;}/*左区 */ 
                case 0x40:      {BusyR();break;}/*右区 */ 
        } 
        x = Col&0x3F|0x40;      /* col.and.0x3f.or.Set Y Address*/ 
        y = Page&0x07|0xB8;     /* row.and.0x07.or.set Page     */ 
        CheckBusy();                /* waitting for enable */ 
        RS = 0;                 //指令 
        RW = 0;                 //写 
        DataPort = y;                 //设置页面地址 
        E = 1; 
        _nop_(); 
        E = 0; 
        _nop_(); 
        CheckBusy();                /* waitting for enable */ 
        RS = 0; 
        RW = 0; 
        DataPort = x;                 //设置列地址 
        E = 1; 
        _nop_(); 
        E = 0; 
        _nop_(); 

/***************************/ 
/*写指令                   */ 
/***************************/ 
void WriteCommandL( uchar CommandByte ) 

        BusyL(); 
        DataPort = CommandByte; 
        RS = 0;         //指令 
        RW = 0; 
        E = 1; 
        _nop_(); 
        E = 0; 
        _nop_(); 

void WriteCommandR( uchar CommandByte ) 

        BusyR(); 
        DataPort = CommandByte; 
        RS = 0;         //指令 
        RW = 0; 
        E = 1; 
        _nop_(); 
        E = 0; 
        _nop_(); 

/***************************/ 
/*读数据                   */ 
/***************************/ 
uchar ReadData( void ) 

        uchar DataByte; 
        Locatexy();     /*坐标定位,返回时保留分区状态不变      */ 
        RS = 1;         /*数据输出*/ 
        RW = 1;         /*读入 */ 
        DataPort = 0xFF;              //输出0xff以便读取正确 
        E = 1;         /*读入到LCM*/ 
        _nop_(); 
        DataByte = DataPort; /*数据读出到数据口P1 */ 
        E = 0; 
        _nop_(); 
        return DataByte; 

/***************************/ 
/*写数据                   */ 
/***************************/ 
void WriteData( uchar DataByte ) 

        Locatexy();     /*坐标定位,返回时保留分区状态不变      */ 
        RS = 1;         /*数据输出*/ 
        RW = 0;         /*写输出 */ 
        DataPort = DataByte; /*数据输出到数据口 */ 
        E = 1;         /*写入到LCM*/ 
        _nop_(); 
        E = 0; 
        _nop_(); 

void LcmClear( void ) 

        Page = 0; 
        Col = 0; 
        for(Page=0;Page<8;Page++) 
                for(Col=0;Col<128;Col++) 
                        WriteData(0); 

void LcmInit( void ) 

    Delay(200);     //等待复位 
        WriteCommandL(0x3f);    //开显示 
        WriteCommandR(0x3f); 
         
        WriteCommandL(0xc0);    //设置起始地址=0 
        WriteCommandR(0xc0); 
        WriteCommandL(0x3f);    //开显示 
        WriteCommandR(0x3f); 
        LcmClear(); 
        Col = 0; 
        Page= 0; 
        Locatexy(); 


uchar * uchartostr(uchar unm) 

uchar x00,xx,x0,x,n; 
x00=unm/100; 
xx=unm%100; 
x0=xx/10; 
x=xx%10; 
n=0; 
if(x00!=0) 
{ str[n]=x00+48; //值加48即为字符 
    n++; 

if(!(x00==0&x0==0)) 
{ str[n]=x0+48; 
    n++; 

str[n]=x+48; 
n++; 
str[n]='\0'; 
   return str; 

void LcmPutAsc( uchar asc ) 

        uchar j; 
        uint x; 
        x = 5*(asc-32); 
            for(j=0;j<5;j++) 
                { 
                        WriteData(ASC_5x7[x]); 
                        x++; 
                        Col++; 
                } 
            WriteData(0x00); 
            Col++; 

void LcmPutstr( uchar row,uchar y,uchar * str ) 
{ unsigned char * x; 
   x=str; 
Page=row; 
Col=y; 
while(*x!='\0') 
{ LcmPutAsc( *x ); 
    x++; 


void Delay(uint MS) 

        uchar us,usn; 
        while(MS!=0) 
        { 
                usn = 2;        //for 12M 
                while(usn!=0) 
                { 
                        us=0xf6; 
                        while (us!=0){us--;}; 
                        usn--; 
                } 
                MS--; 
        } 


void Main( void ) 

        uchar last; 
        LcmInit(); 
        LcmClear(); 
    dmsec(1); 
    tmstart(); 
      dmsec(1000); 
      last=tmrtemp(); 
      LcmPutstr( 4,76,uchartostr(last) ); 
    LcmPutstr( 2,42,"DS18B20" ); 
    LcmPutstr( 4,2,"Temperature" ); 
    LcmPutstr( 4,92,"'C" ); 
        LcmPutstr( 7,42,"[email=TXZ001@139.com]TXZ001@139.com[/email]" ); 
        while(1) 
        { 
      dmsec(1); 
    tmstart(); 
    dmsec(1000); 
    last=tmrtemp(); 
    LcmPutstr( 4,76,uchartostr(last) ); 
         //Delay(1000); 
       
        } 


unsigned char co de ASC_5x7[]={ 
0x00, 0x00, 0x00, 0x00, 0x00, // 
0x00, 0x00, 0x4F, 0x00, 0x00, // 
0x00, 0x07, 0x00, 0x07, 0x00, // 
0x14, 0x7F, 0x14, 0x7F, 0x14, // 
0x24, 0x2A, 0x7F, 0x2A, 0x12, // 
0x23, 0x13, 0x08, 0x64, 0x62, // 
0x36, 0x49, 0x55, 0x22, 0x50, // 
0x00, 0x05, 0x03, 0x00, 0x00, // 
0x00, 0x1C, 0x22, 0x41, 0x00, // 
0x00, 0x41, 0x22, 0x1C, 0x00, // 
0x14, 0x08, 0x3E, 0x08, 0x14, // 
0x08, 0x08, 0x3E, 0x08, 0x08, // 
0x00, 0x50, 0x30, 0x00, 0x00, // 
0x08, 0x08, 0x08, 0x08, 0x00, // 
0x00, 0x60, 0x60, 0x00, 0x00, // 
0x20, 0x10, 0x08, 0x04, 0x02, // 
0x3E, 0x51, 0x49, 0x45, 0x3E, // 
0x00, 0x42, 0x7F, 0x40, 0x00, // 
0x42, 0x61, 0x51, 0x49, 0x46, // 
0x21, 0x41, 0x45, 0x4B, 0x31, // 
0x18, 0x14, 0x12, 0x7F, 0x10, // 
0x27, 0x45, 0x45, 0x45, 0x39, // 
0x3C, 0x4A, 0x49, 0x49, 0x30, // 
0x01, 0x01, 0x79, 0x05, 0x03, // 
0x36, 0x49, 0x49, 0x49, 0x36, // 
0x06, 0x49, 0x49, 0x29, 0x1E, // 
0x00, 0x36, 0x36, 0x00, 0x00, // 
0x00, 0x56, 0x36, 0x00, 0x00, // 
0x08, 0x14, 0x22, 0x41, 0x00, // 
0x14, 0x14, 0x14, 0x14, 0x14, // 
0x00, 0x41, 0x22, 0x14, 0x08, // 
0x02, 0x01, 0x51, 0x09, 0x06, // 
0x32, 0x49, 0x79, 0x41, 0x3E, // 
0x7E, 0x11, 0x11, 0x11, 0x7E, // 
0x41, 0x7F, 0x49, 0x49, 0x36, // 
0x3E, 0x41, 0x41, 0x41, 0x22, // 
0x41, 0x7F, 0x41, 0x41, 0x3E, // 
0x7F, 0x49, 0x49, 0x49, 0x49, // 
0x7F, 0x09, 0x09, 0x09, 0x01, // 
0x3E, 0x41, 0x41, 0x49, 0x7A, // 
0x7F, 0x08, 0x08, 0x08, 0x7F, // 
0x00, 0x41, 0x7F, 0x41, 0x00, // 
0x20, 0x40, 0x41, 0x3F, 0x01, // 
0x7F, 0x08, 0x14, 0x22, 0x41, // 
0x7F, 0x40, 0x40, 0x40, 0x40, // 
0x7F, 0x02, 0x0C, 0x02, 0x7F, // 
0x7F, 0x06, 0x08, 0x30, 0x7F, // 
0x3E, 0x41, 0x41, 0x41, 0x3E, // 
0x7F, 0x09, 0x09, 0x09, 0x06, // 
0x3E, 0x41, 0x51, 0x21, 0x5E, // 
0x7F, 0x09, 0x19, 0x29, 0x46, // 
0x26, 0x49, 0x49, 0x49, 0x32, // 
0x01, 0x01, 0x7F, 0x01, 0x01, // 
0x3F, 0x40, 0x40, 0x40, 0x3F, // 
0x1F, 0x20, 0x40, 0x20, 0x1F, // 
0x7F, 0x20, 0x18, 0x20, 0x7F, // 
0x63, 0x14, 0x08, 0x14, 0x63, // 
0x07, 0x08, 0x70, 0x08, 0x07, // 
0x61, 0x51, 0x49, 0x45, 0x43, // 
0x00, 0x7F, 0x41, 0x41, 0x00, // 
0x02, 0x04, 0x08, 0x10, 0x20, // 
0x00, 0x41, 0x41, 0x7F, 0x00, // 
0x04, 0x02, 0x01, 0x02, 0x04, // 
0x40, 0x40, 0x00, 0x40, 0x40, // 
0x01, 0x02, 0x04, 0x00, 0x00, // 
0x20, 0x54, 0x54, 0x54, 0x78, // 
0x7F, 0x48, 0x44, 0x44, 0x38, // 
0x38, 0x44, 0x44, 0x44, 0x28, // 
0x38, 0x44, 0x44, 0x48, 0x7F, // 
0x38, 0x54, 0x54, 0x54, 0x18, // 
0x00, 0x08, 0x7E, 0x09, 0x02, // 
0x0C, 0x52, 0x52, 0x4C, 0x3E, // 
0x7F, 0x08, 0x04, 0x04, 0x78, // 
0x00, 0x44, 0x7D, 0x40, 0x00, // 
0x20, 0x40, 0x44, 0x3D, 0x00, // 
0x00, 0x7F, 0x10, 0x28, 0x44, // 
0x00, 0x41, 0x7F, 0x40, 0x00, // 
0x7C, 0x04, 0x78, 0x04, 0x78, // 
0x7C, 0x08, 0x04, 0x04, 0x78, // 
0x38, 0x44, 0x44, 0x44, 0x38, // 
0x7E, 0x0C, 0x12, 0x12, 0x0C, // 
0x0C, 0x12, 0x12, 0x0C, 0x7E, // 
0x7C, 0x08, 0x04, 0x04, 0x08, // 
0x58, 0x54, 0x54, 0x54, 0x64, // 
0x04, 0x3F, 0x44, 0x40, 0x20, // 
0x3C, 0x40, 0x40, 0x3C, 0x40, // 
0x1C, 0x20, 0x40, 0x20, 0x1C, // 
0x3C, 0x40, 0x30, 0x40, 0x3C, // 
0x44, 0x28, 0x10, 0x28, 0x44, // 
0x1C, 0xA0, 0xA0, 0x90, 0x7C, // 
0x44, 0x64, 0x54, 0x4C, 0x44, // 
0x00, 0x08, 0x36, 0x41, 0x00, // 
0x00, 0x00, 0x77, 0x00, 0x00, // 
0x00, 0x41, 0x36, 0x08, 0x00, // 
0x02, 0x01, 0x02, 0x04, 0x02, // 
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 
}; 
实际运行后的效果图如下: 
DS18B20温度测量(2)实际制做 - 少占鱼-网易 - 少占鱼
实际操作中发现时序并没有像所说的那么严格,我试着将12MHz的晶振跳到11.0592MHz时,也一样正常运行。 

晶振在12MHz位置,如下图 
DS18B20温度测量(2)实际制做 - 少占鱼-网易 - 少占鱼 

晶振跳至11.0592MHz 如下图: 
DS18B20温度测量(2)实际制做 - 少占鱼-网易 - 少占鱼 
上张大图看看清楚吧! 

DS18B20温度测量(2)实际制做 - 少占鱼-网易 - 少占鱼 (点击上图可看最大尺寸)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值