mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DS1820 Liefert nur 0xFF zurück


Autor: Makke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ein großes Problem mit der Temperaturmessung mit einem DS1820.
Habe das 1-wire Protokoll nach der Application Note 162 von Maxim
imlementiert und auch verstanden. Allerdings liefert der Sensor keine
vernünftigen Werte. Ich bin mir jetzt nicht schlüssig, ob der Fehler
beim Sensor liegt oder in meinem Zeitdelay:

void delay_us(unsigned int x){//x in µSekunden eingeben
   TCNT1=0x0000;
   TCCR1A=0b00000000;//Normal PORT Operation
                           //Normal Timer/Counter
   TCCR1B=0b00000001; //Normal Timer/Counter,CLK(1MHZ)
   while(x>=TCNT1){}  //Timer soll bis x laufen(ca. x µsekunden)
  }    //Timer-Funktion schließen

Als Prozessor benutze ich einen Atmega48 mit 1Mhz internem Oszillator.
Die Datenleitung ist an PB0 angeschlossen. Anschließend wird die
Temperatur auf einem LCD ausgegeben. Die Presence-Funktion erkennt den
Sensor(Geht von 1 auf 0 wenn der Sensor angeschlossen wird), allerdings
muss im Schreib oder Lesevorgang ein Fehler auftreten.

Kann mir jemand ungefähr sagen, was die gesamte delay_us Funktion in
echt an µSekunden braucht?Ich besitze leider kein Oszilloskop.
Vielleicht liegt das Problem darin, daß wenn ich delay_us(15) eingebe,
nicht 15µSekunden als Ergebnis rauskommen, sondern entsprechend mehr
was im Endeffekt zu dem Fehler führt.

Bin für jede Hilfe dankbar!

Autor: Makke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann denn wirklich keiner etwas dazu sagen? Keiner Idee oder sonst
irgendeinen Hinweis?

Autor: Elektrikser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde persönlich einen externen Quarz verwenden. Die delay_us ist
schon relativ genau, aber wie sieht es mit dem internen RC-Oszillator
aus? Der hat schon eine ziemliche Ungenauigkeit, deshalb kann man ihn
ja abeichen.

Gruß Elektrikser

Autor: Makke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Laut Datenblatt wird der ATmega48 mit einem Kalibrierregister auf 8MHz
genau getaktet und dann durch 8 geteilt. Aber vielleicht hast du recht
und nicht mal auf das kann man sich verlassen. Ist der 1-wire Bus denn
so Zeitempfinglich?

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der interne Takt des mega48 ist einfach miserabelst stabil.
Irgendwo in de Codesammlung gibt es schon fertige Routinen für den
DS1820 von peter danegger.

Autor: Paul Baumann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Elektrikser!
Ich verstehe zwar nichts von C, habe aber mit Bascom mit dem DS
gearbeitet. Du kannst den Sensor selbst abfragen, wann er mit dem
Umwandeln fertig ist. Dann brauchst Du keine Zeit zu programmieren;
er gibt ja selbst die Meldung zurück. Das steht im Datenblatt von
Dallas/Maxim und geht auch so.
MfG Paul
bis er fertig ist

Autor: Makke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sieht es denn mit dem internen RC-Oszillator vom Mega8 aus? Ist der
auch so miserabel? Den hätte ich nämlich hier noch auf Lager und ließe
sich schnell tauschen!

Autor: Elektrikser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Paul,

das ist vollkommen richtig. Hat aber meines Wissens einen Nachteil:
Wenn man mit delays arbeitet ist aber die Buszeit kürzer. Das
Setzen/Rücksetzen von einen Bit in einem I/O-Register benötigt bei den
delays z.B. einen Zyklus, aber 14 Zyklen beim variablen Bus (wenn man
auf die Meldung vom Sensor immer wartet).

Gruß Elektrikser

Autor: Paul Baumann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Elektrikser!
Alles klar, da habe ich wieder was Neues erfahren. Naja, wie gesagt
ich habe stur den Ablauf, wie er im Datenblatt stand in ein Programm
eingesetzt, die Berechnungsformel "zersägt" (Bascom kann nicht mehr
als 2Terme auf einmal bearbeiten) und es mißt. Ich erzeuge einen
Interrupt mit 1 Sekunde Abstand und in der Interruptroutine drin
sitzt die Abfrage des Fühlers.
MfG Paul

Autor: Alex10178 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Das gleiche Problem hatte ich auch mit einem DS1822 und dem M16c62
Mikrocontroller!

Das Problem liegt einen einen Zeitschlitzen!! die müssen genau so lang
sein wie es im Datenblatt steht!

Ich habe das Problem mit einem Logikanalyser gefunden! die Zeiten waren
viel zu lang!!

