Hallo *,
z.Z. versuche ich mich an der Temperaturmessung mit einem DS18S20 an
einem Atmega8 16Mhz. Die Code-Beispiel die ich bisher gesehen habe,
laufen bei mir nicht.
Im Prinzip kann ich auch Kontakt zwischen dem DS18S20 und dem Atmega8
herstellen. Nur stoße ich auf folgendes Problem (siehe Auszug der
Debugausgabe):
>>Read Scratchpad>>Read Scratchpad.Done
0X1E 0X20 0XA 0XFE 0XFE 0X8C 0X96 0X0 0X6E
>>Calculate Temperature>>check crc failed
55 Celsius
>>Read Scratchpad>>Read Scratchpad.Done
0X96 0X20 0X8 0XFE 0XFE 0X8C 0X96 0X0 0X6E
>>Calculate Temperature>>check crc failed
55 Celsius
1. die Messung fällt durch die CRC-Prüfung
2. Bytes 4 und 5 sollten eigentlich per default auf 0xFF stehen hier
fehlt wohl in bit
3. die 55 Grad Celsius sind natürlich gefühlt nicht nachvollziehbar ;-)
Meine Code hab ich am Anhang gepostet!
Also, ich bin langsam ratlos und verbringe schon ein weilchen mit dem
Problem. Was läuft hier falsch?
Vielen Dank schonmal fürs Anschauen, für Kommentare und
Hilfstellungen!!!
Gruss,
Matthias
Diesen Code kannste voll in der Pfeife rauchen, sowas macht man nicht.
Der AVR-GCC lacht sich nen Ast darüber und optimiert ihn weg.
Und für die Delays schreibt man keine kryptische Zahlen.
Die stimmen, wenn überhaupt, nur für eine bestimmte CPU, bei einer
bestimmten Frequenz mit einer bestimmten Compilerversion und einer
bestimmten Optimierungsstufe.
Das ist völlig unportabler und unzuverlässiger Code.
Du mußt die Bibliotheksfunktion void _delay_us(double __us) aus delay.h
benutzen (vorher natürlich F_CPU definieren).
Warum nimmst Du nicht Code aus der Codesammlung?
Peter
Hallo Peter,
Danke fürs Schauen. Die Delays hab ich mit dem Speicheroszilloskop
kalibriert. Hätte der Compiler diese "wegoptimiert" hätte ich auf dem
DSO nichts gesehen, gelle?
Ich will nicht ausschließen, daß das Problem im Timing sitzt. Aber Deine
Annahme kann ich leider nicht bestätigen.
Ich hab mich an Deinem Code versucht, ihn aber nicht zum Laufen
gebracht. Ferner ist die Temperaturmessung ein Add-On zu einem weiteren
Programmmodul. Mit dem Code hier komme ich vom Speicher her hin. Die
portable Variante von Dir würde vom Speicher schon nicht in Frage
kommen.
Viele Grüße,
Matthias
Matthias V. wrote:
> Die Delays hab ich mit dem Speicheroszilloskop kalibriert.
Sobald du die Optimierung des Compilers einschaltest sind die Schleifen
weg. Versprochen. Nur solange du mit -O0 arbeitest werden sie
funktionieren.
Ich würde das Beispiel auf einem Pollin Funk-AVR-Evaluationsboard
ausprobieren. Allerdings mit 12 MHz Atmega8 statt 16 MHz. Sensor D18S20
ist vorhanden, denn ich wollte eh was damit experimentieren.
Schickst du mir Infos, wie du den Sensor passend zu deiner Source
angeschlossen hast?
Auf die Schnelle habe ich diesen Abschnitt gefunden
// configure your port here
// set pin mask
#define wmask 0x00
// set 1-wire pin for output
#define wOut DDRC |= wmask
// set 1-wire pin for input (bus released)
#define wIn DDRC &= ~wmask
// set 1-wire bus high
#define wH PORTC |= wmask
// set 1-wire bus low
#define wL PORTC &= ~wmask
// get 1-wire bus input (bus released)
#define wR PINC & wmask
Aber ich kann nicht sehen, wie das mit wmask 0x00 arbeiten soll. Hier
müsste IMHO ein Bit gesetzt sein - das Bit für den Pin, an dem der
Sensor hängt.
Und nochwas brauche ich zum Nachstellen der Situation, damit wir über
das gleiche reden: hast du den Sensor direkt anschlossen oder noch
zusätzliche Hardware verwendet? Wenn letzteres, schick bitte eine
Skizze/Schaltplan.
BTW: Ist das von dir angepasster Fremdcode? Wenn ja, schick auch einen
Link oder einen Hinweis, wo das Original zu finden ist. Danke.
Ich habe mal eine deiner Schleifen nachgezählt. uDelay(0) frisst beim
GCC 4.1 bereits ca. 43 Takte. Bei 4.3 sind's noch ein paar mehr. Mit
welcher Taktfrequenz arbeitest du?
Hallo *,
ich arbeite mit -O0. Eben weil der Compiler die while-Schliefen
zerflückt.
In den Sourcen ist ein Bug. Man kann wmask auf 0xFF setzen. Für einen
Sensor reicht das. Ich hatte den Fehler zu spät bemerkt und fehlerhafte
Sourcen gepostet. Die Ausgaben oben sind mit wmaxk 0xFF entstanden.
Vielen Dank und Gruss,
Mattahis
Hi Andreas,
> Ich habe mal eine deiner Schleifen nachgezählt. uDelay(0) frisst beim> GCC 4.1 bereits ca. 43 Takte. Bei 4.3 sind's noch ein paar mehr. Mit> welcher Taktfrequenz arbeitest du?
Mit 16 MHz arbeitet der Atmega im STK.
Zur Beschaltung. Ich ziehe VCC vom STK500 und lege GND auf das STK500.
Über VCC zur Datenleitung hängt noch ein Pull-Up-Widerstand mit 4,7
kOhm.
Viele Grüße,
Matthias
uups...
"Vorschau" und "Abschicken" verwechselt...
Das "Wegoptimieren" könnte man verhindern, indem man die Signatur der
Funktionen in
1
voiduDelay(volatileu8count)
und
1
voidiDelay(volatileunsignedintcount)
ändert.
Dennoch muß dann für jede Compilerversion / Optimierungsstufe neu
"kalibriert" werden, da der Compiler verschiedenen Möglichkeiten hat,
die Schleifen in Maschinencode zu übersetzen.
Also: wie man es dreht, nicht zu empfehlen...
Matthias V. wrote:
> ich arbeite mit -O0. Eben weil der Compiler die while-Schliefen> zerflückt.
Falscher Ansatz.
Bei uDelay() frisst jede Iteration je nach Compiler 10 oder 21 Takte.
Viel Vergnügen beim Update des Compilers.
Hallo *,
soeben hab ich mir Peters Code nochmal angeschaut. Der Code lief nicht,
weil ich lediglich in 1WIRE.C die Ports angepaßt hatte. Ganz übersehen
hatte ich die Definitionen in main.h.
Meanwhile liest der DS18S20 die richtige Temperatur und damit ist mein
Ziel erreicht.
Fazit: Mit diesem Fehler wieder was gelernt.
Daher Euch und ganz besonders Peter vielen Dank für die Anregungen und
Hinweise!!!!!
Damit geht mein DS18S20 Projekt nach /dev/null ;-)
Und wie ich gerade sehe, gibt es Überschneidungen im Timer-Interrupt.
Ich nutze den gleichen Timer fürs PWM zur Ansteuerung eines Motors.
Shit.
Viele Grüße,
Matthias
Sensor läuft. Ich habe beim Aufbau gesehen, dass es ein DS1820 ist und
kein DS18S20. Ausgabe s.u. Allerdings merke ich von den 48 °C nichts ;-)
1
>>Reset device
2
>>device found!
3
>>Skip Rom
4
>>Start conversation
5
>>Reset device 2
6
>> device found!
7
>>Skip Rom
8
>>Read Scratchpad
9
>>Read Scratchpad.Done
10
0 0 0XA0 0XF0 0XF0 0X60 0XB0 0 0X60
11
>>Calculate Temperature
12
>>check crc failed
13
48 Celsius
Wegen der anderen Taktrate (12 MHz statt 16 MHz) musste ich _delay_us
verwenden. Weitere Anpassungen betreffen die vielen Warnings.
Ich fuxe mich jetzt ins DS1820 Datenblatt rein.
EDIT: Oder auch nicht.
> Damit geht mein DS18S20 Projekt nach /dev/null ;-)
Ich will ja keine Leiche fleddern ;-)
Hallo Stefan,
dann bleib ich mal mit am Ball. Bin gespannt! Obwohl Peters Projekt nun
bei mir läuft würde ich schon gerne doch mein Projekt weiter im Auge
behalten, weil ich zur Steuerung eines Motors schon den Timer 1
verwende. Und ich fühle mich im Moment nicht sicher genug Peters und
mein Geraffel zusammen zu führen.
Viele Grüße,
Matthias
In meiner Bude sind es 19,5 °C. Die Fehlerursache ist fies zu finden.
Der Sensor liefert korrekte Daten (s. Anhang) aber die Ausgabe meldet
Schrott und CRC Probleme. Der Fehler steckt in diesem Codestück:
1
// configure your port here
2
// set pin mask
3
#define wmask (1<<PC4);
4
// set 1-wire pin for output
5
#define wOut DDRC |= wmask
6
// get 1-wire bus input (bus released)
7
#define wR PINC & wmask
8
// ...
9
10
u8wRxbit(void)
11
{
12
u8data;
13
14
wOut;wL;
15
DELAY__1US;// 10.58us
16
wIn;
17
DELAY_10US;// Lesen innerhalb der ersten 15 uS
18
data=wR;
19
DELAY_60US;// 61.82us
20
returndata;
21
}
22
23
u8wRxbyte(void)
24
{
25
u8i;
26
u8bit;
27
u8data;
28
29
data=0x00;
30
for(i=0;i<8;i++)
31
{
32
#if 1
33
// Ohne Fehler
34
// allerdings auch nicht multipinfähig!
35
data>>=1;
36
bit=wRxbit();
37
if(bit)
38
data|=(1<<7);
39
#else
40
// Mit Fehler
41
// Das geht nur gut, wenn wRxbit() 1 oder 0 zurückliefert
42
// Das geht schief, wenn über wmask mehrere Pins im Spiel
43
// sind (z.B. bei dir "Man kann wmask auf 0xFF setzen")
44
// oder der 1-Wire-Pin nicht Pin 0 (z.B. bei meinem Aufbau
45
// an PC4) ist...
46
bit=wRxbit();
47
data|=bit<<i;
48
#endif
49
}
50
returndata;
51
}
Die _delay_us arbeiten gut auch mit 12 MHz. Ich sehe keinen Grund für
die handausgemessenen Schleifen.
Hi Stefan,
das nenne ich konstruktiv!!! Dir vielen Dank an der Stelle.
Ich habe versucht die Delays mit der avrlib umzusetzen.
Dabei ist mir aufgefallen, daß ein _delay_us (480) tatsächlich 48 us
benötigt. Allerdings arbeite ich mit 16 MHz. Ähnliches gilt auch für
_delay_us(410).
Ich habe das wieder entsprechend angepaßt bzw. kalibriert und
jetzt funktionierts!!!
Dir nochmal vielen Dank, dass Du dir noch mit dem Problem die Nacht um
die Ohren geschlagen hast!!!
Das erspart mir jetzt die Umschreiberei der restlichen Module.
Multipin Fähigkeit ist eh nicht gefragt, von daher bin ich mit der
Lösung absolut zufrieden.
Viele Grüße,
Matthias
Matthias V. wrote:
> Dabei ist mir aufgefallen, daß ein _delay_us (480) tatsächlich 48 us> benötigt.
Die Delay-Funktionen der avr-libc haben leider einen eingebauten aber
immerhin dokumentierten Webfehler. Jenseits von 768/Clock (48µs bei
16MHz) wird (in halbwegs aktuellen Versionen) auf _delay_ms
umgeschaltet, allerdings wird bei der fälligen Umrechnung abgerundet, so
dass _delay_ms(0) rauskommt. Ganz alte Versionen sind in dem Fall
komplett undefiniert.
Damit sind die für 1-Wire Delays ebensowenig einsetzbar, wie deine
handkalibierten.
Weshalb ich eine andere Version der Delay-Routinen einsetze. Die stammt
letztlich aus der Martin Thomas'schen Version von Peter Daneggers 1-Wire
Routinen. Anbei.
Hi, hab Sie ersetzt. Sie waren ja schon in Peters Projekt enthalten.
Etwas angepaßt noch auf dem Parameter F_CPU.
Läuft einwandfrei.
Vielen Dank und Gruss,
Matthias
Welche Version von WinAVR verwendest du?
> allerdings wird bei der fälligen Umrechnung abgerundet,
In dem Punkt muss ich mich korrigieren. Ich hatte übersehen, dass der
Kram in "double" gerechnet wird. Die aktuelle Version von <util/delay.h>
sollte eigentlich auch funktionieren.
Ach, ja ;-) SIE-lowercase! Nach lustig kommt doof (reine Selbstkritik).
Nun zu Deiner Frage...
Im Einsatz ist ....... WinAVR-20070525.
Aktuell ist ....... WinAVR-20080411.
Ich sehe aber gerade, daß die util/delay.h auch in der eingesetzten
Version erhalten ist. Dennoch tritt das Phänomen dort auf. Klar #include
<avr/delay.h> führt intern auf <util/delay.h>.
Greets,
Matthias
Hallo
ich habe die Software von Matthias heruntergeladen (vielen Dank!!) und
versucht für den ATMEGA8 zu complimieren.
Leider bekomm ich immer einen Fehler:
1
uint8_tdocrc8(uint8_tnumber_of_bytes_to_read)/// HIER ist der Fehler
Mit folgender Fehlermeldung:
../crc8.c:10: error: expected '=', ',', ';', 'asm' or '__attribute__'
before 'uint8_t'
Ich weis leider nicht wiso, ich habe die h - Files includiert und denke
das diese passen müssten.
Weis jemand von euch an was dies liegen könnte?
Ich habe das komplette Projekt hochgeladen, vl ist es einfacher was zu
finden. ( Ich verwende AVR Studio 4.16 und WinAVR-20090313)
Grüße
Luke
Luke schrieb:> Mit folgender Fehlermeldung:> ../crc8.c:10: error: expected '=', ',', ';', 'asm' or '__attribute__'> before 'uint8_t'
File: global.h
letzte Definition
1
EXTERNuint8_trx_received// die Variable wird in ein Register verlegt, spart ca. 30 Byte
da fehlt der ;
Bei Fehlermeldungen für die du keine Erklärung findest, immer auch die
unmittelbar vorhergehenden Zeilen untersuchen. Wenn die aus einem Header
File kommen, dann auch ins Header File schauen.