Hallo Experten, ich möchte mit den µController Atmega 128 einen Interrupt ausführen, wenn ich auf eine Taste betätige. Es ist alles richtig angeschlossen, aber der Interrupt wird nicht ausgeführt. Hier die wichtigsten Stellen meines Quellcodes: #include <avr/interrupt.h> .. .. sei(); .. .. ISR(_VECTOR(1)) { DisplayOff(); } .. .. Mit den Ozsi sehe ich das immer ein Signal an den Eingang des Interrupt Pin ankommt wenn ich mein Schalter betätige. Muss ich noch Register Einstellungen vornehmen ? Danke schonmal im Vorraus Patrick
also mit dem codegeschnippsel das du gepostet hast kann dir wohl niemand einen wirklich guten ratschlag geben. und wegen den registereinstellungen.du musst deinen externen interrupt schon irgendwie initialisieren.
das sind aber die einzigsten Stellen, wo ich was mit Interrupt was mache. Ich könnte auch mein ganzen Quelltext einstellen aber da steigt dann keiner mehr durch ;-( Mfg Patrick
Den Interrupt muss man auch initialisieren. Wenn Du das oben für die wichtigsten Stellen des Codes hältst, dann liegst Du schief. Wo ist die lokale Freigabe (Interrupt Enable) und die Flankeneinstellung und...?
@ Travel Rec.: weisst du ob er alle pins nutzt? vielleicht tut er das ja...oder hat sogar 128kb code ;-) @ Patrick: sag das mal lieber nicht das hier keiner deinen code verstehen würde!!! aber wie sollen wir dir bitte mit dem code-auszug da oben helfen? initialisierst du deinen interrupt. sprich...schreibst du irgendwas in die register EICRA, EICRB, EIMSK, EIFR? wenn ja...dann solltest du das auch posten. wirklich sicher das alles richtig angeschlossen ist? ist die funktion "DisplayOff();" wirklich in ordnung? ich weiss grad leider nicht mit welchem prog du arbeitest! meine frage daher: ISR(_VECTOR(1)) ... ist hier die syntax hier richtig?
@ dschedsche and johnny.m Danke, das war der Entscheidene Hinweis. Ich habe keine Intialisierung der Interrupt Register vorgenommen. Nachdem ich EICRA, EICRB, EIMSK intialisert habe funktioniert es einwandfrei ! Danke nochmals :-) Falls es jemanden helfen sollte mein Code: int main (void) { sei(); // Interrupt einschalten DisplayOn(); DisplayInit(1); D_DIR =0x30; D_OUT =0x30; D_IN =0x0F; D_OUT|=0x30; EICRA|=(1<<ISC00); // INT0 EICRA|=(1<<ISC01); EICRA|=(1<<ISC10); // INT1 EICRA|=(1<<ISC11); EICRA|=(1<<ISC20); // INT2 EICRA|=(1<<ISC21); EICRA|=(1<<ISC30); // INT3 EICRA|=(1<<ISC31); EIMSK|=(1<<INT0); // unmask Interrupt 0 EIMSK|=(1<<INT1); EIMSK|=(1<<INT2); EIMSK|=(1<<INT3); while(1){} } // Interrupt Service Routinen ISR(INT0_vect) // _VECTOR(1) { WriteSentence("Interrupt 0 ",8,1); ClearDisplay(0,0x00,1); } ISR(INT1_vect) { WriteSentence("Interrupt 1 ",16,1); } ISR(INT2_vect) { WriteSentence("Interrupt 2 ",24,1); } ISR(INT3_vect) { WriteSentence("Interrupt 3 ",32,1); } ------- Patrick
Wenn das alles Taster sind, ist das noch vertretbar. Allerdings haben Ausgabefunktionen (ich vermute mal, dass "WriteSentence" irgendwas über eine Schnittstelle an ein Display o.ä. ausgibt) in einer ISR normalerweise nix verloren. Spätestens dann, wenn irgendwelche Zeitkritischen Sachen dazukommen, musst Du die Ausgabefunktionen ins Hauptprogramm verlagern, da diese i.d.R. (v.a. bei Ausgabe über serielle Schnittstellen) vergleichsweise viel Zeit brauchen und Warteschleifen enthalten. Während der Ausführungszeit der ISR ist aber das komplette System blockiert, so dass auch andere Interrupt-Quellen (z.B. Timer oder andere Schnittstellen) nicht bearbeitet werden können, was zu Fehlfunktionen (Timer-Interrupts) oder sogar Datenverlust (Schnittstellen) führen kann. Außerdem ist es i.d.R. nicht sinnvoll, Taster über externe Interrupts abzufragen. Es gibt viele Beispiele, wie man Taster zyklisch über einen Timer-Interrupt alle paar zig Millisekunden abfragen kann, inklusive vernünftige Entprellung. Die externen Interrupts dafür zu verwenden ist eigentlich Verschwendung.
Ich bitte um Hilfe. Ich habe ein Problem mit einem ATMEGA 128 und dem INT2 am PD2 --> Funktion aber großen Stromfluss. Am INT3 / PD3 betreibe ich einen DCF Empfänger. Der funktioniert wie erwartet. Am INT2 möchte ich ein KeyPad betreiben. Die Initialisierung habe ich für INT3 und INT2 in gleicher Weise auf fallende Flanke. Der Interrupt arbeitet wie erwartet, jedoch fliesst ein Stom von ca. 35mA vom PD2 nach Richtung GND. Bemerkt habe ich das "Problem" als ich mit dem Oszilloskop prüfen wollte ob der Interrupt Ausgang bei jeder Taste wirklich kommt. Dabei habe ich 1,2V Spannung am PD2 gemessen und weiter untersucht, weil ich mit max. etwa 0,7V gerechnet hätte. Der Auslöser für den INT2 ist der TWI 8-Bit Port Expander PCF8574. Wenn das Keypad betätigt wird, dann löst der IRQ des PCF8574 wie erwartet aus. Ich bekomme den Stromfluss nicht in den Griff ! Ich habe schon (obwohl ich das beim PD3 nicht mache, und den grossen Stromfluss nicht habe): 1. Den PD2 als EIngang definiert 2. Den PD2 Pull-Up Widerstand abgeschalten 3. Im AVR-Simulator / I/O Viewer geprüft, ob "jemand" die Einstellung unter DDRD, PORTD verstellt. 4. Eine ungewollte elektrische Verbindung schließe ich aus, da ich mit einem Oszilloskop die erwarteten 5V messe, so lange der PCF8574 keinen IRQ auslöst. Die Einstellung ist (Breakpoint in der ISR) wie beim INT3 wie erwartet beides Low. Den RXD1 habe ich nicht als serielle Schnittstelle initialisiert. Ich Programmiere mit AVR Studio 4.16 Build 638 und GNU Compiler in C. Sehr merkwürdig finde ich, dass die ISR für INT2 angesprungen wird. Das habe ich sowohl im AVR-Studio in der Simulation, wie auch in der Wirklichkeit. Deshalb die Frage: Hat der PD2 irgendeine Sonderfunktion, die noch abgeschalten werden muss ? Wenn ja wie ?
> Ich bitte um Hilfe. In einer sechsjahrealten Diskussion? > ATMEGA 128 Wird der auch als Atmega128 betrieben oder ist er noch im Werkszustand d.h. seine M103C Fuse ist noch gesetzt und er ist ein verboozter Atmega103
Ja, ich habe gedacht, dass dieser Beitrag am besten zu meiner Frage passt. Für Gegenvorschläge bin ich offen, und berichte gerne in einem anderen Beitrag, falls dieser passender sein sollte. Ich habe in diesem Forum schon viel - auch von sehr alten Beiträgen - gelernt. Zur Frage: Ich betreibe den ATMEGA 128 als solchen. Im ATMEL Studio ist unter: Tools - Program AVR - Auto Connect - Fuses: die Option nicht M103 markiert. Ich compiliere auch mit der Einstellung: Project-Configuration Options-Device: mit "atmega128". Die programmierten Funktionen: LCD, KeyPad, TWI, DCF, UART und das Hauptprogramm funktionieren. Ich kann ja auch den IRQ auslösen. Das erkenne ich daran, das ich bei jedem INT2 eine LED toggle. Initialisiert wird der INT 2 mit: EICRA |= (1<<ISC21) | (0<<ISC20); // fallende Flanke EIMSK |= (1<<INT2); // Int einschalten sei(); // enable global interrupt Den PD2 schalte ich zu Versuchszwecken auf Eingang und den Pull-up aus: DDRD = &= ~(1<<PD2); // Eingang PORTD = &= ~(1<<PD2); // Pull Up aus Für mich nicht erklärbar ist die Situation, dass der PD2 trotzdem +5V liefert !? Ich habe keinen externen Widerstand angeschlossen. Das Verifiziere ich indem ich den Draht zu dem PD2 unterbreche, dann habe ich auch die erwarteten 0V am IRQ des PCF874. Die Fuse "SPIEN" ist markiert, Brown-out bei 2,7V, Ext. Cristal 16K CK + 4ms, BOOTSZ=512 words start address=$FE00. Ansonsten alle Checkboxen nicht markiert. Grundsätzliche Fehler hier hätte ich auch nicht erwartet, da ja der INT3 ohne großen Stromfluss funktioniert. INT0 und INT2 sind durch HW TWI Funktion initialisiert und stehen nicht für externe Interrupts zu Verfügung.
Heute habe ich in Richtung des ATMEGA128 gemessen, ob ggf. eine Beschaltung auf dem Prozessor-Board einen relativ kleinen Pull-Up Widerstand hat. Ich konnte bei spannungsloser Schaltung weder nach GND und auch nicht nach +5V einen relativ kleinen Wiederstand messen, d.h. in beide Richtungen >200kOhm. Den angeschlossenen Programmer habe ich auch abgesteckt. Keine Veränderung an dem Stromfluss. Ich weiß nun nicht mehr wo der Strom herkommen soll, wenn nicht aus dem PD2 Pin. Nur dass es keinen offensichtlichen Grund dafür gibt.
>Den PD2 schalte ich zu Versuchszwecken auf Eingang und den Pull-up aus: >DDRD = &= ~(1<<PD2); // Eingang >PORTD = &= ~(1<<PD2); // Pull Up aus So bestimmt nicht. Da haut dir der Compiler eins um die Ohren. Such nach allen Stellen die DDRD bearbeiten.
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.