Forum: Mikrocontroller und Digitale Elektronik EEPROM lesen im Interrupt


von Ahnungsloser (Gast)


Lesenswert?

Hallo zusammen,

habe mit meinem AVR (ATMega644PA) ein kleines Problem, dass ich nicht 
gelöst bekomme.

Folgendes:
Wenn ich einen Block mit der Funktion "eeprom_read_block" aus dem EEPROM 
lesen funktioniert alles einwandfrei.
Wenn ich aber diese Funktion innerhalb eines Interrupt verwende, dann 
werden alle Pins am PORT C zu Null. Am Port C hängen Relais, die dann 
alle abfallen.
Hab auch schon gegoogelt, finde aber nichts in der Richtung.
Der Controller macht auch keinen RESET und der Watchdog schlägt auch 
nicht zu.
Kann mit das Verhalten überhaupt nicht erklären.

Hatte von euch schon mal jemand so ein Verhalten?

Gruß und Danke

: Bearbeitet durch User
von Ahnungsloser (Gast)


Lesenswert?

Ahnungsloser schrieb:
> Hallo zusammen,
>
> habe mit meinem AVR (ATMega644PA) ein kleines Problem, dass ich nicht
> gelöst bekomme.
>
> Folgendes:
> Wenn ich einen Block mit der Funktion "eeprom_read_block" aus dem EEPROM
> lesen funktioniert alles einwandfrei.
> Wenn ich aber diese Funktion innerhalb eines Interrupt verwende, dann
> werden alle Pins am PORT C zu Null. Am Port C hängen Relais, die dann
> alle abfallen.
> Hab auch schon gegoogelt, finde aber nichts in der Richtung.
> Der Controller macht auch keinen RESET und der Watchdog schlägt auch
> nicht zu.
> Kann mit das Verhalten überhaupt nicht erklären.
>
> Hatte von euch schon mal jemand so ein Verhalten?
>
> Gruß und Danke

Sorry habe gerade gemerkt, dass ich die Überschrift falsch betitelt 
habe.
Es muss heißen: EEPROM lesen im Interrupt.

Sorry

[ Mod: ich hab den Titel mal geändert ]

: Bearbeitet durch User
von Ingo (Gast)


Lesenswert?

Ahnungsloser schrieb:
> Watchdog schlägt auch nicht zu.
Sicher? EEPROM lesen dauert etwas. Wie schnell kommen denn deine 
Interrupts?
Code zeigen!

von holger (Gast)


Lesenswert?

Ahnungsloser schrieb:
> dann
>> werden alle Pins am PORT C zu Null. Am Port C hängen Relais, die dann
>> alle abfallen.
>> Der Controller macht auch keinen RESET

Das sieht aber ganz danach aus das er genau das tut.

von npn (Gast)


Lesenswert?

Ahnungsloser schrieb:
> Hatte von euch schon mal jemand so ein Verhalten?

Ja, und zwar in der Zeile 42...

von Ahnungsloser (Gast)


Lesenswert?

Ingo schrieb:
>> Watchdog schlägt auch nicht zu.
> Sicher? EEPROM lesen dauert etwas. Wie schnell kommen denn deine
> Interrupts?
> Code zeigen!

Ganz sicher, der Watchdog kommt nicht!
Das ganze passiert auch wenn ich nur einen einzelnen Interrupt auslöse 
und in dem das EEPROM auslese. Der Port C wird komplett abgenullt.
Ich werde noch verrückt.

P.S. Der Block ist 4 Byte lang. Es passiert aber auch bei einem oder 8 
Bytes.

Ich muss mal kucken, ob ich den Code so zusammen stutzen kann, dass ihr 
etwas mit anfangen könnt.

von Ahnungsloser (Gast)


Lesenswert?

holger schrieb:
> Das sieht aber ganz danach aus das er genau das tut.

War auch meine Vermutung, aber er tut es nicht. Alle anderen Ports sind 
auch nicht betroffen. Nur Port C.

von npn (Gast)


Lesenswert?

Ahnungsloser schrieb:
> Ich muss mal kucken, ob ich den Code so zusammen stutzen kann, dass ihr
> etwas mit anfangen könnt.

Danke. Das wollte ich hören :-)
Schau aber auch, daß in der gestutzten Version der Fehler auch auftritt! 
Einmal compilieren und testen vor dem Posten bitte.

von Ingo (Gast)


Lesenswert?

Ahnungsloser schrieb:
> Ganz sicher, der Watchdog kommt nicht!
Denk mal drüber nach wann du den WDT zurücksetzt (sofern du ihn 
überhaupt aktiviert hast, weiß ja keiner) und wie lange deine ISR 
blockiert wird mit dem Lesen des EEPROMs. Was ist mit den Anderen IOs?

