DS18b20 Reset geht nicht

Gast #2594115
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
Angehängte Dateien:
Gast #2594186
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.
Gast #2594197
Lesenswert?

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

3
    _delay_us(480);
4
    BUSDDR_AUS();
5
    if (reset == 0)
6
    {  
7
        
8
      PORTA |= (1<<ERRJA);
9
    //  lcd_string("Reset fehler");
10
    }
11
    else
12
    {
13
      PORTA |= (1<<ERRNEIN);
14
    //  lcd_string("Reset okay");
15
    }

Funktioniert drotzem nicht.
Gast #2594234
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?
Gast #2594271
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:
1
void lcd_string(char *s)
2
{
3
  char c;
4
  c=*s;
5
  while (c != '\0')
6
  {  
7
    RS_S;
8
    DISPLAY_PORT = c;
9
    DISPLAY_EN();
10
    DISPLAY_BUSY();
11
    *s++;
12
    c=*s;
13
  }
14
}

auf so:
1
void lcd_string(char *s)
2
{
3
  char c;
4
  c=*s;
5
  while (c != '\0')
6
  {  
7
    RS_S;
8
    DISPLAY_PORT = c;
9
    DISPLAY_EN();
10
    DISPLAY_BUSY();
11
    _delay_ms(10);
12
    *s++;
13
    c=*s;
14
  }
15
}

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?
Angehängte Dateien:
#2594407
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:
1
void lcd_string(char *s) {
2
  
3
  while(*s) {
4
    tuwas(*s);
5
    s++;
6
  }
7
}

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.
#2594421
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
1
void lcd_string(const char *s)
2
{
3
  while(*s)
4
    lcd_character(*s++);
5
}
Gast #2594997
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:
1
void lcd_string(char *s)
2
{
3
  char c;
4
  c=*s;
5
  while (c != '\0')
6
  {  
7
    RS_S;
8
    DISPLAY_PORT = c;
9
    DISPLAY_EN();
10
    DISPLAY_BUSY();
11
    *s++;
12
    c=*s;
13
  }
14
}

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.
Gast #2597046
Lesenswert?

Hallo,

wollte nur schnell bescheidgeben das es so funktioniert:
1
void lcd_string(char *s)
2
{
3
   while (*s != '\0')
4
  {
5
    RS_S;
6
    DISPLAY_PORT = *s;
7
    DISPLAY_EN();
8
    DISPLAY_BUSY();
9
    s++;
10
   }
11
}

Aber das mit dem Busy-Flag klappt noch nicht.
Könnt ihr mir da auch noch helfen?
Wie muss ich denn Code ändern:
1
void DISPLAY_BUSY(void)
2
{
3
    uint8_t j;
4
    j=0;
5
    DDRC=0x00;
6
    while (!(j==0))
7
    {
8
      RS_L;
9
      RW_S;
10
      asm("nop");  
11
      EN_S;
12
      asm("nop");        
13

14
      if (!(PINC &(1<<PIN7)))
15
      {
16
        j=0;
17
      }
18
      else
19
      {
20
        j=1;
21
      }      
22
      EN_L;
23
      RW_L;
24
    }  
25
    DDRC=0xFF;
26
}
Gast #2601189
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:
1
void reset (void)
2
  {
3
    uint8_t reset;
4
    BUSDDR_AUSGANG();
5
    BUS_LOW();
6
    _delay_us(480);
7
    BUSDDR_EINGANG();
8
    _delay_us(66);
9
    
10
    reset = (Eingang & 1<<Bus);
11

12
    _delay_us(480);
13
    BUSDDR_AUSGANG();
14
    if (reset == 1)
15
    {  
16
       lcd_string("Reset fehler");
17
    }
18
    else
19
    {
20
      lcd_string("Reset okay");
21
    }
22
  }

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?
Gast #2602389
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;
}
Gast #2602418
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

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