Autor: Makke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich komme einfach nicht mehr weiter. Mittlerweile kann ich die 1-wire
Funktionen auswendig. Vielleicht hat jemand Lust sich meine Routinen
anzuschauen, ob er noch einen Fehler entdeckt. Ich kann keinen mehr
finden, außer dass es an den Zeitroutinen liegen könnte oder der Sensor
kaputt ist. Danke für eure Hilfe!

Hier der Code:

void DQhigh(void){
   DDRB=0x00;       //PORTB ist Eingang
   PORTB=0x00;     //High-Z
   }
void DQlow(void){
   DDRB=0xFF;              //PORTB ist Ausgang
   PORTB=0x00;
   }

void delay_us(unsigned int x){ //Zeitverzögerung in µSekunden
   TCNT1=0x0000;         //Zähler auf 0 setzen
   TCCR1A=0b00000000;    //Normal PORT Operation,
                               //NormalTimer/Counter
   TCCR1B=0b00000001;    //Normal Timer/Counter,CLK(1MHZ)
   while(x>=TCNT1){}  //Timer soll bis x laufen(ca. x usekunden)
  }         //Timer-Funktion schließen

unsigned char ow_reset(void){
  unsigned char presence,temp;
  DQlow();         //pull DQ line low
  delay_us(480);       //leave it low for 480µs
  DQhigh();       //allow line to return high
  delay_us(70);       // wait for presence
  temp=PINB&0x01;
  presence=(PINB&0x01);      //get presence signal
  delay_us(400);       //wait for end of timeslot
  return(presence);     //presence signal returned
}           // 0=presence OK ; 1= no part False

unsigned char read_bit(void){
  unsigned char i,temp;
  DQlow();       //pull DQ low to start timeslot
  DQhigh();    //then return high
  delay_us(15);    //delay 15µs from start of timeslot
  temp=PINB&0x01;    //DQ einlesen
  delay_us(100);
  return(temp);    //return value of DQ line
  }
unsigned char read_byte(void){
  unsigned char i;
  unsigned char value=0;

  for(i=0;i<8;i++){
    if(read_bit())value|=0x01<<i;     //reads byte in,one bit at a time
and then shifts left
    delay_us(120);    //wait for rest of timeslot
    }
    return(value);
  }

void write_bit(char bitval){
   DQlow();    //pull DQ low to start timeslot
   if(bitval==1)DQhigh();  //return DQ high if write 1
   delay_us(100);
   DQhigh();
   }

void write_byte(char val){
   unsigned char i;
   unsigned char temp;

   for(i=0;i<8;i++){
     temp=val>>i;
    temp&=0x01;
    write_bit(temp);
    }
   delay_us(100);
   }

unsigned char read_temp(void){
  {
  unsigned char get[10],i;
  unsigned char temp_lsb,temp_msb;
  int k;
  unsigned char temp_f,temp_c;
  ow_reset();
  write_byte(0xCC); //Skip ROM
  write_byte(0x44); // Start Conversion
  for(i=0;i<20;i++){
  delay_us(64000);} //Warten bis Wandlung fertig

  ow_reset();
  write_byte(0xCC); // Skip ROM
  write_byte(0xBE); // Read Scratch Pad
  for (k=0;k<9;k++){get[k]=read_byte();}
  temp_msb = get[1]; // Sign byte + lsbit
  temp_lsb = get[0]; // Temp data plus lsb

        return temp_lsb;
        }
}

Autor: Alex10178 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

das sollte dir helfen!

http://www.m16c.de/PDF/AppNotes/APP_EXTMEM/reu05b0...

Viel Spaß damit!
damit läuft es bei mir!

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Teste mal die delay()-Routine. Geht auch ohne Oszi.

Beispielsweise ein 10µs-Delay 100000mal hintereinander, und dann, also
offiziell jede Sekunde, eine LED umschalten.

Ich glaube kaum, dass es auch nur annähernd 0,5Hz werden. Weil die
Routine auch bei delay_us(0) schon um die 10µs mehr verbrutzelt als
vorgesehen.

Autor: Makke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Test war erfolgreich. Hab ein Delay von 100µSekunden eingestellt und das
10000 mal in einer Schleife durchlaufen lassen. Kam auf jeden Fall was
unter einem Hertz raus. Hat denn jemand eine Idee wie ich dann einen so
kurzen delay von etwa 15µSekunden mit einem Takt von 1MHz realisieren
kann? Wenn ich eine For-Schleife benutze bin ich doch bestimmt auch bei
for(i=0;i<0;i++){} auch schon wieder über 15µSekunden,oder nicht?
Danke schon mal für eure Tips.So weiß ich immerhin schon mal, dass das
Problem am Delay liegt und nicht an den Funktionen selber.

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
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
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 bestätigst du, die Nutzungsbedingungen anzuerkennen.