Hast du evtl. ne wackelige VCC oder die BOD zu "scharf" eingestellt?
100nF da wo sie hin sollen?

von Ahnungsloser (Gast)


Lesenswert?

Ingo schrieb:
> Ahnungsloser schrieb:
>> Ganz sicher, der Watchdog kommt nicht!
> Denk mal drüber nach wann du den WDT zurücksetzt (sofern du ihn
> überhaupt aktiviert hast, weiß ja keiner) und wie lange deine ISR
> blockiert wird mit dem Lesen des EEPROMs. Was ist mit den Anderen IOs?
>
> Hast du evtl. ne wackelige VCC oder die BOD zu "scharf" eingestellt?
> 100nF da wo sie hin sollen?

Ja ich bediene den Watchdog. Er ist gerade auf 2s eingestellt. Der BOD 
ist bei 2,7V. Die Versorgung habe ich schon mehrmals mit dem Oszi 
beobachtet, da tut sich nichts bei dem Lesevorgang. Und direkt an jedem 
Versorgungspin sind 100nF. Ich habe auch den PullUp am Resetpin nicht 
vergessen.
Das Lesen von 4 Bytes aus dem EEPORM geht auch schneller als gedacht. 
Ich kann ja mal versuchen die genau Zeit des Interrupts zu messen.
Meine komplette Programmlaufzeit liegt etwa bei 50µs, also völlig i.O.

von Oliver S. (oliverso)


Lesenswert?

Ahnungsloser schrieb:
> Ganz sicher, der Watchdog kommt nicht!

Wie lang ist denn der Watchdog-Zyklus?

Oliver

von Ahnungsloser (Gast)


Lesenswert?

Der Interrupt wird übrigens von einem Timer im festen Zeitraster von 
10ms ausgelöst.

ISR (TIMER2_OVF_vect)
{
    eeprom_read_block(dev_info, &DevInfo, sizeof(TS_DEV_INFO));
}

von Ahnungsloser (Gast)


Lesenswert?

Oliver S. schrieb:
> Wie lang ist denn der Watchdog-Zyklus?

2s

von Falk B. (falk)


Lesenswert?

Denn EEPROM lesen geht fix, dauer pro Byte um die 4 Takte + 
Verwaltungskram. Sprich, dein 4 Byte Block ist in vielleicht 30-40 
Takten gelesen. Das ist gar nix.

Ausserdem, warum muss man alle 10ms die exakt gleichen Daten aus dem 
EEPROM lesen?

von Ahnungsloser (Gast)


Lesenswert?

Falk Brunner schrieb:
> Ausserdem, warum muss man alle 10ms die exakt gleichen Daten aus dem
> EEPROM lesen?

Mach dir keine Gedanken, das ist gekürzt für Tests. Es ist aber egal wie 
viele Bytes ich lese. Es ist auch egal welche. Und auch in welchem 
Interrupt. Ich habe immer das selbe Verhalten, dass PORTC abgenullt 
wird. Alle anderen PORTs bleiben unberührt.

von Route_66 H. (route_66)


Lesenswert?

Ahnungsloser schrieb:
> Wenn ich aber diese Funktion innerhalb eines Interrupt verwende, dann
> werden alle Pins am PORT C zu Null.

ALLE oder nur die, die zum JTAG gehören?

von Falk B. (falk)


Lesenswert?

Kann es sein, das im Hauptprogramm noch EEPROM-Zugriffe erfolgen und die 
sich mit den Zugriffen in der ISR überschneiden?

von Peter D. (peda)


Lesenswert?

Ahnungsloser schrieb:
> eeprom_read_block(dev_info, &DevInfo, sizeof(TS_DEV_INFO));

Was soll diese Aufzählung von 3 Unbekannten?
Damit kann keiner was anfangen.

von Ahnungsloser (Gast)


Lesenswert?

Route 66 schrieb:
> ALLE oder nur die, die zum JTAG gehören?

Alle, aber guter Einwand.

Falk Brunner schrieb:
> Kann es sein, das im Hauptprogramm noch EEPROM-Zugriffe erfolgen und die
> sich mit den Zugriffen in der ISR überschneiden?

Ich hab das Programm so zusammen gestutzt, dass nur dieser Interrupt 
ausgeführt wird, sonst nichts.

Peter Dannegger schrieb:
> Was soll diese Aufzählung von 3 Unbekannten?
> Damit kann keiner was anfangen.

