Forum: Mikrocontroller und Digitale Elektronik MEGA88 springt nicht in Interrupt Routine vom ANACOMP


von Uli R. (uli40)


Lesenswert?

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

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


Lesenswert?

sei(); vergessen?

von MaWin (Gast)


Lesenswert?

> ... aber warum zur Hölle springt er nicht in den Händler.

Könnte rein humanistische Gründe haben.

von Uli R. (uli40)


Lesenswert?

Nö, externe Interrupts und Timer kommen völlig korrekt...

von Uli R. (uli40)


Lesenswert?

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?

von S. Landolt (Gast)


Lesenswert?

> 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)

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


Lesenswert?

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
von Hubert G. (hubertg)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

Was sollen die unformatierten Schnipselchen, damit kann keiner was 
anfangen.
Kompletter Code als Anhang!

von Uli R. (uli40)


Lesenswert?

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.

von Tr (Gast)


Lesenswert?

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.

von Sven K. (svenk)


Lesenswert?

Vielleicht ist Dir irgendwo beim Register setzen vom |= der senkrechte 
Strich abhanden gekommen und Du verlierst Bits.

Gruß Sven

: Bearbeitet durch User
von Uli R. (uli40)


Lesenswert?

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 :-)

von S. Landolt (Gast)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

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.

von S. Landolt (Gast)


Lesenswert?

Das war mir bekannt. Und eben, die Interruptrate scheint hier ja viel zu 
hoch zu sein.

von S. Landolt (Gast)


Lesenswert?

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.

von Uli R. (uli40)


Lesenswert?

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
Noch kein Account? Hier anmelden.