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
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
Ahnungsloser schrieb: > Watchdog schlägt auch nicht zu. Sicher? EEPROM lesen dauert etwas. Wie schnell kommen denn deine Interrupts? Code zeigen!
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.
Ahnungsloser schrieb: > Hatte von euch schon mal jemand so ein Verhalten? Ja, und zwar in der Zeile 42...
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.
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.
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.
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?
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.
Ahnungsloser schrieb: > Ganz sicher, der Watchdog kommt nicht! Wie lang ist denn der Watchdog-Zyklus? Oliver
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)); }
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?
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.
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?
Kann es sein, das im Hauptprogramm noch EEPROM-Zugriffe erfolgen und die sich mit den Zugriffen in der ISR überschneiden?
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.
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.
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).
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.
Ach übrigens, den Controller habe ich auch schon getauscht. Gleiches Problem!
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 | }
|
Poste bitte mal deinen gesamten Code, mit diesem "rate rate was ist das" kommt man hier selten weiter.
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.
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.
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.
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.
Na ja, alle 10ms auslesen ist zwar nicht unbedingt erforderlich, schadet aber auch nicht. Oliver
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
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
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.
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.
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).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.