Ja Sorry du hast Recht.
Aber für diese Unbekannten kannst du dir denke was du willst, ich hab 
schon alles probiert. Auch wenn ich nu ein Byte lese, passiert das 
besagte.

von Falk B. (falk)


Lesenswert?

Kann es sein, dass der falsche Prozessortyp im Compiler eingestellt ist 
und der Zugriff auf falsche IO-Register erfolgt?

Lass man nur ein IO mit LED toggeln, um zu sehen, dass der Interrupt 
läuft (ggf. mit Softwareteiler, damit man es blinken statt flimmern 
sieht).

von Ahnungsloser (Gast)


Lesenswert?

Falk Brunner schrieb:
> Kann es sein, dass der falsche Prozessortyp im Compiler eingestellt ist
> und der Zugriff auf falsche IO-Register erfolgt?

Also da steht ATMega644PA. Aber vielleicht liegt da wirklich das 
Problem. Eventuell macht der Compiler etwas falsch.

Falk Brunner schrieb:
> Lass man nur ein IO mit LED toggeln, um zu sehen, dass der Interrupt
> läuft (ggf. mit Softwareteiler, damit man es blinken statt flimmern
> sieht).

Der Interrupt läuft, dass habe ich mit einem Pin probiert. In jedem 
Interrupt habe ich den Pin invertiert. Es hat alles perfekt 
funktioniert.
Wenn ich allerdings einen Pin am PORTC nehme und die EEPORM-Leseroutine 
benutze, dann gehts nicht. Der PORTC wird einfach überschrieben.

von Ahnungsloser (Gast)


Lesenswert?

Ach übrigens, den Controller habe ich auch schon getauscht. Gleiches 
Problem!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ahnungsloser schrieb:
> Eventuell macht der Compiler etwas falsch.

In 99,9% der Fälle macht der nix falsch.

Such besser bei Dir selber.

Formuliere folgenden Pseudocode aus:
1
ISR ()
2
{
3
  eeprom_auslesen();
4
}
5
6
main ()
7
{
8
   timer_init ();
9
   PORT_C_auf_ausgang ();
10
   PORT_C = 0xFF;
11
   Benutze_keinen_Watchdog();
12
13
   sei ();
14
15
   while (1)
16
   {
17
      ;
18
   }
19
}

Ich wette, da passiert dann nichts mehr mit PORTC.

Noch etwas: Du solltest Dein Verfahren nochmal überdenken und 
dahingehend abwandeln:
1
static volatile eeflag;
2
3
ISR (..)
4
{
5
  eeflag = 1;
6
}
7
8
main
9
{
10
   ...
11
   while (1)
12
   {
13
      ...
14
      if (eeflag) { eeprom_auslesen(); flag = 0; }
15
      ...
16
   }
17
}

von Nil (nilsnilss)


Lesenswert?

Poste bitte mal deinen gesamten Code, mit diesem "rate rate was ist das" 
kommt man hier selten weiter.

von Ahnungsloser (Gast)


Lesenswert?

Frank M. schrieb:
> static volatile eeflag;
>
> ISR (..)
> {
>   eeflag = 1;
> }
>
> main
> {
>    ...
>    while (1)
>    {
>       ...
>       if (eeflag) { eeprom_auslesen(); flag = 0; }
>       ...
>    }
> }

Genau so habe ich jetzt auch drum herum programmiert. Dann geht 
natürlich alles. Würde es aber trotzdem gerne verstehen.
Also gut, dann fange ich nochmal von vorne an. So wie du es beschrieben 
hast. Ich melde mich, nur heute wirds nix mehr. Muss leider weg.

von Peter D. (peda)


Lesenswert?

Nils Friess schrieb:
> Poste bitte mal deinen gesamten Code, mit diesem "rate rate was ist das"
> kommt man hier selten weiter.

Ja!

Immer diese Schnipseltaktik.
Man kommt sich ja vor, wie mit ner Augenklappe, wo nur ein ganz kleines 
Loch drin ist.
Was ist denn so geheim an einem compilierbaren Code.
Willst Du nicht auch selber wissen, was faul ist?

Ahnungsloser schrieb:
> Genau so habe ich jetzt auch drum herum programmiert. Dann geht
> natürlich alles.

Also vor dem Fehler wegrennen.
Hilft aber nicht lange, der holt Dich bestimmt bald wieder ein.

