单片机/MCUwilliam hill官网
直播中

a12355x

12年用户 3经验值
私信 关注

AVR的DS18B20温度程序

参照网上的资料和DATESHEET写了一个DS18B20的程序,单片机为ATMEL128,晶振为8M,但是温度一直显示为255,从早上开始找原因,没有找到。现在把源代码发上来,各位能帮我分析一下原因吗?(程序未完整,只是发了温度部分,显示部分就不发了,调试是成功了)

#include
#include
#include til/delay.h>
#include
#include

#define  FREQ  8         //芯片工作频率
#define uchar unsigned char
#define uint  unsigned int

/*******************温度设定********************/

#define DQ_H PORTA|= (1< #define DQ_L PORTA&= ~(1< #define DQ_R PINA        //读取总线数据
#define DQ_IN DDRA&=~(1< #define DQ_OUT DDRA|=(1<
static uchar *table[10]={"0","1","2","3","4","5","6","7","8","9",};

/******延时函数********/

void delay_nms(uint n)        
   {
      uint i=0 ;
      for (i=0 ;i       _delay_loop_2(250*FREQ) ;
   }

/********************************************************/
/*                                                      */
/* y*us延时函数                                         */
/*                                                      */
/********************************************************/   
void  delay(uint y)
  {
    _delay_loop_2(2*y);
  }


/***************************DS18B20复位程序**************************/
void reset(void)
{
        uchar flag;
        flag=1;

        while(flag)

        {
                DQ_L;
                delay(600);        //拉低总线600us,发送复位命令
                DQ_H;
                DQ_IN;
                delay(60);        //等待回应
        
                if(PINA&_BV(PA3))
                                delay(350);        //延时后继续复位        
                else
                        flag=0;                        //跳出复位        
        }                        
        delay(350);//初始化完成,恢复高电平
        DQ_OUT;
        delay(2);

}

/**********************向DS18B20发送数据(从低位到高位)*******************/
void send_date1(uchar date)
{
        uchar temp,i;

        for(i=8;i>0;i--)
        {
                temp=(date&0x01);        //检测date第一位是否为1
                DQ_L;
                delay(15);//产生发送时序
                if(temp)        
                        DQ_H;               
                else               
                        DQ_L;        //发送数据
                        
                delay(60);        //等待DS18B20采样
                DQ_H;
                delay(2);        //结束发送,进入下一个字节发送
                date=(date>>1);

        }
                                
}


/********************从DS18B20读数据(高位到低位)***********/

uchar read_date1(void)
{
        uchar date,i;
        date=0x00;
        for(i=8;i>0;i--)
        {        
                DQ_L;
                delay(1);        //产生读时序
                date=(date>>1);               
                DQ_H;                //发送读取命令
                DQ_IN;
                delay(3);//释放总线
                if((DQ_R&=(1<                 date=(date|0x80);        //如果总线数据为1,那么高位置1
                delay(60);                //一个读周期
                DQ_H;        //恢复总线        
                DQ_OUT;
                delay(1);
        }

        return(date);
}

/**********************************温度函数**********************/

unsigned int readtemp(void)
{
        uchar TVL,TVH;
        unsigned int tempvalue,temp;
        tempvalue=0;
        temp=0;

        reset();
        send_date1(0xCC);        //忽略RAM匹配
        send_date1(0x44);        //发送温度查询命令


        reset();                //复位
        send_date1(0xCC);
        send_date1(0xBE);        //读取暂存器上的温度数据        
        
        TVL=read_date1();        //温度低8位
        TVH=read_date1();        //温度高8位
//        TVL=0x55;
//        TVH=0x02;
        temp=TVH;
        temp=(temp<<8);
        tempvalue=(temp|TVL);
        tempvalue=(tempvalue*0.0625);
        

        return tempvalue;

}

已退回1积分

回帖(3)

longxi0514

2015-2-5 11:53:51
#define DQ_data PORTC.7
#define DQ_bus(x) DDRC.7 = x
void DS18B20_Init()
{
    uint i = 0;
    DQ_bus(1);
    DQ_data = 1;
    DQ_data = 0;
    delay_us(640);
    DQ_data =1;
   
    DQ_bus(0);
//    delay_us(60);
    while(PINC.7)
    {
        delay_us(60);
        i++;
        if(i >= 10000)
        {
            flag = 1;
            break;
        }      
    }
    delay_us(480);
   
    DQ_bus(1);
    DQ_data = 1;
   
}

void DS18b20_Write(uchar dat)
{
    uchar m;
    DQ_bus(1);
    for(m = 0;m < 8; m++)
    {
        DQ_data = 0;
        delay_us(15);      
        if(dat &(1 << m))
        {

            DQ_data = 1;
            delay_us(15);
            delay_us(15);
            delay_us(15);     
        }
        else
        {
            DQ_data = 0;
            delay_us(15);
            delay_us(15);
            delay_us(15);
            delay_us(15);
      
        }
        DQ_data = 1;        
    }
    DQ_bus(1);
    DQ_data = 1;
}


uchar DS18b20_Read()
{
    uchar n,temp,k;
    temp = 0;
   
   // IO_In;
    for(n = 0;n < 8;n++)
    {
        DQ_bus(1);   
        DQ_data = 1;
        delay_us(2);
        DQ_data = 0;
        delay_us(6);
        DQ_data = 1;
        delay_us(4);
        DQ_bus(0);
        k = (PINC & (1 << 7));
        if(k)
        {
            temp |= (1 << n);
        }
        else
        {
            temp &= ~(1 << n);
        }
        delay_us(30);

    //    DQ_bus(1);     
    }
    return (temp);
}


void Gettemp()
{
    uint w;

  //  uchar i;

    DS18B20_Init();
    DS18b20_Write(0xcc);
    DS18b20_Write(0x44);
    delay_ms(100);
    DS18B20_Init();
    DS18b20_Write(0xcc);
    DS18b20_Write(0xbe);
    templ = DS18b20_Read();
    temph = DS18b20_Read();
   
//    uint w;
//   uchar i;
//    Gettemp();
    w = temph;
    w = w << 8;
    w = w | templ;
    if(w < 0x0fff)
        sign1 = 1;
    else
        {
            w = ~w + 1;
            sign1 = 0;
        }
    w = w * (0.625) - 40;

    e[0] = w / 1000 + 0x30;
    e[1] = w % 1000 / 100 + 0x30;
    e[2] = w % 100 / 10 + 0x30;
    e[3] = w % 10 +0x30;

}
举报

longxi0514

2015-2-5 11:54:13
这个程序我测试过了,你自己对一下吧
举报

唐凌

2015-5-3 14:55:49
谢谢分享                              
举报

更多回帖

发帖
×
20
完善资料,
赚取积分