Board logo

标题: DS18B20测温程序,大侠帮忙看看 [打印本页]

作者: flexraybeginer    时间: 2010-8-12 21:51     标题: DS18B20测温程序,大侠帮忙看看

程序一直调不出来,调的过程中结果不是全是F,就是全是0,哪位好心帮我看看吧~先谢过了!

#include <hidef.h>      /* common defines and macros */
#include <mc9s12xf512.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xf512"
#include "Fr_UNIFIED_types.h"
uint16 TempeValue,TempeValdone;
boolean  TempeReady = 0;
uint32 timech;

#define DQ 1
#define DQ_H PTP_PTP0 = 0 //设置P0.0口为输出
#define DQ_L PTP_PTP0 = 1 //设置P0.0口为输入
uint8 flag=0;
uint8 Temp=0;
uint8 tempH;
uint8 tempL;
uint8 f;
uint8 tmp;
uint8 tmp_t,COUNTER = 0;

void Delay(uint32 time) //3.75us
{
  for(;time>0;time--);
   
}

//初始化作为输入口
void GPIO_Iint()
{
DDRP_DDRP0 = 0;   
}
//初始化作为输出口
void GPIO_Oint()
{
DDRP_DDRP0 = 1;        
}
// 函数功能:一线总线复位及从设备应答控制程序
void TxReset(void)
{   
   
    do{
    int err = 5;
    flag = 0;  
    GPIO_Oint();
    DQ_H;
    Delay(2);              //延时5us
    DQ_L;              //置低,初始化开始
    Delay(480);            //延时722us     
   
    GPIO_Iint();
    Delay(45);             //延时60us以上
            
                       /*等待18B20发出存在脉冲--低电平*/              
    while((PTP_PTP0 == 1)||(err == 0)) {
      err--;   
      Delay(12);
    }
     
    if(err == 0) flag = 0;
    else flag = 1;
      Delay(39); //60us
      GPIO_Oint();
      DQ_H;
      Delay(79); //120us,总480us
      Delay(79);
      Delay(79);
      Delay(79);
      
    } while(flag == 0) ;
   
}

void WrByte(uint8 b)
{
    uint8 i;
    for(i=0;i<8;i++)
    {
       if(b&0x01)
       {
         GPIO_Oint();
                             /*先置高再置低,告诉18B20 写开始*/
         DQ_H;                   //置高
         Delay(2);               //5us
         DQ_L;                   //置低
         Delay(5);               //延时20us
   
         DQ_H;                  //P0.0置高,写 1 开始
         Delay(39);               //延时10us
   
         GPIO_Iint();
         Delay(5);               //保证写2位数据的间隙大于 1 us  

       }
       else
       {
         GPIO_Oint();
                        
         DQ_H;             //置高
         Delay(2);                //5us
         DQ_L;                   //置低                        
         Delay(45);               //延时70us
         DQ_H;
         GPIO_Iint();
         Delay(5);               //保证写2位数据的间隙大于 1 us  
       }
       b=b>>1;
    }
}
//读数据的一位,满足读时隙要求读取
uint8 RdBit(void)
{
    uint8 read_bit;
   
    GPIO_Oint();        /*先置高再置低,告诉18B20 读开始*/
   
    DQ_L;           
    Delay(2);              //延时5us
   
    GPIO_Iint();
    Delay(5);     //10us
    if(PTP_PTP0)
      read_bit=0x80;
    else
      read_bit=0;
   
    GPIO_Oint();           //输出
    DQ_H;                  //置高,释放总线
    Delay(40);
   
    return read_bit;
}
//读取数据的一个字节
uint8 RdByte(void)
{
    uint8 i,Data=0;
    for(i=0;i<8;i++)
    {
       Data=Data>>1;
       Data=Data|RdBit();
    }
    return Data;
}
//启动一次DS18B20测温,并读取测温结果//得到完整的温度值(整数和小数)
uint8 get_temp_t(void)
{   
     uint8 i,j;
     TxReset();
     COUNTER++;
     if(flag)       //如果一线总线复位及从设备应答控制 成功 则向下执行
    {
        WrByte(0xCC);    //跳过ROM
        COUNTER++;
        WrByte(0x44);    //开始一次温度变换
        COUNTER++;
        Delay(480);       //700us
        COUNTER++;
        TxReset(); //一线总线复位及从设备应答控制
        COUNTER++;
        WrByte(0xCC);     //跳过ROM
        COUNTER++;
        WrByte(0xBE);    //读暂存存储器
        COUNTER++;
        tempL=RdByte();
        COUNTER++;
        tempH=RdByte();
        COUNTER++;
    }      
        
      
                  COUNTER = 0;
            return(f);
}
void temperaturehandler(void) {
   
    TempeReady = 1;
    get_temp_t();
  TempeValue = (uint16)tempH;
  TempeValue = TempeValue << 8;
  TempeValue = TempeValue + (uint16)tempL;
  TempeValdone = TempeValue;
  TempeReady = 0;

}