von Ahnungsloser (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Also vor dem Fehler wegrennen.
> Hilft aber nicht lange, der holt Dich bestimmt bald wieder ein.

Da hast du Recht, darum will ich es ja wissen.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ich hätte gerne mal einen einzigen Grund dafür gewusst, warum man einen 
EEPROM alle 10ms auslesen muss - und das auch noch in einer ISR. Und 
dann hätte ich auch gerne mal für die Frage nach der JTAG Fuse eine 
Antwort.

von Oliver S. (oliverso)


Lesenswert?

Na ja, alle 10ms auslesen ist zwar nicht unbedingt erforderlich, schadet 
aber auch nicht.

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Man mag mich naiv nennen. Aber wie kann sich das interne EEPROM 
verändern, wenn nicht unter Kontrolle des Programms? Und warum kann dann 
derjenige Codeteil nicht gleich die betreffenden Variablen beschreiben 
sondern muss den Umweg übers EEPROM nehmen?

Die Sache mit den Portpins sollte natürlich nicht sein und es ist nicht 
uninteressant, was da eigentlich los ist. Aber das ganze stinkt schon 
nach einem kleinen Problem, hinter dem sich ein noch viel größeres 
Design-Problem versteckt.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Ich hab zwar nur nen ATMega644 ohne PA, aber wenn man endlich mal ein 
compilierbares Programm hätte, wäre es ein Leichtes, das auf dem STK500 
auszuprobieren und die 8 LEDs an PORT C zu hängen.

Dann könnte man sich auch das Listing ansehen, ob es ein Compilerfehler 
ist.

Welcher Compiler und welche Optimierung überhaupt?
Ohne Not sollte man immer -Os verwenden (default).

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
> Man mag mich naiv nennen. Aber wie kann sich das interne EEPROM
> verändern, wenn nicht unter Kontrolle des Programms? Und warum kann dann
> derjenige Codeteil nicht gleich die betreffenden Variablen beschreiben
> sondern muss den Umweg übers EEPROM nehmen?

Vielleicht hat er ja ein EEPROM-Stress-Test-Programm geschrieben ;-)

> Die Sache mit den Portpins sollte natürlich nicht sein und es ist nicht
> uninteressant, was da eigentlich los ist. Aber das ganze stinkt schon
> nach einem kleinen Problem, hinter dem sich ein noch viel größeres
> Design-Problem versteckt.

Sehe ich genauso. Deshalb bat ich ihn ja auch, eine Mini-main() mit 
Mini-ISR() zu veröffentlichen, mit dem er das Problem reproduzieren 
kann.

von Nosnibor (Gast)


Lesenswert?

Karl Heinz schrieb:
> Man mag mich naiv nennen. Aber wie kann sich das interne EEPROM
> verändern, wenn nicht unter Kontrolle des Programms? Und warum kann dann
> derjenige Codeteil nicht gleich die betreffenden Variablen beschreiben
> sondern muss den Umweg übers EEPROM nehmen?

Wer sagt denn, daß der EEPROM-Inhalt sich ändert? Oder daß das 
10ms-EEPROM-Lesen überhaupt im Originalprogramm vorkam und nicht nur in 
der abgespeckten Testversion?

Außerdem war es früher zumindest auf den kleineren Prozessoren üblich, 
Konstantentabellen ins EEPROM zu legen, wenn man das nicht anderweitig 
braucht und Flash knapp ist. Und wenn es sich bei den Konstanten um den 
"Zeichensatz" eines Displays handelt, das man in Software multiplext, 
dann ist ein Lesezugriff alle 10ms, auch im Interruptn gar nicht so 
ungewöhnlich.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Nosnibor schrieb:
> Und wenn es sich bei den Konstanten um den
> "Zeichensatz" eines Displays handelt, das man in Software multiplext,
> dann ist ein Lesezugriff alle 10ms, auch im Interruptn gar nicht so
> ungewöhnlich.

Der Zeichensatz eines Display hat mMn ebenso wenig in einem EEPROM 
verloren - sowas gehört ins Flash.

> Außerdem war es früher zumindest auf den kleineren Prozessoren üblich,
> Konstantentabellen ins EEPROM zu legen

Es ist ein Mega644(!) - nichts, was ich als kleineren Prozessor 
bezeichnen würde. Der Flash ist so gross, das ich da auch 4 Zeichensätze 
unterbringe.

Und auch Performance zählt nicht, denn lt. DB:
> When the EEPROM is read, the CPU is halted for four clock
> cycles before the next instruction is executed.
Ausserdem muss für jedes Lesen des EEPROM die Adresse gesetzt werden (in 
EEARL und EEARH).

von Peter D. (peda)


Lesenswert?

Es ist doch vollkommen wurscht, was und wie oft man aus dem EEPROM 
liest.
Fakt ist, es muß auch im Interrupt funktionieren.

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.