Hallo,
ich versuche schon länger einen DS18S20 Temperatursensor zum laufen zu
bringen, scheitere aber immer am Auslesen der Temperatur.
Um die Temperatur auslesen zu können muss ich laut Doku ein READ-Signal
senden und danach die Temperatur empfangen. Da ich sowohl senden als
auch empfangen muss um eine Temperatur zu bekommen weiß ich nicht in
welcher Funktion der Fehler ist (vllt. auch in beiden).
Die Initialisierung des Sensors funktioniert auf jeden Fall, das hab ich
bereits testen können - er ist also nicht defekt oder so.
Der Code:
1
voidwrite(unsignedcharc)
2
{
3
charcnt;
4
for(cnt=0;cnt<8;++cnt){
5
DQ=0;
6
t0_wait(0xFF,0xF1);// 15µs
7
DQ=(c>>cnt)&1;// write bit to sensor
8
t0_wait(0xFF,0xD3);// 45µs
9
}
10
}
1
voidread()
2
{
3
charcnt;
4
write(FC_READ);
5
for(cnt=0;cnt<8;++cnt){
6
DQ=0;
7
t0_wait(0xFF,0xFE);// 1µs
8
Tlow|=((char)DQ<<cnt);// read bit from sensor
9
t0_wait(0xFF,0xC4);// 60µs
10
}
11
DQ=0;
12
t0_wait(0xFF,0xFE);// 1µs
13
Thigh=DQ;
14
}
DQ ist das Bit an das die Daten gesendet werden, Tlow das erste
gesendete Byte, Thigh das Zweite (von dem ich aber nur ein Bit brauche).
Ich hoffe hier ist jemand dabei, der einen DS18S20 schon mal zum laufen
gebracht hat und der mir sagen kann was da falsch dran ist. Das
Datasheet:
http://www.datasheetcatalog.net/de/datasheets_pdf/D/S/1/8/DS1820.shtml
So nun habe ich ein wenig Zeit gefunden, die beiden Dinge zu
vergleichen:
Zu deiner read Funktion:
- warum liefert diese Funktion keine Werte zurück? bzw. wo befinden sich
Tlow und Thigh? werden diese auch vor Aufruf der Funktion richtig
initialsiert? Ich würde Pointer an die Funktion übergeben, dann richtig
initialisieren und erst dann schreiben. Wäre dann übersichtlicher.
- zum Lesen solltest du den Bus wieder freigeben, das konnte ich bei dir
nirgends finden da steht nur DQ=0. Ich gebe den Bus nach 6 µs wieder
frei, 1µs sollte allerdings auch ausreichen.
- du liest direkt nach 1µs den Bus aus, das Signal des DS18S20 ist aber
erst nach 15 µs nach den fallende Flange gültig, das steht im Text des
Datenblatt unter READ-TIME SLOTS S.13
Zu deiner write Funktion:
- du solltest zwischen den Bits auch noch 1 µs warten. Das wären dann
bei dir mind. 46 µs statt 45.
-sonst siehts gut aus
Probier das mal aus und berichte dann wieder.
Klaus Wachtler schrieb:> Schon mal die Suchfunktion bemüht?> Es gibt hier doch bestimmt schon lauffähige Lösungen.
Ja, hab ich. Aber das hat mir alles leider nicht wirklich
weitergeholfen.
Benni L. schrieb:> - warum liefert diese Funktion keine Werte zurück? bzw. wo befinden sich> Tlow und Thigh? werden diese auch vor Aufruf der Funktion richtig> initialsiert? Ich würde Pointer an die Funktion übergeben, dann richtig> initialisieren und erst dann schreiben. Wäre dann übersichtlicher.
Der Code ist noch im Betastatus, weshalb ich ihn erst auf die einfachste
Weise geschrieben hab, die mir eingefallen ist. Sobald er mal läuft
werde ich ihn überarbeiten. Ich lese in der read-Funktion gleich beide
Bytes aus, weshalb ich auch keine Werte zurückgeben brauche. Die
einzelnen Bits schiebe ich dann einfach an den richtigen Platz. Das hab
ich im Simulator-Debugger getestet und das hat auch funktioniert.
Tlow und Thigh sind global und initialisiert.
Benni L. schrieb:> - zum Lesen solltest du den Bus wieder freigeben, das konnte ich bei dir> nirgends finden da steht nur DQ=0. Ich gebe den Bus nach 6 µs wieder> frei, 1µs sollte allerdings auch ausreichen.
Hab gedacht das freigeben würde automatisch über diesen "pullup
resistor" erfolgen. Hab ich zu Testzwecken aber mal eingebaut.
Benni L. schrieb:> - du liest direkt nach 1µs den Bus aus, das Signal des DS18S20 ist aber> erst nach 15 µs nach den fallende Flange gültig, das steht im Text des> Datenblatt unter READ-TIME SLOTS S.13
Da steht doch: "Output data from the DS18S20 is valid for 15μs after the
falling edge that initiated the read-time slot." Das bedeutet doch, dass
die Daten nur 15μs gültig sind und nicht, dass sie es erst ab 15μs
gültig sind.
Benni L. schrieb:> - du solltest zwischen den Bits auch noch 1 µs warten. Das wären dann> bei dir mind. 46 µs statt 45.
Hab mir gedacht, dass der Code ja auch noch Zeit benötigt bis er
ausgeführt ist, weshalb ich das nicht berücksichtigt hab. Aber hab es
sicherheitshalber mal eingebaut.
Trotz aller Ratschläge bekomme ich dennoch kein Signal vom Sensor.
Ich hab deinen Code, Benni, mal fast 1:1 übernommen, er geht bei mir
aber dennoch nicht:
Vielleicht gehen ja die Dateien im Anhang.
Damit hatte ich mal erfolgreich von einem DS1820 gelesen
(atmega32, 16MHz).
Leider in C++, aber der für dich relevante Teil ist reines C.
Als Ausgangsbasis kannst du ja damit anfangen und weglassen, was
du nicht brauchst (in C++ ist eigentlich nur die LCD-Ausgabe).
PS: sehe gerade, daß da auch noch auskommentiert das gleiche
Spiel für einen TSic 206 dabei ist.
Ebenso wird irgendwo eine LED an- oder asusgeschaltet, der
Kommentar dazu faselt von einem Relais (für das der Quelltext später
verwendet wurde).
Nicht verwirren lassen!
Danke für eure Codes, die kann ich auf meinem μC aber leider nicht
benutzen. Und große Unterschiede zu meinem Code kann ich nicht erkennen
- trotzdem geht er nicht.
Ansonsten bin ich genau so vorgegangen wie in deinem Dokument, BvB, das
echt super ist. Dennoch funktioniert nach wie vor nur das Resetsignal.
Ich hab den Code jetzt zwar so umgeschrieben, dass der komplette
Scratchpad (9 Bytes) ausgelesen wird, ich erhalte aber nur lauter Einsen
als Ausgabe, was bedeutet, dass der Sensor nicht reagiert:
1
voidwrite(unsignedcharc)
2
{
3
charcnt;
4
for(cnt=0;cnt<8;++cnt){
5
DQ=0;
6
if((c>>cnt)&1==1)
7
DQ=1;
8
delay_us(12);// 100µs
9
DQ=1;
10
}
11
}
1
voidread()
2
{
3
charcnt,i;
4
for(i=0;i<9;++i){
5
for(cnt=0;cnt<8;++cnt){
6
DQ=0;
7
DQ=1;
8
delay_us(2);// 15µs
9
ds1820[i]|=((char)DQ<<cnt);
10
delay_us(12);// 100µs
11
}
12
}
13
}
Ich setze DQ ja immer auf 1, weshalb diese auch immer in das Array
ds1820 geschrieben wird.
Da alle gelesenen Bits kein Signal zurückgeben, muss der Fehler muss
entweder in der Zeitverzögerung der read-Funktion liegen (zu kurz), oder
in der write-Funktion. Ich hab schon alle möglichen minimale bis
maximale mögliche Werte probiert, aber leider keine Änderung.
Weiß jemand wie der Sensor reagiert, wenn der vorhergehende READ-Befehl
nicht erfolgreich war? Antwortet er dann überhaupt?
Ich habe da gerade so eine Befürchtung ;)
was benutzt du eigentlich für einen Controller? Und kannst du mal hier
posten wie DQ definiert ist.
Ich befürchte nämlich, dass du den Bus mit beim Lesen nicht in den
hochohmigen Zustand versetzt sondern auf aktiv High (Pin von Output auf
Input ändern beim Lesen). Bei Atmel musst du dazu das DDR ändern, bei
PIC das TRIS Register.
unknown schrieb:> Weiß jemand wie der Sensor reagiert, wenn der vorhergehende READ-Befehl>> nicht erfolgreich war? Antwortet er dann überhaupt?
Das meine ich mit meinem Post. Er wird womöglich versuchen zu antworten,
aber es nicht schaffen den Bus gegen den Controller herunterzuziehen.
Ich hab einen AT89C5131 von Atmel. Kompilieren tu ich mit dem
C51-Compiler, der auch von Atmel ist.
1
sfrp=0xA0;// Port 2
2
sbitDQ=P2^0;// Daten I/O
Bisher hab ich nur auf DQ zugegriffen. Beim DDR hab ich nichts gemacht.
Ich wüsste auch gar nicht was man da ändern kann. ;)
Wäre schön wenn du mir das noch genauer erklären könntest.
Also selber bauen geht leider nicht, da ich davon keine Ahnung hab. Ich
steuere die Bausteine nur an, kann sie aber nicht selbst herstellen...
Und den Sensor an P0 anzuschließen hat leider auch keinen Erfolg
gebracht. Aber das liegt vllt. auch daran, weil der bei mir irgendwie
defekt ist. Da funktioniert nicht einmal das Reset-Signal. Aber sind die
Signale denn nicht identisch? Ich mein, wenn der Sensor auf einen Reset
antworten kann, dann müsste er doch auch auf einen Lese-Befehl antworten
können.
Hmm ich hab mir das Bild der I/O vom AT89C5131 nochmal genauer
angeschaut. Du hast recht, es sollte auch mit P2 funktionieren und DQ =
1. Wie hast du den DS18S20 angeschlossen? VCC und GND und den Bus mit
Pullup? Oder mit parasitärer Versorgung nur über den Bus?
Woher weisst du, dass du den Presence Pulse sicher empfängst? Dürfte ich
da mal die Funktion dafür sehen? Ein Oszi hast du nich zufällig?