Murph (Diskussion | Beiträge) K |
K (→Weblinks) |
||
Zeile 236: | Zeile 236: | ||
[[Kategorie:Kommunikation]] | [[Kategorie:Kommunikation]] | ||
[[Kategorie:Microcontroller]] | [[Kategorie:Microcontroller]] | ||
− | |||
[[Kategorie:Praxis]] | [[Kategorie:Praxis]] | ||
[[Kategorie:Software]] | [[Kategorie:Software]] | ||
[[Kategorie:Quellcode Bascom]] | [[Kategorie:Quellcode Bascom]] |
Version vom 19. Juni 2009, 15:09 Uhr
In diesem Artikel folgen einige Programmbeispiele, in denen gezeigt wird wie Bascom über den 1-Wire-Bus kommuniziert.
1-Wire (Eindraht) ist eine serielle Schnittstelle, die mit nur einer Datenleitung auskommt, die gleichzeitig auch noch als Stromversorgung genutzt werden kann. Aufgrund der Einfachheit kann diese Schnittstelle leicht in Software auf einem Mikrocontroller nachgebildet werden.
In Bascom sind Befehle für die 1-Wire-Kommunikation enthalten, sodass der Programmierer sich nicht um das Protokoll und das Timing der Übertragung kümmern muss.
Es gibt 1-Wire-Geräte mit verschiedenen Funktionen, in der Roboterwelt dürfte einer der bekanntesten der Temperatursensor DS18S20 (bzw. DS18B20) sein, deswegen wird dieser in den Beispielen verwendet.
Inhaltsverzeichnis
Beschaltung
Die Beschaltung rund um den DS18B20 sieht so aus:
Ablauf der Kommunikation
Die Kommunikation mit dem 1-Wire-Gerät muss immer diesen Ablauf haben:
- Initialisierung
- "ROM Function" Befehl
- "Memory Function" Befehl
- Übertragung/Daten
Aus diesem Ablauf ergeben sich die beiden folgenden Programmabläufe.
Kommunikation mit nur einem Gerät
Wenn sich nur ein einziges Gerät am Bus befindet kann man diese kurze Version der Kommunikation verwenden. Ein ROM-Befehl ist dabei nicht notwendig und kann übersprungen werden, dies muss aber dem Gerät mitgeteilt werden.
Beispiel:
' Minimalprogramm für Temperaturmessung Config 1wire = Portc.7 Dim Sp(9) As Byte 1wreset ' Initialisierung 1wwrite &HCC ' überspringe ROM-Befehl 1wwrite &H44 ' Temperaturmessung anstoßen Waitms 500 ' warten bis Messung fertig 1wreset ' Initialisierung 1wwrite &HCC ' überspringe ROM-Befehl 1wwrite &HBE ' Temperatur auslesen Sp(1) = 1wread(9) ' Daten in ein Array lesen Wait 1
Im Array Sp() stehen die Daten des Gerätes die dann Anhand des Datenblattes ausgewertet werden.
Kommunikation mit mehreren Geräten
Wenn sich mehrere Geräte am 1-Wire-Bus befinden, müssen diese jeweils Adressiert werden um mit dem gewünschten Gerät in Kontakt zu treten. Zum Adressieren wird die Seriennummer verwendet, die in jedem 1-Wire-Gerät eindeutig vorhanden ist. Um an diese Seriennummer zu kommen gibt es zwei Strategien.
Entweder man liest bei allen Geräten vorher einzeln diese Nr. aus, um diese in das eigentliche Programm einzutragen (kürzer), oder man sucht beim Programmstart jedesmal nach vorhandenen Geräten (flexibler).
SerienNr einzeln auslesen
Config 1wire = Portc.7 Dim Ar(8) As Byte 1wreset 1wwrite &H33 ' ROM-Befehl zum lesen der SerienNr Ar(1) = 1wread(8) ' 8 Bytes lesen For I = 1 To 8 Print Hex(ar(i)); ' Ausgeben Print " "; Next Print Wait 1
Im Array Ar() befindet sich somit die SerienNr des Gerätes.
SerienNr aller Geräte
$regfile = "M32def.dat" $crystal = 16000000 $baud = 38400 Config 1wire = Portc.7 Dim Ar(8) As Byte ' Array für SerienNr. Dim I As Byte Dim W As Word Sound Portd.7 , 400 , 450 ' BEEP bei RN-Control Print Print "1-Wire" Wait 1 Ar(1) = 1wsearchfirst() ' gibts überhaupt ein Gerät If Err = 0 Then Do ' Ausgabe der SerienNr. For I = 1 To 8 Print Hex(ar(i)); Print " "; Next Print ' Nach weiterem Gerät suchen Ar(1) = 1wsearchnext() Loop Until Err = 1 ' solange bis sich kein weiteres Gerät mehr meldet. End If Print "Fertig" W = 1wirecount() ' Anzahl der gefundenen Geräte zählen Print "Anzahl "; Print W Do Loop End
Am ersten Byte der SerienNr (Family-Code) ist zu erkennen um welches Gerät es sich handelt, beim DS18B20 ist es die &H28, beim DS18S20 die &H10. Da beide unterschiedliche Formate beim Temperaturwert haben, kann die Berechnung anhand des Family-Code angepasst werden.
Bestimmtes Gerät ansprechen
Um bei mehreren vorhandenen Geräten ein bestimmtes anzusprechen muss es mit der SerienNr adressiert werden.
Do 1wverify Ar(1) ' Gerät mit der SerienNr. aus Ar() auswählen ' Gerät vorhanden If Err = 0 Then 1wwrite &H44 ' Temperaturmessung anstoßen Waitms 500 ' warten bis Messung fertig 1wverify Ar(1) ' Gerät mit der SerienNr. aus Ar() auswählen 1wwrite &HBE ' Temperatur auslesen Sp(1) = 1wread(9) ' Daten in ein Array lesen For I = 1 To 9 Print Hex(sp(i)); Next Print ' Nur für die Temperatur wichtige Daten ausgeben Print Hex(sp(2)); Print Hex(sp(1)) Else Print "Fehler" End If Wait 1 Loop
Die SerienNr. des gewünschten Gerätes muss im Array Ar() stehen, bevor es mit 1wverify gesucht wird, dies ist auch gleichzeitig der ROM-Befehl, diesem kann der Memory-Befehl folgen, und anschließend die Daten übertragen werden.
Prüfsumme
Da wegen der einen Datenleitung durchaus mit Störungen zu rechnen ist, wird jeder Übertragung ein Prüfbyte angehängt, mit dem sich die Korrektheit der Daten überprüfen lässt.
Config 1wire = Portc.7 Dim Ar(8) As Byte ' Array für SerienNr Dim I As Byte 1wreset If Err = 0 Then 1wwrite &H33 ' ROM-Befehl zum lesen der SerienNr. Ar(1) = 1wread(8) ' 8 Bytes lesen For I = 1 To 8 Print Hex(ar(i)); ' Ausgabe der SerienNr. Print " "; Next Print Print Hex(crc8(ar(1) , 7) ) ' Prüfsumme ausgeben If Ar(8) = Crc8(ar(1) , 7) Then ' Prüfsumme vergleichen Print "Daten OK" Else Print "Fehler" End If End If
Wenn das letzte Byte der Übertragung und die berechnete Prüfsumme aus den Bytes 1-7 übereinstimmt, war die Übertragung erfolgreich, und die Daten können weiterverarbeitet werden. Beim auslesen der Temperatur werden 9 Bytes übertragen, deshalb müssen zum berechnen der Prüfsumme Byte 1-8 einbezogen werden.
Parasitäre Stromversorgung
Da bei der Schaltung von oben eigentlich drei Leitungen benötigt werden, statt der einen wie man vermuten könnte, ist es mit der folgenden Schaltung immerhin möglich die Anzahl auf zwei Leitungen zu reduzieren.
Es ist aber Abhängig vom Gerät und den Umgebungsbedingungen ob es sich immer so lösen lässt. Ein Blick ins Datenblatt hilft da weiter.
Siehe auch
Weblinks
--Linux 80 03:16, 23. Aug 2008 (CEST)