Hallo Leute, ich verzweifle, und brauche bitte, bitte Hilfe um einen vielleicht total blöden Fehler zu finden, bin echt am Ende :-) Ich habe ein Projekt, dass auf einem TINY44 wunderbar läuft, muss jetzt aber wegen Codegröße umsteigen und habe mich für einen MEGA88PA (brauche auch ein UART) Als IDE benutze ich AVR Studio 7 und auch CodeVision AVR für andere Projekte. Hier aber nur GCC Projekt. Somit portiere ich alles Schritt für Schritt, auch schon ein paar neue Codeblöcke und neue Variablen, Timer und externe Interrupts laufen auch ohne Problem, nur der blöde Analog Comparator will nicht in den Interrupt Handler springen. Die Interrupt Routine sollte doch das sein, oder? ISR (ANALOG_COMP_vect) { } Ich kann den Comparator Output ACO und auch das Interrupt Flag ACI per Polling abfragen, kommt korrekt, aber er springt einfach nicht in den Handler. Initialisierung sieht so aus: // Analog Comparator initialization // Analog Comparator: On // The Analog Comparator's positive input is // connected to the AIN0 pin // The Analog Comparator's negative input is // connected to the AIN1 pin // Interrupt on Rising Output Edge // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=(0<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (1<<ACIE) | (0<<ACIC) | (1<<ACIS1) | (1<<ACIS0); // Digital input buffer on AIN0: Off // Digital input buffer on AIN1: Off DIDR1=(1<<AIN0D) | (1<<AIN1D); Wie gesagt, ich kann das Flag pollen, aber warum zur Hölle springt er nicht in den Händler. AVR Studio nimmt beim Projekt auch automatisch die iom88pa.h, die Definition sieht auch korrekt aus: #define ANALOG_COMP_vect _VECTOR(23) /* Analog Comparator */ Mache ich irgend einen dummen Fehler, ist mein erstes Projekt mit dem Mega88. Wäre super dankbar für ein paar Ideen... lg. Uli
> ... aber warum zur Hölle springt er nicht in den Händler.
Könnte rein humanistische Gründe haben.
Nö, externe Interrupts und Timer kommen völlig korrekt...
Ich suche und suche, aber es macht für mich echt keinen Sinn. Der UART läuft auch, daher lassen sich jetzt etwas besser Daten raus lesen. Wenn ich in die Main Schleife das hier einbaue: if (ACSR & 0x10) { UDR0=ACSR; ACSR=ACSR|0x10; //manuell löschen } Bekomme ich tadellos die Flags und auch die Bestätigung am UART, dass das ACI Flag da ist, also 0x1B als Antwort (ich muss das Flag auch manuell löschen, sonst meldet er endlos die Interrupts auf diese Art. Auch wenn ich die ISR (ANALOG_COMP_vect) komplett raus nehme und gar nicht mit kompiliere, kommt es zu keinem Fehlverhalten, er springt einfach trotz dem Interrupt Flag nicht in den Händler und löscht damit auch nicht das Interrupt Flag in der Hardware. Wenn man so komisches Verhalten hat, denkt man ja immer gleich ob es vielleicht nen Hardwarefehler gibt. Habe auch schon den Chip getauscht, aber gleiches Ergebnis. Es kann doch nicht sein, dass der hier verwendete MEGA88PA, also der PA Typ da irgendeine Sonderheit hat?
> Ich suche und suche Seit gestern Abend... Ich verstehe die Vorgehensweise nicht, es sollte doch ein Leichtes sein, binnen zehn Minuten mit einem Einfachstprogramm die AC-ISR eine LED schalten zu lassen, und auf dieser Grundlage den Fehler zu finden bzw. dann weiterzumachen. Wozu wird da ein UART benötigt? (Und nein, konkret kann ich nicht helfen, ich habe nur zwei steinalte ATmega88-20PU)
Es gibt ein bekanntes Erratum, wenn man ACME in ADCSRB setzt (und damit für AIN1 den AD Multiplexer verwendet): " 35.4 Errata ATmega88PA The revision letter in this section refers to the revision of the ATmega88PA device. 35.4.1 Rev. F • Analog MUX can be turned off when setting ACME bit 1. Analog MUX can be turned off when setting ACME bit If the ACME (Analog Comparator Multiplexer Enabled) bit in ADCSRB is set while MUX3 in ADMUX is '1' (ADMUX[3:0]=1xxx), all MUX'es are turned off until the ACME bit is cleared. Problem Fix/Workaround Clear the MUX3 bit before setting the ACME bit." Das ist übrigens das einzige bekannte Problem bei der Mega48 - Mega 328 Serie, zumindest bis zum 5/11 Stand des Datenblattes. Wenn vorhanden, kompilier mal für den 168PA oder den 328PA.
:
Bearbeitet durch User
Uli R. schrieb: > Mache ich irgend einen dummen Fehler, ist mein erstes Projekt mit dem > Mega88. Wäre super dankbar für ein paar Ideen... Nachdem die Initialisierung OK erscheint, muss doch der Fehler im Rest des Programms sein?
Was sollen die unformatierten Schnipselchen, damit kann keiner was anfangen. Kompletter Code als Anhang!
Hi, Also die Idee mit dem Einfachstprogramm hatte ich in der Form noch nicht, ist wahr. Kurz gemacht, und ja, da funktioniert es, hätte ich auch drauf kommen können. ABER das hilft noch nicht ganz so viel, weil ich an dem ganzen Programm über Wochen gewachsen ist, soweit alles andere geht, nur eben dieser eine Interrupt nicht ausgeführt wird - alle anderen aber schon. Ich werde jetzt dann wohl mal Block für Block kopieren und gucken wann es nicht mehr geht, ist logisch nicht ganz leicht, wird was dauern... Hat auch kaum Sinn hier hier über Tausend Zeilen vom Gesamtcode zu posten. Daher denke ich immer noch an einen dummen Fehler zwischen meinen Ohren... Aber woher kann es den kommen, dass die ISR in einem Einfachstprogramm aufgerufen wird (alle anderen ISRs sind auch da und auch gleich initialisiert), aber im Hauptprogramm nicht. Macht der Kompiler Unterschiede bei der Reihenfolge von Funktionen und ISRs? Kann doch nicht, oder? Ach ja, das Errata ist bekannt, nutze aber den MUX nicht.
Vergleiche die Unterschiede zwischen den Programmen und achte dabei auf die Register. Vielleicht passiert auch irgendwas im Hintergrund (ADC Kanalwechsel o.ä.) bei dem du versehentlich die Konfiguration änderst oder die Flags löscht. Lass das Programm mal im Simulator laufen und schau was tatsächlich im Konfig Register steht.
Vielleicht ist Dir irgendwo beim Register setzen vom |= der senkrechte Strich abhanden gekommen und Du verlierst Bits. Gruß Sven
:
Bearbeitet durch User
Ja Simulator hatte ich gesten auch schon laufen, ist bei komplexeren Programmen mit äußeren Einflüssen halt kaum möglich was zu sagen. ABER ich glaube ich habs gefunden, Fehler zwischen den Ohren, eh klar - aber für fortgeschrittene Deppen: Ich verwende bei dem Projekt erstmals den UART auf einer BUS Leitung, also alles was ich sende empfange ich auch. In der aktuell einfachen Realisierung hab ich noch kein MAC Protokoll vorgesehen. Daher komme ich beim einfachen Senden kleiner Infowerte scheinbar in einen Livelock der UART Interrupts. Der Analog Komparator hat geringere Priorität, die anderen Timer und externen IRQ haben höhere Priorität - daher läuft das Programm eigentlich normal, aber eben der eine, niedrige IRQ kommt nicht mehr... Ich denke,... hoffe das war es. Danke für den Gedankenaustausch :-)
Klingt merkwürdig, das würde bedeuten, dass der Controller hoffnungslos überlastet ist, da er nur noch die höheren ISRs bedienen kann, oder sehe ich das falsch?
Die AVRs machen wie die 8051 immer mindestens einen Befehl der Mainloop zwischen 2 Interrupts. D.h. das Main läuft immer, auch wenn die Interrupts viel zu schnell kommen. So kann es sein, daß man eine zu hohe Interruptrate nicht immer sofort merkt.
Das war mir bekannt. Und eben, die Interruptrate scheint hier ja viel zu hoch zu sein.
Wenn ich den Gedankengang fortspinnen darf, vielleicht hilft es ja auch dem Fragenden: Irgendwann, eher früher als später, reicht die Zeit nicht mehr, um die höherwertigen Interrupts fristgerecht zu bedienen, und das hätte doch auffallen müssen. Außerdem scheint es sich ja nicht um ein Anfängerprojekt zu handeln, wir dürfen also davon ausgehen, dass Uli Ro sich im Vorfeld Gedanken gemacht hat über die benötigte Controller-Leistung. Also mir ist die Sache noch nicht klar.
Hi, Also, ich hatte zum Debugging einfach eine Konstante auf dem UART ausgegeben um zu sehen, ob ein Teil der Schleife angesprungen wird. So beim Analog Komparator, aber auch beim UART. Jetzt war es schon klar, dass der Transmit IRQ kommt, in der Routine war auch nichts. Beim Empfangs UART war aber schon was drinnen - durch die Wired-OR für die Busleitung hat jetzt aber jedes gesendete Byte ein neues Byte in dem Empfangs IRQ gesendet, und diese dann wieder ein neues... Komisch ist nur, dass mir das erst jetzt aufgefallen ist. Nachdem ich jede Menge Daten auf dem UART bekommen habe war es dann plötzlich klar. Ich bin nicht ganz sicher, warum es vorgestern weder funktionierte, noch diese Datenflut kam. Ein bisschen komisch bleibt es also in der Erinnerung. Durch das viele Testen und Suchen ist es aber ein bisschen im Nebel. Und ja, es gibt schon einige Interrupts von Timern und auch Extern, die sind aber nicht sehr zeitkritisch. Noch dazu läuft das Hauptprogramm eh im Main, eh klassisch asynchron. Deswegen ist es wohl auch nicht aufgefallen, alles lief noch "ziemlich" normal - mit der Erkenntnis jetzt, erklärt sich aber auch ein Performance-Flackern, dass ich gestern mal hatte (da dachte ich aber an ein falsch eingestelltes, gewolltes Delay)
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.