DS1820 alle paar sekunden eine Anfrage

OP #496906
Lesenswert?

Moin,

ich habe eine Frage zum Temperatursensor ds1820.
Und zwar habe ich Code von Peter Dannegger verwendet,
allerdings evrändert, da ich die Daten nicht über UART ausgeben möchte.

Meine Anfrage sieht folgendermaßen aus:

    lcd_gotoxy(0,0);
    snprintf(lcd_buffer,16,"TEMP : %d", test);
    lcd_puts(lcd_buffer);
    start_meas();
    _delay_ms(500);
    temp = read_meas();
    lcd_gotoxy(0,1);
    if(temp !=0 ){
      snprintf(lcd_buffer,16,"%4d.%01dC",temp>>4,(temp << 12)/6553);
      lcd_puts(lcd_buffer);
    }

die abgeänderten Funktionen von Peter Dannegger,
welche die Kommunikation mit dem Sensor regeln


bit w1_reset(void){
  bit err=0;

  W1_OUT &= ~(1<<W1_PIN);
  W1_DDR |= 1<<W1_PIN;
  _delay_us(480);
  cli();
  W1_DDR &= ~(1<<W1_PIN);
  _delay_us(66);
  err = W1_IN & (1<<W1_PIN);      // no presence detect
  sei();
  _delay_us(414);
  if( (W1_IN & (1<<W1_PIN)) == 0 )    // short circuit
    err = 1;
  return err;
}


uchar w1_bit_io( bit b )
{
  cli();
  W1_DDR |= 1<<W1_PIN;
  _delay_us(1);
  if( b )
    W1_DDR &= ~(1<<W1_PIN);
  _delay_us(14);
  if( (W1_IN & (1<<W1_PIN)) == 0 )
    b = 0;
  _delay_us(45);
  W1_DDR &= ~(1<<W1_PIN);
  sei();
  return b;
}


uint w1_byte_wr( uchar b ){
  uchar i = 8, j;
  do{
    j = w1_bit_io( b & 1 );
    b >>= 1;
    if( j )
      b |= 0x80;
  }while( --i );
  return b;
}


uint w1_byte_rd( void ){
  return w1_byte_wr( 0xFF );
}


uchar w1_rom_search( uchar diff, uchar idata *id ){
  uchar i, j, next_diff;
  bit b;

  if( w1_reset() )
    return PRESENCE_ERR;      // error, no device found
  w1_byte_wr( SEARCH_ROM );      // ROM search command
  next_diff = LAST_DEVICE;      // unchanged on last device
  i = 8 * 8;          // 8 bytes
  do{
    j = 8;          // 8 bits
    do{
      b = w1_bit_io( 1 );      // read bit
      if( w1_bit_io( 1 ) ){      // read complement bit
  if( b )          // 11
    return DATA_ERR;      // data error
      }else{
  if( !b ){        // 00 = 2 devices
    if( diff > i ||
      ((*id & 1) && diff != i) ){
      b = 1;        // now 1
      next_diff = i;      // next pass 0
    }
  }
      }
      w1_bit_io( b );           // write bit
      *id >>= 1;
      if( b )          // store bit
  *id |= 0x80;
      i--;
    }while( --j );
    id++;          // next byte
  }while( i );
  return next_diff;        // to continue search
}


void w1_command( uchar command, uchar idata *id ){
  uchar i;
  w1_reset();
  if( id ){
    w1_byte_wr( MATCH_ROM );      // to a single device
    i = 8;
    do{
      w1_byte_wr( *id );
      id++;
    }while( --i );
  }else{
    w1_byte_wr( SKIP_ROM );      // to all devices
  }
  w1_byte_wr( command );
}

void start_meas( void ){

  if( W1_IN & 1<< W1_PIN ){
    w1_command( CONVERT_T, NULL );
    W1_OUT |= 1<< W1_PIN;
    W1_DDR |= 1<< W1_PIN;      // parasite power on

  }else{
    //uputsnl( "Short Circuit !" );
  }
}


uint read_meas( void ){

  uchar id[8], diff;
  uchar i;
  uint temp=0;

  diff = w1_rom_search( SEARCH_FIRST, id );

  if( diff == PRESENCE_ERR ){
    //temp=1;
    temp = 0;
  } else if( diff == DATA_ERR ){
    //temp = 2;
    temp = 0;
  } else if( id[0] == 0x28 || id[0] == 0x10 ){  // temperature sensor
    w1_byte_wr( READ );      // read command
    temp = w1_byte_rd();      // low byte
    temp |= (uint)w1_byte_rd() << 8;    // high byte
    if( id[0] == 0x10 )      // 9 -> 12 bit
      temp <<= 3;
  }
  return temp;
}

Allerdings "findet" er nur dann und wann die Temperatur,
meine Frage ist einerseits warum findet er die Temperatur nur manchmal.
Weiter würde ich gerne wissen, wie man "festlegen" kann, welcher Sensor 
von den mehreren am Bus angeschlossenen, man verwenden möchte.

Danke
Matthias

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren