www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DS18b20 Reset geht nicht


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Ratemall (Gast)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,
ich brauch dringend eure Hilfe.
Ich versuche seit drei Tagen einen DS18B20 zum laufen zu bekommen und 
bleib schon beim Reset hängen. Na das kann ja noch witzig werden.

Mein Aufbau:

Atmega 32 Pin A0 an PIN 2 des DS... .
Pin A1 und A2 Oszi.
GND an Pin 1 des DS... .
5V an Pin 3 des DS... . Selbe Versorgung wie vom Atmega 32.
Zischen Pin 2 und 3 des DS... befindet sich ein 4,7 k parallel.
Atmega Takt: 4Mhz Qaurz.

Was pasiert:
Schalte ich die Spannungsversorgung ein liegt A0 auf GND und A2 auf 
High.
Trenne ich die Datenleitung des DS... und starte neu ist A2 auch high.
Auf der Datenleitung liegen dann 5V.
Ich hab es auch schon mit einem anderen Probiert. Das selbe Problem.
Was mach ich falsch?

Danke für eure Hilfe.

Gruß,
Jürgen

Autor: holger (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
#define Bus        PA0

if (Bus == 0)

PA0 ist immer Null. Bus damit auch.

Autor: Ratemall (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
holger schrieb:
> #define Bus        PA0
>
> if (Bus == 0)
>
> PA0 ist immer Null. Bus damit auch.

Versteh ich nicht. Was willst du mir damit sagen? Hängt das mit dem 
Fehler zusammen?

Autor: A. K. (prx)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ratemall schrieb:

> Versteh ich nicht. Was willst du mir damit sagen? Hängt das mit dem
> Fehler zusammen?

Könnte man so sagen. Das entspricht ungefähr
  main()
  {
     if (1)
       printf("Fehler!");
     else
       printf("OK!");
  }
mit der anschliessenden verblüfften Frage, weshalb das Programm immer 
nur Fehler! ausspuckt.

Autor: holger (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
>Versteh ich nicht. Was willst du mir damit sagen?

PA0 ist ein #define aus einer Header Datei.
Du kannst nicht PA0 (was immer 0 ist) abfragen sondern das
Bit 0 (=PA0) aus dem PINA Register. Das ist dein Fehler.

Autor: Ratemall (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Da ist ein Denkfehler von mir.
Ich muß die Variable reset abfragen:
    reset = (Eingang & 1<<Bus);

    _delay_us(480);
    BUSDDR_AUS();
    if (reset == 0)
    {  
        
      PORTA |= (1<<ERRJA);
    //  lcd_string("Reset fehler");
    }
    else
    {
      PORTA |= (1<<ERRNEIN);
    //  lcd_string("Reset okay");
    }

Funktioniert drotzem nicht.

Beitrag #2594211 wurde vom Autor gelöscht.
Autor: Ratemall (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Oha, jetzt wirds interessant.

Hab den Optimieren auf 00 gesetzt, funktioniert. Mit Datenleitung A1 
High und ohne A2 high.
Wie man im Code sieht wollte ich das ganze auf ein Display ausgeben. Das 
Display läuft aber nur bei 0S richtig.

Was tun?

Autor: Ratemall (Gast)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Okay, raus gefunden wo der Fehler ist. Der Fehler liegt bei der 
Display-Routine. Diese Fragt anscheinend das Busyflak nicht richtig ab. 
Im 0S funktioniert die Anzeige aber das Reset nicht. Im 00 funktioniert 
der Reset aber das Display zeigt nur Schrott. Es sieht so aus als würde 
das Display nicht nachkommen. Deshalb habe ich die Routine von so:
void lcd_string(char *s)
{
  char c;
  c=*s;
  while (c != '\0')
  {  
    RS_S;
    DISPLAY_PORT = c;
    DISPLAY_EN();
    DISPLAY_BUSY();
    *s++;
    c=*s;
  }
}

auf so:
void lcd_string(char *s)
{
  char c;
  c=*s;
  while (c != '\0')
  {  
    RS_S;
    DISPLAY_PORT = c;
    DISPLAY_EN();
    DISPLAY_BUSY();
    _delay_ms(10);
    *s++;
    c=*s;
  }
}

geändert.
Das macht das Display aber langsam.
Aber das ist woll ein anderes Problem. Muss ich ein neues Thread 
aufmachen oder kannst Du mir da auch schnell helfen?

Autor: cyblord ---- (cyblord)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Wieso machst du nicht eins nach dem anderen? Bekomm doch erstmal deine 
LCD Routine in den Griff und frag das Busy Flag korrekt ab. Dein Code 
sieht allgemein ziemlich komisch aus.

Wenn du einen String durchlaufen willst, dann musst du s++ schreiben und 
nicht *s++. Du willst ja die Adresse um 1 erhöhen und nicht den 
Buchstaben. Allerdings funktioniert es, wegen der Operatorreihenfolge. 
Trotzdem falsch und murks.

Grundsätzlich so:
void lcd_string(char *s) {
  
  while(*s) {
    tuwas(*s);
    s++;
  }
}

Und dann die unnötigen Zuweisungen zur Variable c.
Warum schreibst du manche Funktionen klein (richtig) und andere 
wiederrum komplett groß? Der Code ist allgemein grausam.

Autor: Karl Heinz Buchegger (kbuchegg) (Moderator)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Und fang als erstes damit an, die eine Funktion zu machen, die ein 
einzelnes Byte ausgibt. Das ist doch grausam, wenn du da jedesmal immer 
wieder den gleichen Ausgabecode in jeder einzelnen Funktion hast.

Eine Stringausgabe ist dann ganz simpel
void lcd_string(const char *s)
{
  while(*s)
    lcd_character(*s++);
}

Autor: Ratemall (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
cyblord ---- schrieb:
> Wieso machst du nicht eins nach dem anderen?

Weil die Routine eigentlich schon längst fertig war.

Das ist ja cool. Die Routine hab ich noch von der Ausbildung. Die hat 
ein Lehrer erstellt und ich habe sie nur an mein Board angepasst.

cyblord ---- schrieb:
> Warum schreibst du manche Funktionen klein (richtig) und andere
> wiederrum komplett groß?

Das hatte denn Hintergedanken das die kleingeschriebenen aus dem 
Hauptprogram aufgerufen werden und die großen nur intern in der Routine 
benötigt werden.

Das heist wenn ich das:
void lcd_string(char *s)
{
  char c;
  c=*s;
  while (c != '\0')
  {  
    RS_S;
    DISPLAY_PORT = c;
    DISPLAY_EN();
    DISPLAY_BUSY();
    *s++;
    c=*s;
  }
}

zu dem:

void lcd_string(char *s)
{
   while (*s != '\0')
  {
    RS_S;
    DISPLAY_PORT = *s;
    DISPLAY_EN();
    DISPLAY_BUSY();
    s++;
   }
}

änder, müßte es auch mit der Optimierung 00 funktionieren?

Werds heute abend mall ausprobieren.

Danke für eure Mühe.

Autor: Ratemall (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,

wollte nur schnell bescheidgeben das es so funktioniert:
void lcd_string(char *s)
{
   while (*s != '\0')
  {
    RS_S;
    DISPLAY_PORT = *s;
    DISPLAY_EN();
    DISPLAY_BUSY();
    s++;
   }
}

Aber das mit dem Busy-Flag klappt noch nicht.
Könnt ihr mir da auch noch helfen?
Wie muss ich denn Code ändern:
void DISPLAY_BUSY(void)
{
    uint8_t j;
    j=0;
    DDRC=0x00;
    while (!(j==0))
    {
      RS_L;
      RW_S;
      asm("nop");  
      EN_S;
      asm("nop");        

      if (!(PINC &(1<<PIN7)))
      {
        j=0;
      }
      else
      {
        j=1;
      }      
      EN_L;
      RW_L;
    }  
    DDRC=0xFF;
}

Autor: Ratemall (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Achso, ich benutze ein EA W204B-NLW. Ist denke noch wichtig zu wiesen.

Autor: Ratemall (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Guten abend.

Muss den Thread doch noch mal zum Leben erwecken.

Display funktioniert jetzt einwandfrei. Bastel schon seit Freitag wieder 
an dem Fühler rum und komme nicht weiter.

Dachte eigentlich der Reset funktioniert und habe am auslesen weiter 
gemacht. Da es nicht funktioniert, habe ich denn Reset nochmals 
untersucht und festgestellt das es mich vera.....t hat.

So sieht momentan der Code aus:
void reset (void)
  {
    uint8_t reset;
    BUSDDR_AUSGANG();
    BUS_LOW();
    _delay_us(480);
    BUSDDR_EINGANG();
    _delay_us(66);
    
    reset = (Eingang & 1<<Bus);

    _delay_us(480);
    BUSDDR_AUSGANG();
    if (reset == 1)
    {  
       lcd_string("Reset fehler");
    }
    else
    {
      lcd_string("Reset okay");
    }
  }

Ist die Datenleitung eingesteckt und ich schalte das Bord an, zeigt das 
Display: "Fehler". Ist die Datenleitung getrennt und ich schalte ein, 
zeigt das Display "okay" an. Die Routine funktioniert demnach. Weil, 
würde der Reset funktionieren würde der Sensor die Datenleitung auf null 
ziehen das ja dem trennen der Leitung entspricht.? Jetzt hab ich an der 
Leitung gemessen was für ein Pegel anliegt wenn die Leitung nicht 
angeschlossen ist. Siehe da, 5V. Ist das Richtig?

Autor: Ratemall (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,

keiner eine Idee?

Autor: Klaus (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Die Initialisieung sieht bei mie so aus.
Vllt. hilft dir das weiter.


// Initalisierung
int DS18S20_Init(void)
{
  uint8_t err=100;
  DS18S20_DDR |= 1 << DS18S20_wire;  // 1-wire Leitung auf LOW schalten
  _delay_us(480);            // mind. 480µs Low halten

  DS18S20_DDR &= ~(1<<DS18S20_wire);  // 1-wire Leitung auf HIGH 
schalten
    _delay_us(60);            // nach mind. 60µs wird der 
Precense-Impuls abgefragt

  err = (DS18S20_PIN & (1<<DS18S20_wire))  >> DS18S20_wire;  // err = 0 
Sensor ermittelt
  // Eine am Port D Pin 1 angeschlossene LED zeigt einen Fehler an wenn 
kein Sensor angeschlossen ist
  if (err == 1)
  {
    DS18S20_DDR |= ( 1 << LED_error);  // Kein Sensor vorhanden oder 
Leitungs Unterbrechung
  }
  else
  {
    DS18S20_DDR &= ~( 1 << LED_error);  // Mindestens ein Sensor 
ermittelt
  }
  _delay_us(480);
  return err;
}

Autor: Klaus (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Sorry deine Frage vergessen

>Die Routine funktioniert demnach. Weil,
>würde der Reset funktionieren würde der Sensor die Datenleitung auf null
>ziehen.

Die Aussage ist richtig wenn der Sensor angeschlossen ist.


> das ja dem trennen der Leitung entspricht.?

Diese Ausage ist falsch! Warum? Weil der Pull-UP den BUS im Ruhezustand 
auf High-Signal zieht.

Du hast doch hoffentlich einen Externen Pull-UP?


> Siehe da, 5V. Ist das Richtig?
  Ja wenn externer PULL-UP auf High gechaltet ist

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net