智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 7784|回复: 12
打印 上一主题 下一主题

关于温度传感器ds18b20的采集

[复制链接]

0

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
369
威望
228
贡献
61
兑换币
20
注册时间
2009-6-25
在线时间
40 小时
跳转到指定楼层
1#
发表于 2009-8-17 21:51:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近做了个测温的模块,用的是DS18B20这款传感器(DG128编程),可是温度老是采集不回来,多次检查时序没有错,想请教下用过这个传感器的高手!以下是我编的程序:
#include <hidef.h>      /* common defines and macros */
#include <mc9s12dg128.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"
void MCU_Init(void);
void Delay(unsigned int k);//k=2~65535存在一定误差(比规定值偏大)
void Delay_1us(void);      //精确延时1us
void get_temp(void);
void ds18b20_Init(void);
void ds18b20_write(unsigned char command);
void ds18b20_read(void);
unsigned char tempdf,tempin;
void main(void) {
   
   MCU_Init();
  
   for(;;){
   get_temp();
   }
  
}
/*----------------------MCU初始化函数----------------------------*/
void MCU_Init(void){
   CLKSEL &= 0x7f;
   PLLCTL &= 0xbf;
   SYNR = 24;
   REFDV = 15;               //bus clock=25MHz
   PLLCTL |= (1<<6);
   while((CRGFLG&0x08)==0x00);
   CLKSEL |= (1<<7);
   INTCR &= 0xbf;
   COPCTL = 0x00;
}
/*-----------------------测温函数-------------------------------*/
void get_temp(void){
  DDRA_BIT7=1;    //A7为输出
  DDRA_BIT6=0;    //A6为输入
  ds18b20_Init();
  ds18b20_write(0xcc);
  ds18b20_write(0x44);
  Delay(500);
  ds18b20_Init();
  ds18b20_write(0xcc);
  ds18b20_write(0xbe);
  ds18b20_read();
}
/*-----------------------DS18B20初始化函数----------------------*/
void ds18b20_Init(void){
  while(1){
   unsigned char flag=0;
   PORTA_BIT7=0;
   Delay(500);
   PORTA_BIT7=1;
   Delay(60);
   while(PORTA_BIT6==0){
    Delay(250);
    if(PORTA_BIT6==1){
      DDRA_BIT5=1;
      PORTA_BIT5=0;
      flag=1;
      break;
    }
   }
   if(flag==1) {
    Delay(200);
    break;
   }
  }
}
/*-----------------------DS18B20写命令函数----------------------*/
void ds18b20_write(unsigned char command){
   unsigned char i;
   for(i=0;i<8;i++){
    PORTA_BIT7=0;
    Delay(12);
    if((command & 0x01)==1) {
      PORTA_BIT7=1;
    }
    else {
      PORTA_BIT7=0;
    }
    Delay(45);
    command=command>>1;
    PORTA_BIT7=1;
    Delay_1us();  
   }
}
/*-----------------------DS18B20读温度函数----------------------*/
void ds18b20_read(void){
  unsigned char i,j=2,k,temp,templ,temph;
  while(j--){
   for(i=0;i<8;i++){
     temp>>=1;
     PORTA_BIT7=0;
     Delay(2);
     PORTA_BIT7=1;
     Delay(5);
     if(PORTA_BIT6)
      temp |= 0x80;
     Delay(50);
   }
   if(j==1)
     templ=temp;
   else
     temph=temp;
  }
  if((temph & 0xf8)!=0){
    DDRA_BIT4=1;
    PORTA_BIT4=0;
    temph=~temph;
    templ=~templ;
    k=templ+1;
    templ=k;
    if(k>255){
      temph++;
    }
  }
  tempdf=templ & 0x0f;
  templ>>=4;
  temph<<=4;
  tempin=temph|templ;
}
  
