Seltsam: Atmega328 bzw. 168 halten verordnete Pause (=delay) nicht ein

mmi

Mitglied
27. Okt. 2009
101
0
16
Northern Bavaria
Sprachen
  1. ANSI C
Hallo zusammen,

nachdem hier einige hervorragende Atmel-Spezialisten zugange sind, will ich mal meine aktuelle Problematik schildern - ein für mich äusserst seltsames Verhalten.

Auf einem Arduino Duemilanove Board läuft ein Atmega 328 mit 16 Mhz Takt. Arduino-spezifische Eigenheiten wie z.B. Bootloader kommen nicht in Frage, der Atmega könnte eigentlich auch auf jedem anderen Board sitzen.

Ich musste feststellen, daß das "delay" Kommando unter normalen Umständen nicht mehr korrekt ausgeführt wird. Ich habe deshalb ein simples Programm geschrieben, das lediglich an einem Pin eine LED für 4 Sekunden ein- und für 4 Sekunden ausschaltet, also Blinken im 4 Sekunden-Rhythmus (in C mit 2 mal "delay(4000)" bewerkstelligt, verwendet wird avr-gcc und avrdude, aber daran liegt es sicher nicht).

Die LED blinkt viel schneller als gewollt - ziemlich exakt im 1 Sek. Rhythmus, also 4x so schnell - was sich ja leicht im Vergleich mit dem Sekundenzeiger an der Armbanduhr feststellen lässt.

Ich habe dann folgende Prozedur gemacht:

- Fuses über ISP mit AVR MKII neu geflasht, anschließend reset
- siehe da: jetzt sind die Pausen korrekt (4 secs), auch mehrere resets (über reset-Taster) stören nicht
- die Freude währte nicht lange:
- Stromversorgung aus-/eingeschaltet: alter Fehler wieder da (4x schneller)
- das unveränderte Programm habe ich nochmal geflasht, derselbe Effekt.

Diese Prozedur habe ich mehrmals wiederholt, immer dasselbe Ergebnis.

Dann habe ich den Prozessor gewechselt, ein Atmega168 anstelle dem 328er - aber auch hier exakt dasselbe Verhalten. Ein fehlerhafter Prozessor scheidet somit wohl aus. :bad:

Daß sollte wohl irgendwie mit den internen Timern zu tun haben, aber warum läuft es unmittelbar nach dem Flashen der fuses immer richtig und dann nicht mehr?

Hat jemand eine Idee, wo man da ansetzen könnte ?

Danke und Gruß,
Manfred.
 
Kannst Du das mal mit einem kleinen Testprogramm ohne delay - direkt mit dem Hardware-Timer testen? Wenn ich das richtig überschlagen habe, sollte ein 16bit-Timer mit 1024er prescaler, abgeleitet aus 16MHz ca 4,2sec bis zum Überlauf brauchen. Also dann im TOV einfach das PIN-Register-Bit der entsprechenden LED = 1 setzen (das toggelt das Bein, und läßt sich normalerweise direkt setzen (in Assembler mit SBI))
 
Hey,

was mir noch einfällt...

du schreibst delay(4000);

also ich kenn nur die delay_ms();
oder hast du da von Andurio irgendetwas eigenes und nicht den normalen WinAVR ?

Hast du den Optimizer eingestellt ? (Weil davon lebt die delay.h)

Aber wie Lotada schon sagte, hierfür wäre der HardwareTimer eh die bessere Variante :).

Gruß,
Manuel
 
@LotadaC:
Direkter Test mit Timer2 und ISR-Routine sowie diversen prescalern:
Zuerst gleiches Verhalten wie mit "delay": nach dem Flashen läuft alles richtig (auch nach resets). Nach Aus-/Einschalten des Boards wieder alles zu schnell.

Zusätzliche neue Erkenntnis nach über 1 Std. Betrieb: Auch nach dem Flashen kein normaler Zustand mehr erreichbar - alles scheint noch schneller zu laufen, denn die LED blinkt jetzt gar nimmer.
Habe auch Spannungsversorgung kontrolliert, aber alles im grünen Bereich. Kann nur hoffen, daß ich mir dadurch nicht bis zu drei Prozessoren geschrottet habe. Wäre nicht auch möglich, daß der externe Quarz bzw. die Filterkondensatoren "spinnen"? Oszi sollte bald zur Verfügung stehen, dann sieht man mehr.

@Manuel:
Hier läuft alles mit Linux, dafür gibt's leider kein AVR-Studio, WinAVR, etc. Aber mit dem avr-gcc (den es auch für Win gibt) kommt man auch ganz gut zurecht.

