Forum: Compiler & IDEs DS18S20, Atmega8 und Winavr


von Matthias V. (snailhouserock)


Angehängte Dateien:

Lesenswert?

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

von Peter D. (peda)


Lesenswert?

1
void uDelay(u8 count)
2
{
3
    while(count--);                 
4
}
5
6
void iDelay(unsigned int count)
7
{
8
    while(count--); 
9
}
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

von Matthias V. (snailhouserock)


Lesenswert?

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

von Matthias V. (snailhouserock)


Lesenswert?

Rehi, klar ist es so schwierig, den Code auch praktisch zu testen. Kein 
Zweifel, sorry, Matthias

von Andreas K. (a-k)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Martin L. (melvin_the_moose)


Lesenswert?

Das "Wegoptimieren" könnte man verhindern, indem man die Signatur der 
Funktionen zu
1
void uDelay(u8 count)

von Andreas K. (a-k)


Lesenswert?

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?

von Matthias V. (snailhouserock)


Lesenswert?

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

von Matthias V. (snailhouserock)


Lesenswert?

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

von Martin L. (melvin_the_moose)


Lesenswert?

uups...
"Vorschau" und "Abschicken" verwechselt...

Das "Wegoptimieren" könnte man verhindern, indem man die Signatur der
Funktionen in
1
void uDelay(volatile u8 count)
und
1
void iDelay(volatile unsigned int count)
ä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...

von Andreas K. (a-k)


Lesenswert?

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.

von Matthias V. (snailhouserock)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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 ;-)

von Matthias V. (snailhouserock)


Lesenswert?

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

von Andreas K. (a-k)


Lesenswert?

Stefan "stefb" B. wrote:

> Allerdings merke ich von den 48 °C nichts ;-)

Sei froh, dass es kein DS18B20 ist. Dann wären es 384°.

von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

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
u8 wRxbit (void)
11
{
12
   u8 data;
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
   return data;
21
}
22
23
u8 wRxbyte (void)
24
{
25
    u8 i;
26
    u8 bit;
27
    u8 data;
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
    return data;
51
}

Die _delay_us arbeiten gut auch mit 12 MHz. Ich sehe keinen Grund für 
die handausgemessenen Schleifen.

von Matthias V. (snailhouserock)


Lesenswert?

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

von Andreas K. (a-k)


Angehängte Dateien:

Lesenswert?

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.

von Matthias V. (snailhouserock)


Lesenswert?

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

von Andreas K. (a-k)


Lesenswert?

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.

von Andreas K. (a-k)


Lesenswert?

Matthias V. wrote:

> Hi, hab Sie ersetzt.

Netter Versuch, aber so leicht lasse ich mich nicht ersetzen. ;-)

von Matthias V. (snailhouserock)


Lesenswert?

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

von Luke (Gast)


Angehängte Dateien:

Lesenswert?

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_t  docrc8 ( uint8_t number_of_bytes_to_read )  /// HIER ist der Fehler
2
{
3
  uint8_t   crc;
4
  uint16_t loop_count;
5
  uint8_t  bit_counter;
6
  uint8_t  data;
7
  uint8_t  feedback_bit;
8
  
9
  crc = CRC8INIT;
10
11
  for (loop_count = 0; loop_count != number_of_bytes_to_read; loop_count++)
12
  {
13
    data = ow_buffer[loop_count];
14
    
15
    bit_counter = 8;
16
    do {
17
      feedback_bit = (crc ^ data) & 0x01;
18
  
19
      if ( feedback_bit == 0x01 ) {
20
        crc = crc ^ CRC8POLY;
21
      }
22
      crc = (crc >> 1) & 0x7F;
23
      if ( feedback_bit == 0x01 ) {
24
        crc = crc | 0x80;
25
      }
26
    
27
      data = data >> 1;
28
      bit_counter--;
29
    
30
    } while (bit_counter > 0);
31
  }
32
  
33
  return crc;
34
}
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

von Luke (Gast)


Lesenswert?

Pardon hab am falschen Thread gepostet :(

von Karl H. (kbuchegg)


Lesenswert?

Luke schrieb:

> Mit folgender Fehlermeldung:
> ../crc8.c:10: error: expected '=', ',', ';', 'asm' or '__attribute__'
> before 'uint8_t'


File: global.h

letzte Definition
1
EXTERN          uint8_t rx_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.

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
Noch kein Account? Hier anmelden.