/*----------------------普通延时函数----------------------------*/
void Delay(unsigned int k)
{
    unsigned int j;
   
   while(--k){
   for(j=0;j<=2;j++){
   }
   }
}
/*----------------------精确延时1us函数-------------------------*/
void Delay_1us(void)
{
   unsigned int j;
   j=1;
   while(--j){
   }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

0

主题

42

帖子

0

精华

高级会员

Rank: 4

积分
949
威望
495
贡献
268
兑换币
103
注册时间
2009-7-28
在线时间
93 小时
2#
发表于 2009-8-17 23:00:31 | 只看该作者
建议不要用这种DELAY函数,DG128这种延时不准,建议用示波器看看时序,通过示波器可以很明显的看出哪里出错.建议使用定时器模块.18b20对时序的要求很高.不知你PA7和PA6口是怎么接的,其实用一个口就可以了,没必要用两个口,它是单总线结构,所以两个口的话如果接的不好的话,会出现总线上的电平错误或者矛盾的
回复 支持 反对

使用道具 举报

0

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
369
威望
228
贡献
61
兑换币
20
注册时间
2009-6-25
在线时间
40 小时
3#
 楼主| 发表于 2009-8-17 23:07:19 | 只看该作者
建议不要用这种DELAY函数,DG128这种延时不准,建议用示波器看看时序,通过示波器可以很明显的看出哪里出错.建议使用定时器模块.18b20对时序的要求很高.不知你PA7和PA6口是怎么接的,其实用一个口就可以了,没必要用两个口 ...
ysjynkpgmw 发表于 2009-8-17 23:00

PA7是输出,PA6是输入的,原来也用一个口控制,但是也才不回温度,所以改成两个口控制!delay函数我用示波器侧过了,有点误差,但是不是很差很多!
回复 支持 反对

使用道具 举报

0

主题

42

帖子

0

精华

高级会员

Rank: 4

积分
949
威望
495
贡献
268
兑换币
103
注册时间
2009-7-28
在线时间
93 小时
4#
发表于 2009-8-17 23:22:02 | 只看该作者
用示波器看波型的整体的波型,也就是对照18B20的技术手册上给的波型图一点一点看,它的DELAY函数是非常非线性.18B20是低电平有效,所以置成0后,得置回1.如果你PA7和PA6直接联的话.你这段程序
  
   PORTA_BIT7=1;
     Delay(5);
     if(PORTA_BIT6)
      temp |= 0x80;
PA7的高电平会直接把PA6的输入拉成高.此时18B20是低的.就会出现错误了.
你可以先用示波器看看18B20有没有反回.如果有反回.再进行18B20的温度转化,它的温度转化也得按照它技术手册里的公式转.
建议按这样:
1:看发出的波型是不是符合技术手册,在示波器上是可以直接读0101的
2:然后往后看有没有反馈,先是第一个应答反馈,再是测温反馈
3:再就是算转化公式对不对
回复 支持 反对

使用道具 举报

0

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
369
威望
228
贡献
61
兑换币
20
注册时间
2009-6-25
在线时间
40 小时
5#
 楼主| 发表于 2009-8-18 00:35:49 | 只看该作者
用示波器看波型的整体的波型,也就是对照18B20的技术手册上给的波型图一点一点看,它的DELAY函数是非常非线性.18B20是低电平有效,所以置成0后,得置回1.如果你PA7和PA6直接联的话.你这段程序
  
   PORTA_BIT7=1;
   ...
ysjynkpgmw 发表于 2009-8-17 23:22

恩,这样啊,了解,明天去实验室看看,谢谢啦!
回复 支持 反对

使用道具 举报

14

主题

929

帖子

1

精华

功勋会员

WJ

Rank: 10Rank: 10Rank: 10

积分
6304

特殊贡献奖章

威望
1456
贡献
4674
兑换币
17
注册时间
2008-4-6
在线时间
87 小时
6#
发表于 2009-8-18 21:46:58 | 只看该作者
DS18B20是单线数据传输。
延时要求不高,
我以前用的DS18B20程序,是好用的。你参考看看。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

0

主题

17

帖子

0

精华

禁止发言

积分
-1029
QQ
威望
-1063
贡献
28
兑换币
6
注册时间
2008-3-23
在线时间
3 小时
7#
发表于 2009-8-19 00:18:11 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

17

帖子

0

精华

禁止发言

积分
-1029
QQ
威望
-1063
贡献
28
兑换币
6
注册时间
2008-3-23
在线时间
3 小时
8#
发表于 2009-8-19 13:16:25 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
369
威望
228
贡献
61
兑换币
20
注册时间
2009-6-25
在线时间
40 小时
9#
 楼主| 发表于 2009-8-19 18:11:11 | 只看该作者
DS18B20是单线数据传输。
延时要求不高,
我以前用的DS18B20程序,是好用的。你参考看看。
whut_wj 发表于 2009-8-18 21:46

感谢Wj分享啊,学习了!
回复 支持 反对

使用道具 举报

0

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
369
威望
228
贡献
61
兑换币
20
注册时间
2009-6-25
在线时间
40 小时
10#
 楼主| 发表于 2009-8-19 22:30:47 | 只看该作者
wj,我传感器回来的波形很奇怪啊!而且温度只有21一个值,不管放哪里都不变!
#include <hidef.h>      /* common defines and macros */
#include <mc9s12dg128.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"

#define DQ           PORTA_BIT7
#define DQ_DIR       DDRA_BIT7
#define DQ_HIGH()    DQ_DIR =0                   //设置数据口为输入
#define DQ_LOW()     DQ_DIR = 1;DQ = 0          //设置数据口为输出


void MCU_Init(void);
void Delay(unsigned int k);//k=2~65535存在一定误差(比规定值偏大)
void Delay_1us(void);      //精确延时1us
unsigned char get_temp(void);
void ds18b20_Init(void);
void ds18b20_write(unsigned char command);
unsigned char ds18b20_read(void);

unsigned char templ,temph,tempdf,a;
void main(void) {
   
   MCU_Init();
  
   for(;;){
   a=get_temp();
   Delay(20);
   }
  
}

/*----------------------MCU初始化函数----------------------------*/

void MCU_Init(void){
   CLKSEL &= 0x7f;
   PLLCTL &= 0xbf;
   SYNR = 24;
   REFDV = 15;               //bus clock=25MHz
   PLLCTL |= (1<<6);
   while((CRGFLG&0x08)==0x00);
   CLKSEL |= (1<<7);
   INTCR &= 0xbf;
   COPCTL = 0x00;
}

/*-----------------------测温函数-------------------------------*/

unsigned char get_temp(void){
  DQ_HIGH();
  ds18b20_Init();
  ds18b20_write(0xcc);
  ds18b20_write(0x44);
  Delay(500);
  ds18b20_Init();
  ds18b20_write(0xcc);
  ds18b20_write(0xbe);
  templ=ds18b20_read();
  temph=ds18b20_read();
  DQ_HIGH();
  tempdf=(templ>>4)|(temph<<4)&0x3f;
  Delay(5);
  return tempdf;
  
}

/*-----------------------DS18B20初始化函数----------------------*/

void ds18b20_Init(void){
  unsigned char flag=1;
  while(flag){
   DQ_LOW();
   Delay(500);
   DQ_HIGH();
   Delay(60);
   if(DQ==0){
    flag=0;
    DDRA_BIT6=1;
    PORTA_BIT6=0;
   }else{
    flag=1;
   }
   Delay(500);      
  }
}

/*-----------------------DS18B20写命令函数----------------------*/

void ds18b20_write(unsigned char command){
   unsigned char i;
   for(i=0;i<8;i++){
    DQ_LOW();
    Delay(12);
    if((command & 0x01)==1) {
      PORTA_BIT7=1;
    }
    else {
      PORTA_BIT7=0;
    }
    Delay(45);
    command=command>>1;
    DQ_HIGH();
    Delay_1us();  
   }
}

/*-----------------------DS18B20读温度函数----------------------*/

unsigned char ds18b20_read(void){
  //static byte j;
  unsigned char i,temp=0;
  for(i=0;i<8;i++){
     temp>>=1;
     DQ_LOW();
     Delay_1us();
     DQ_HIGH();
     Delay(2);
    // j=DQ;
     if(DQ)
      temp |= 0x80;
     Delay(60);
   }
   return(temp);
}

/*----------------------普通延时函数----------------------------*/

void Delay(unsigned int k)
{
    unsigned int j;
   
   while(--k){
   for(j=0;j<=2;j++){
   }
   }
}

/*----------------------精确延时1us函数-------------------------*/

void Delay_1us(void)
{
   unsigned int j;
   j=1;
   while(--j){
   }
}
回复 支持 反对

使用道具 举报

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

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-12-27 14:30 , Processed in 0.052971 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表