Die Arduino-IDE ist eigentlich identisch zum C bzw. C++ Standard ohne Einschränkungen. Man kann für eine effizientere Programmierung durchaus Portbits, Registerwerte, etc. direkt setzen - also keine Beschränkungen für den C-Programmierer.
Für den Einsteiger sind Befehle wie z.B. "digitalWrite(pin, HIGH)" leichter zu verstehen, als wenn man ihn gleich mit AND, OR, XOR konfrontiert. Ich arbeite ganz gerne mit den Arduino-Clones, insbesondere den kleinen Bauformen wie z.B. Nano.

Danke für Eure Bemühungen,
Gruß, Manfred.
 
Mein nächster Schritt wäre jetzt, das mit dem internen Taktgeber durchzugehen, aber ich weiß nicht, ob das mit Deinem Arduino überhaupt geht. Es sei denn, Du hast ein Oszilloskop zur Hand.
 
@mmi: Hast Du die Fuses richtig gesetzt? Du sagst, die MCU hat einen Quarz und läuft mit 16MHz. Ist es sicher? Sprich, hast Du der MCU gesagt, dass da ein externer Quarz dran hängt? So ein Verhalten hatte ich nämlich mal, als ich vergessen habe die Fuses richtig zu setzen.

Ansonsten: Finger weg vom delay. Das Problem ist hier, dass Du die MCU vollständig schlafen legst und sie nichts anderes in der Zeit machen kann. Hier ist ein Timer eine deutlich bessere Variante.
 
@LotadaC: Mit dem internen Takt ist eine gute Idee, obwohl dasselbe Verhalten mit einem anderen neuen Prozessor schon
dafür spricht, daß es eine externe Ursache hat. Aber egal, ich mach's heute abend mal, fuse ist ja schnell geändert.

@Hemi: Das Board ist schon geraume Zeit im Einsatz - mit externem Quarz und fuse im atmega für 16 Mhz. Habe die fuses auch schon
mehrmals neu geflasht, dann lief es zunächst richtig. Anschliessend Stromzufuhr ein-/ausgeschaltet: alter Fehler wieder da. Und mit einem anderen, nagelneuen Prozessor ist es dasselbe.

Der Unterschied zwischen der "delay"-Funktion und einer timergesteuerten Interruptroutine ist bekannt. Habe ja mittlerweile mit beiden Methoden getestet (siehe oben).

Bald werde ich ein DSO haben, dann lässt sich bei solchen Fehlern doch gleich vernünftiger arbeiten. :)
 
hey,

mal ne andere idee,

kann das ganze eventuell an deinem Watchdog / Reset hängen ?!?

Häng hier doch mal dein Programm an ... es sieht für mich so aus, als ob dein Programm irgendwie hängt und das "Blinken" irgendwie garnichts mit deiner Delay zu tun hat ^^
 
Die einfachste Version - die auf anderen boards problemlos funktioniert und vom durchschnittlichen Arduino-User zigfach seit Jahren im Einsatz ist:

Code:
void loop() {
    digitalWrite (11, HIGH);  // LED an pin 11 ein
    delay (1000);  // 1 sec. Pause
    digitalWrite (11,LOW);   // LED an pin 11 aus
    delay (1000);
}

Das erzeugte HEX-file ist absolut ok, denn auf anderen Boards mit gleichem atmega läuft es ja einwandfrei.
Jetzt noch weitere Tests mit effizienten Timerinterrupts zu machen (einen habe ich ja schon gemacht), kostet mir zuviel Zeit, das ist es mir nicht wert. Für ein paar Euros gibt's ein neues board - und gut isses :goodnight:

Was ich z.B. gerne gehört hätte: "instabiles Schwingverhalten des externen Quarzes" könnte zu solchen Effekten führen.:nurse:

Morgen kommt ein 100Mhz Oszi, dann lässt sich das in ein paar Minuten noch prüfen, aber sonst steck' ich da keine Minute mehr rein, es lohnt sich einfach nicht.
 
... aber so schnell gibt man dann doch noch nicht auf. :)

Vielleicht interessiert ja jemanden die Lösung - mir hat sie nun genug Zeit gekostet - aber wenn am Ende doch noch alles gut ausgeht - Schwamm drüber. ;)

Ich bin bisher davon ausgegangen, daß die Arduino-IDE auch über ISP den Speicherbereich mit dem bootloader korrekt behandelt - zumal ich bisher schon öfter so problemlos gearbeitet hatte. Leider ist es so nicht. hfuse wird für einen nur 512 words grossen Bootbereich gesetzt - anstelle von 2048! Das führte zu diesen abenteuerlichen Effekten, seltsamerweise bei jedem Prozessor ein etwas anderes Verhalten. Wie auch immer - gar nichts defekt - endlich kann man sich wieder sinnvollen Projekten widmen.

Dank nochmal an alle Ideengeber,

Gruß, Manfred.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)