EEPROM lesen im Interrupt

Gast #4037486
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
Gast #4037488
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 ]
Gast #4037496
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.
Gast #4037500
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?
Gast #4037514
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.
Gast #4037531
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.
Gast #4037549
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.
Gast #4037565
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.
Moderator Persönliche Seite #4037587
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
}
Gast #4037618
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.
#4037632
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.
#4038314
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.
#4038321
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).
Moderator Persönliche Seite #4038371
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.
Gast #4038435
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.
(Firma: matzetronics) #4038575
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).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren