Da hier im Forum doch größere Probleme bei der Verwendung der Maxim Temperatursensoren auftreten, anbei nun meine 8051-Routine auf einem ATTINY12 in Assembler implementiert. Eine ausführliche Beschreibung werde ich später dazustellen. Die Sensoren werden über Parasite-Power versorgt, d.h. es reicht eine 2-Draht-Leitung aus. Dazu wird der 1-Wire-Portpin während der Wandlung als Ausgang geschaltet. Da die DS18B20 bis zu 750ms benötigen, wird für eine Wandlung 1s gewartet. Während dieser Zeit können die Sensoren nicht ausgelesen werden. Mittels einer Taste kann zwischen den Sensoren umgeschaltet werden. Die Temperatur wird beim DS18B20 in 0,1°C-Schritten angezeigt. Als Pull-Up habe ich 2,2kOhm verwendet. Das ganze habe ich mit 7 Sensoren an 20m Klingeldraht getestet. Peter
Hallo Peter, wie steuerst du einzelne ds1820 im bus über das eeprom an? du meintest mal, man sollte jedem eine nummer geben und dann diese ansprechen. hast du da eine routine für? Gruss Bastian
Code für den AVR habe ich nicht. Wie man einen Wert speichert, steht im Datenblatt. Und beim Auslesen der Temperatur liest man diesen Wert eben mit aus und vergleicht ihn, ob es die gewünschte Messtelle ist. Mann kann ihn aber auch als Index nehmen, an welcher Adresse in einer Tabelle die Temperatur zu speichern ist. D.h. man speichert alle Werte ab und hat sie dann in der Tabelle nach der Nummer die im EEPROM steht sortiert vorliegen. Peter
Achso, ich dachte man könnte direkt die Adresse zum ansprechen des Sensors im EEPROM speichern. Wenn man mehrere Sensoren am Bus hat muss man ja jeden einzeln zum abfragen adressieren
"Wenn man mehrere Sensoren am Bus hat muss man ja jeden einzeln zum abfragen adressieren" Eben nicht ! Mit dem ROM-Search wird einer nach dem anderen adressiert und kann ausgelesen werden. Aber wer der erste und wer der letzte ist, ist von den Adressen abhängig. Es ergibt sich also eine zufällige Reihenfolge, deshalb der Trick mit der Indexadresse im EEPROM. Ein Beispiel: Der Sensor für die 5.Messtelle wird beim ROM-Search z.B. als 3. gefunden. Aber die Nummer 5 im EEPROM bewirkt, daß dessen Temperaturwert in der Meßwerttabelle an 5. Stelle abgespeichert wird. Nun ist er kaputt und durch einen anderen ersetzt worden, dem ebenfalls die 5 in den EEPROM geschrieben wurde. Der neue wird jetzt aber z.B. als 6. gefunden. Aber die Nummer 5 im EEPROM bewirkt wieder, daß er in der Meßwerttabelle an 5. Stelle abgespeichert wird. Peter
Ich fürchte das ist im Moment noch zu komplex für mich. Das krieg ich noch nich hin. Muss mich erstmal genauer mitm AVR und Assembler vertraut machen. Mal sehen wann ich soweit bin mal 1Wire Routinen richtig zum laufen zu bringen..
Hallo Peter, ich habe folgendes Programm ich habe ein Bus mit 5 Ds1820 diese lese ich der Reihe nach mit ROM-search aus. funkt. auch recht gut ... jetzt kann es aber in meinem Einsatz passieren, daß mal ein Sensor kaputt geht oder die Strippe zum Sensor abreißt. Nun überspringt einfach ROM-Search den def. Sensor und macht mit dem nächsten weiter ... und da ich die Werte in ein EEProm speichere kommt da so einiges durcheinander. Ich will das so machen wenn der eine nicht mehr ansprechbar ist das soll z.B. der ausgelesen Wert auf 0 gehen etc. jetzt habe ich das mit der Adressierung über das EEProm gelesen ... bin aber im Datenblatt nicht ganz schlau geworden ! kannst Du das mal bitte ganz grob erläutern wie man das eeprom beschreibt und wie die Adressierung dann aussieht ? ich mach das jetzt wie folgt : (halb Basic ...) '**************************************************** reg_nr(1-8) = ROMsearch Match ROM Convert Match ROM Read RAM Empf1 = Scratch(1) '**************************************************** man könnte zwar die Adressen der einzelnen Ds1820 vorher im Programm speichern jedoch würde das viel RAM verbrauchen ... Gruß Tobias
@Tobias, ich habs ja oben schon versucht zu erklären: Wenn Du nach Auslesen der Temperatur noch die 2 nächsten Bytes liest, sind das die beiden EEPROM-Bytes, die du frei verwenden kannst, z.B. als Meßstellennummer. Und diese EEPROM-Bytes must Du eben irgendwann einmal entsprechend beschrieben haben. Wie man das macht geht am besten aus dem Flußdiagramm im Datenblatt hervor. Peter
gut die zwei Byte zu beschreiben sollte kein Problem sein ... jedoch wie jetzt Adressieren ? mit ROM-Search und dann abfragen ob z.B. das z.B. Sendor 3 ist oder so ? oder kann man den dirket adressieren über diese 2 Bytes ? aber ich denke mal nicht ... Aber die Antwort hat schon weitergeholfen Danke ! Gruß Tobias
"jedoch wie jetzt Adressieren ? mit ROM-Search und dann abfragen ob z.B. das z.B. Sendor 3 ist oder so ?" Ganz genau ! Um nur einen bestimmten Sensor auszulesen must Du dann solange ROM-Searchen, bis der richtige gefunden ist. Peter
Peter ich Danke Dir... - hat mir sehr geholfen ! also noch einen schönen Abend !
Hi, habe es mit 8051 Assembler hingekriegt, eine DS2401 Seriennummer oder einen DS1821 Temperatursensor auszulesen. Brauche jetzt mal eine 8051-Assembler Routine "ROM-Search" die mir alle Seriennummern anzeigt die auf dem Bus sind. Flussdiagramm dazu habe ich aber ist mir doch ein wenig zu mühselig dass alles umzusetzen.. Mit besten Grüssen
@Peter-Christian Anbei die 1-Wire Funktionen in 8051 Assembler. Der Aufruf erfolgt genauso wie im C-Programm. Peter
Hallo alle, ich bin auf der Suche nach einem DS1820, der in einem Wandgehäuse montiert ist und mit Schraubklemmen o.ä. an ein Kabel angeschlossen werden kann. Habt Ihr eine Ahnung, wo es sowas fertig zu kaufen gibt? Liebe Grüße Tobias
Hallo Peter, führe mir gerade deinen Code für den Attiny12 zu Gemüte. Ich habe es zwar geschafft einen einzelnen DS1820 mit einem Atmega8L auszulesen und als Thermometer zu verwenden, aber jetzt will ich mehrere an einem Bus hängen. Ich programmiere in AVR-GCC. Ich habe aber das ROM-Search noch nicht ganz begriffen. Du hast in deinem ersten Post geschrieben: "Eine ausführliche Beschreibung werde ich später dazustellen." Das würde mir vielleicht ein ganz schönes Stück weiterhelfen, oder eine bessere Kommentierung :-) Der Ablauf, wie ich ihn verstehe: -Reset -Such-Kommando senden: 0xF0 -Erstes Bit lesen -Zweites Bit lesen (Komplement-Bit) -Master sendet erstes Bit zurück ->derjenige Busteilnehmer, der diesen Wert hat, bleibt noch aktiv, der Rest wartet. Das mache ich dann mit allen 63-Bit,bis einer übrig bleibt, oder? Also immer 2 Bit empfangen und eines senden. Habe ich das, kann ich ihm in seinen Scratchpad eine Nummer vergeben. Dann mache ich diese Sucherei solange, bis ich alle gefunden habe und ihnen eine Nummer vergeben habe. Habe ich das richtig verstanden, oder gibt es noch einen anderen Weg? Gruß Elektrikser
Hilft nicht direkt weiter, aber: Wenn man etwas Controller-Speicher frei hat (z.B. im AVR-EEPROM), kann man sich auch die eindeutigen ROM-Codes (Family-Code, Seriennummer, evtl. auch CRC) "merken" und muss nicht in das Scratchpad des DS18x20 schreiben. Indizierung dann ueber den gespeicherten Code. Etwas komplexer zu programmieren, aber koennte einfacher handhabbar sein, falls ein (oder mehr) defekter(e) Sensor(en) ausgetauscht werden mu(e)ss(en). Von Peter Dannegger wurde im Thread http://www.mikrocontroller.net/forum/read-4-84831.html#102216 "fertiger" avr-gcc-Code bereitgestellt. Bei der Gelegenheit: Danke dafuer, Peter.
O.K. dann habe ich das falsche erwischt. Werde mir das mal ansehen. Ich habe mittlerweile das AN162 bei Dallas gefunden. Das hilft auch schon weiter, obwohl es ein C-Code für ein 8051er ist. Aber so viel scheint sich da nicht zu ändern. Der Code für den Rom-Search ist dort schon größer als meine Auswertung des einen DS18S20. Jetzt hilft nur noch try and error. Gruß Elektrikser
"Jetzt hilft nur noch try and error." Warum ? Das was Du oben geschrieben hast, ist doch vollkommmen richtig. So macht es auch mein Programm. Peter
In C bin ich noch ein relativ blutiger Anfänger. (Mein Einstieg war Assembler mit den 8051ern.) Aber ich habe es mir in den Kopf gesetzt und jetzt wird es probiert. Dafür, dass ich vor fünf oder sechs Wochen damit richtig angefangen habe, geht es gar nicht mal so schlecht. Keine Angst, wenn ich Bahnhof verstehe, melde ich mich wieder! :-) Gruß Elektrikser
Hallo Peter, Ich habe mir jetzt dein Programm für den AVR angesehen (den Link, den mthomas gepostet hat: 1wire.zip). Ich habe noch ein Verständnisproblem, vielleicht hilfst du mir: "uchar w1_rom_search( uchar diff, uchar idata *id )" Die Funktion habe ich im groben verstanden, komme aber mit der Übergabe der Funktion nicht klar. idata hast du in der main.h definiert. *id ist ja ein Zeiger, der in der Tempmeas.c durch den Aufruf: "diff = w1_rom_search( diff, id );" auf die erste Adresse des ersten Feldes von id[8] zeigt. Soweit ok. Was bezweckt dieses idata? Warum schreibst du nicht einfach uchar *id? Gruß Gerd G. (Elektrikser)
Das Programm habe ich ursprünglich für den 8051 geschrieben, für den AVR hab ich "idata" einfach drin gelassen. Der 8051 hat verschiedene Speicherbereiche, "idata" ist besonders schnell und codesparend zugreifbar und erlaubt auch viele Operationen direkt auszuführen, ist aber auf 256 Byte beschränkt. "data" ist für häufige und lokale Variablen, "idata" für kleine Datenfelder und "pdata" oder "xdata" für selten benötigte Variablen oder große Felder (bis 64kB). Beim 8051 kann man also durch geschickte Auswahl des Speichersegments besonders schnelle und codesparende Programme schreiben. Peter
Aber bringt das beim AVR etwas? Wo kann ich darüber Infos bekommen? Naja, werde dein Programm compilieren und mal damit rumspielen. Später werde ich das ROM-Search mal in mein Programm einbauen. Danke für die Hilfe, Gerd
Danke Peter, für deine Hilfe. Mit Hilfe deines Programmes habe ich das jetzt zum Laufen gebracht. Gruß gerd
"Aber bringt das beim AVR etwas?" Nein, der kann ja sowas nicht. Deshalb wird es dort auch durch nichts ersetzt: #define idata Ist einfacher, als sämtliche Quelltexte umzueditieren. Peter
Habe es mir schon gedacht. Aber da hatte ich diese Zeile in der main.h überlesen gehabt. Muß mir das beim 8051er ansehen. Ich programmiere da zwar immer noch mit Assembler, aber das mit dem Speicherbereich ist interessant. Werde mal meine Unterlagen wälzen, mal sehen was ich da so finde. Irgendwie scheint mir da was entgangen zu sein.... Gruß Gerd G. (Elektrikser)
Hallo, ich versuche mich gerade an der Match ROM Funktion - leider erhalte ich nur Misst:
1 | //initialisierung
|
2 | uint8_t festeid1[8] = { 0x10,0xd9,0x9f,0xdd,0x01,0x08,0x00,0x30 }; |
3 | |
4 | //.....
|
5 | |
6 | //while(1) dann kommt:
|
7 | |
8 | start_meas(); |
9 | _delay_ms(1000); |
10 | read_meas(); |
11 | _delay_ms(1000); |
12 | |
13 | |
14 | uart_puts_P( "\r\n festeID: " ); |
15 | |
16 | for( i = 0; i < 8; i++ ) |
17 | {
|
18 | sprintf( buffer, "%02X ", festeid1[i] ); |
19 | uart_puts( buffer ); |
20 | }
|
21 | onewire_command(MATCH_ROM, festeid1); |
22 | |
23 | onewire_byte_wr( READ ); // read command |
24 | temperature = onewire_byte_rd(); // low byte |
25 | temperature |= (uint16_t)onewire_byte_rd() << 8; // high byte |
26 | |
27 | temperature <<= 3; // 9 -> 12 bit |
28 | |
29 | |
30 | sprintf( buffer, " T: %04X = ", temperature ); // hex value |
31 | uart_puts( buffer ); |
32 | sprintf( buffer, "%4d.%01d°C", temperature >> 4, (temperature << 12) / 6553 ); // 0.1øC |
33 | uart_puts( buffer );uart_puts("\r\n");uart_puts("\r\n");uart_puts("\r\n"); |
Als Ausgabe erhalte ich für drei angeschlossene DS18S20:
1 | ID: 10 6F 9B DD 01 08 00 9A T: 0180 = 24.0°C |
2 | ID: 10 D9 9F DD 01 08 00 30 T: 0180 = 24.0°C |
3 | ID: 10 A8 AF DD 01 08 00 1B T: 0180 = 24.0°C |
4 | |
5 | |
6 | festeID: 10 D9 9F DD 01 08 00 30 T: FFF8 = 4095.5°C |
Die Temperatur von FFF8 kann nicht sein, aber egal welche ID ich verwende kommt der gleiche Murks! Was mache ich falsch bin beinahe am verzweifeln! Gruß Patrick
Hallo, habe den Fehler nun gefunden!:
1 | //nicht:
|
2 | |
3 | onewire_command(MATCH_ROM, festeid1); |
4 | |
5 | onewire_byte_wr( READ ); // read command |
6 | |
7 | temperature = onewire_byte_rd(); // low byte |
8 | temperature |= (uint16_t)onewire_byte_rd() << 8; // high byte |
9 | |
10 | //sondern:
|
11 | |
12 | onewire_command(READ, festeid1); |
13 | |
14 | temperature = onewire_byte_rd(); // low byte |
15 | temperature |= (uint16_t)onewire_byte_rd() << 8; // high byte |
Gruß Patrick
Hallo Zusammen, ich habe mir den ASM Code von Peter zu Gemüt geführt - erst mal vielen Dank an Peter - und versucht ein wenig mehr Kommentare rein zu machen, denn wie in den Foren zu lesen ist ROM_SEARCH kein Pappensiel.. grad für Anfänger. Ich habe auch noch ein paar Fragen, vielleicht kann mir da jemand helfen, gehöre nämlich auch zu den Anfängern .... So nun Peters Code und meine Kommentare: ;----------------------------------------------------------------------- -- ; ROM Search ;----------------------------------------------------------------------- -- ;Input a0 = bit to resolve ;Output a0 = next bit to resolve ;Used a0, a1, a2, a3, zl w1_rom_search: mov a3, a0 ; a3 = FF rcall w1_reset ; reset bus ldi a0, presence_err ; a0 = FF -> bei fehler ist das der return wert brcs _wrs7 ; wenn error dann ende sonst weiter ldi a0, search_rom rcall w1_byte_wr ; sende search rom ldi zl, romcode ; point to rom code memory 0x01 ? warum ? ldi a0, last_device ; a0 = 0x00 ldi a2, 8 * 16 - 1 ; 8 bytes a 8 bit -> 1111111 7 mal 1 _wrs1: rcall w1_bit_rd ; READ I read bit c=0 sbc a1, a1 ; H = C rcall w1_bit_rd ; READ II read complement bit ld a1, z ; lade a1 aus speicher brhc _wrs2 ; READ I =0 wenn H=0 sprung an _wrs2 brcc _wrs4 ; READ II =0 wenn C=0 sprung an _wrs4 , bit 1 RESOLVED ldi a0, data_err ; wenn READ I und II = 1 dann Fehler ret _wrs2: ; READ I =0 brcs _wrs5 ; READ II =1 sprung an _wrs5 , bit = 0 -> RESOLV ; READ I & II = 0 cp a2, a3 ; vergleiche a2 und a3 , a3=initialwert von a0 breq _wrs5 ; bit 0 RESOLVED - warum ? brcs _wrs3 ; bit = 1, resolve - warum ? sbrs a1, 0 ; skip next wenn a1 an position 0 (ganz rechts) = 1; rjmp _wrs5 ; bit = 0 _wrs3: mov a0, a2 ; bit = 1 _wrs4: ; bit 1 RESOLVED sec ; Set carry bit rjmp _wrs6 _wrs5: ; bit 0 RESOLVED clc ; Clear carry bit _wrs6: ; Speichere bits im ROM an Z Position ror a1 ; C->b7------------------b0->C st z, a1 ; speicher a1 rol a1 ; C<-b7------------------b0<-C rcall w1_bit_wr ; sende Bit bei (Bit 0 RESOLVED send 0) subi a2, 2 ; after 8 times: H = 1 brhc _wrs1 ; wenn byte noch nicht fertig dann sprung inc zl ; next byte im speicher brcc _wrs1 ; wenn noch keine 64 bits fertig dann sprung _wrs7: ret ;----------------------------------------------------------------------- -- Was mir allerdings nicht ganz klar geworden ist ist die 1wire.h Datei ... und zwar die Definition der Register a0 bis zl hier der Ausschnitt: 1wire.h .def a0 = r27 ;working registers .def a1 = r28 .def a2 = r29 ;lcd: a0..a2 .def a3 = r31 ;1wire: a0..a3, zl .def z0 = r30 ;z pointer .def z1 = r31 ;----------------------------------------------------------------------- -- Warum ist a3 = zl? Ist zl (Doppelregister Z (R30 low R31 high) nicht eigentlich ZH d.h beim Inkrement von zl in ROM_SEARCH springe ich im Speicher gleich 255 Bytes nach oben? Zum inc Befehl habe ich generell noch eine Frage, wäre hier nicht adiw z0,1 die bessere Wahl um einen Übertrag bei z0 = FF zu ermöglichen? Wo wird R30 und R31 auf den Anfang des SRAM gesetzt, hab ich irgendwie nicht gefunden? Ok, weiter Fragen sind in den Kommentaren ... an der entsprechenden Stellen ... so wirds klarer wo es kneift. Also vielleicht hat jemand Lust und Zeit mich hier ein wenig aufzuschlauen Cheers Jens
Der ATtiny12 hat keinen SRAM, daher werden einige Register als SRAM mißbraucht. Und auch die Arbeitsregister mehrfach verwendet (nicht gleichzeitig). Peter
Hallo Ich habe versucht das Programm auf dem ATmega 32 laufen zu lassen. Ich scheitere aber bislang an der Definition von " convert ". Kann mir da jemand weiterhelfen? Gruss und danke Lothar
Beitrag #5645322 wurde von einem Moderator gelöscht.
Beitrag #5661862 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.