void main(void) {
  /* put your own code here */
  //EnableInterrupts;
    PLLCTL_PLLON = 0;       /* Disable the PLL */
    SYNR_SYNDIV = 0x04;        /* Set PLL synthesizer register to 4 */
    REFDV_REFDIV = 0x00;     /* Set PLL divider register to 0 */
   
    /* Fvco = 2*OSCCLK*(SYNR+1)/(REFDV+1) = 8MHz* 5/1 = 40MHz   */
    /*                                    -> VCOFRQ = 00b        */        
    SYNR_VCOFRQ1 = 0;
    SYNR_VCOFRQ0 = 0;
        
    /* Fref = OSCCLK/(REFDV+1) = 4MHz/1 = 4MHz -> REFRQ= 01b     */   
    REFDV_REFFRQ1 = 0;
    REFDV_REFFRQ0 = 1;
   
    PLLCTL_PLLON = 1;   /* PLL enabled */
   
        while(!CRGFLG_LOCK)
            ;       /* Wait until the PLL is within the desired frequency */
               
    CLKSEL_PLLSEL = 1;    /* Select clock source from PLL */
              
              GPIO_Oint();
   for(;;) {  
            
      temperaturehandler();   
              
  } /* wait forever */
  /* please make sure that you never leave this function */
}
作者: hxcic    时间: 2010-8-13 09:44

沙发。 顶一个
作者: chiusir    时间: 2010-8-20 13:00

这个对时序要求相当严格,所以参照芯片数据手册,准确把握时序即可,总线频率改变,时序需要重新调整。
作者: flexraybeginer    时间: 2010-8-20 15:01

我又重新按照数据手册来过了,还是不行。读上来的数据一直是0
作者: flexraybeginer    时间: 2010-8-20 15:16

DS18B20加上上拉电阻后就不能正常RESET,也就是说不能收到DS18B20发出的脉冲
作者: bluehacker    时间: 2010-8-23 22:21

这种错误大多数是时序不对,延时庶非常精确,建议用示波器 检查
另外 就是看板子焊接有没有焊错
作者: flexraybeginer    时间: 2010-8-24 09:59

板子的引脚我已经用固定延时的方式检验过,引脚没有拆错
传感器没有焊在板子上,是用杜邦线直接连的
作者: flexraybeginer    时间: 2010-8-25 09:39

#include <hidef.h> /* common defines and macros */
#include <mc9s12xf512.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xf512"
#include "Fr_UNIFIED_types.h"

uint16 TempeValue,TempeValdone;
boolean TempeReady = 0;
uint32 timech;

#define Skip_ROM 0xCC
#define Write 0x4E
#define DQ 1
#define DQ_H PTP_PTP0 = 0 //设置P0.0口为输出
#define DQ_L PTP_PTP0 = 1 //设置P0.0口为输入
uint8 flag=0;
uint8 Temp=0;
uint8 tempH;
uint8 tempL;
uint8 f;
uint8 tmp = 0;
uint8 tmp_t,COUNTER = 0;


void Delay(unsigned int time)
{
PITCFLMT = 0x00; //关闭计时器
PITCE = 0x01; //使能通道1
PITMUX = 0x00; //使用宏时钟0
PITMTLD0 = 19; //宏时钟为1us
PITLD0 = time-1; //timeus
PITTF = 0x01; // 清时钟标志位
PITCFLMT = 0x80; //使能计时器
while(!(PITTF&0x01));
PITTF = 0x01;
PITCFLMT = 0x00;
}
void DelayMS(unsigned int time) //100ms
{
PITCFLMT = 0x00; //关闭计时器
PITCE = 0x01; //使能通道1
PITMUX = 0x00; //使用宏时钟0
PITMTLD0 = 199; //宏时钟为10us
PITLD0 = time*10000-1; //timeus
PITTF = 0x01; // 清时钟标志位
PITCFLMT = 0x80; //使能计时器
while(!(PITTF&0x01));
PITTF = 0x01;
PITCFLMT = 0x00;
}


//初始化作为输入口
void GPIO_Iint()
{

DDRP_DDRP0 = 0; //端口pp0设为输入,并拉高
PERP_PERP0 = 1;
PPSP_PPSP0 = 0;
}

//初始化作为输出口
void GPIO_Oint()
{
   
DDRP_DDRP0 = 1;  
}



// 函数功能:一线总线复位及从设备应答控制程序
void TxReset(void)
{

do{
int err = 10;
flag = 0;
GPIO_Oint();
DQ_H;
Delay(10);
DQ_L; //置低,初始化开始
  Delay(500); //延时500us  

GPIO_Iint();
//Delay(60);
/*等待18B20发出存在脉冲--低电平*/
while((PTIP_PTIP0 == 1)&&(err != 0)) {
err--;
Delay(20);
}
COUNTER++;
if(err == 0) flag = 0;
else flag = 1;

//GPIO_Oint();
//DQ_H;
Delay(480);

} while(flag == 0) ;

}


现在改用定时器做了一下,还是不能初始化,收不到低电平脉冲
作者: flexraybeginer    时间: 2010-8-25 16:50

#define DQ_H PTP_PTP0 = 0 //设置P0.0口为输出
#define DQ_L PTP_PTP0 = 1 //设置P0.0口为输入
原来是这里拉高,拉低写反了




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0