Hallo, ich habe ein Problem mit dem externen INT2 vom Mega32. ich habe folgendes an code: Externer INT0 und INT1 funktionieren, was mache ich falsch?? ... // globale interrupt register INT0 - INT2 einschalten GICR |= (1<<INT0); // enable INT0 - PD2 GICR |= (1<<INT1); // enable INT1 - PD3 GICR |= (1<<INT2); // enable INT2 - PB2 // INT2 fallend Flanke MCUCSR |= (1<<ISC2); ... /* ** Interrupt routine für externen INT2 - PB2 */ ISR(INT2_vect) { TxUart("INT2\r\n"); } ... sei(); Globale interrupts einschalten ....
Das einzige, was in den paar Zeilen auffällt, ist der falsche Kommentar in > // INT2 fallend Flanke > MCUCSR |= (1<<ISC2); Oliver
Hi Oliver, dann berichtige mich doch bitte. Habe ja um Hilfe gebeten, weil ich das nicht ganz verstehe. Ist denn ansonsten alles richtig und komplett, was man benötigt um INT2 abzufragen?? Zur Beschaltung: Taster an einer Seite an Masse und die andere halt am INT2.
Datenblatt S.67:
1 | If ISC2 is written to one, a rising edge on INT2 activates the interrupt. |
... Ok, berichtigt: // INT2 steigende Flanke MCUCSR |= (1<<ISC2); bekomme aber trotz dem keinen Interrupt. Muss ich noch etwas anderes ein-/ausschalten? Was ist mit AINT0 ?? Hoger ...
>bekomme aber trotz dem keinen Interrupt.
Woran merkst du das denn?
Funktioniert das TxUart() auch, wenn es dank Tasterprellen mehrfach
hintereinander aufgerufen wird, auch wenn dabei noch nicht mal das
allererste Zeichen über die Schnittstelle gegangen ist?
Ansonsten, wie eigentlich immer: zeig mal das ganze Programm, nicht nur
die Zeilen, in denen du den Fehler vermutest. Denn in 99% der Fälle
steckt der Fehler ganz woanders.
Oliver
Hallo Oliver, hier mal ein komplett abgespecktes Teil. Funzt Totzdem nicht ! #include "main.h" /* ** delay ms routine */ void dms(unsigned int ms) { unsigned int zaehler; while (ms) { zaehler = F_CPU / 5000; while (zaehler) { asm volatile ("nop"); zaehler--; } ms--; } } /* ** delay ys routine */ void dus(unsigned int us) { if (us < 4) return; if (us < 20) us-= 3; while (us) { asm volatile ("nop"); us--; } } void Beep(u08 count, unsigned int le) { u08 i; for(i= 0;i < count; i++){ sbi(BUZZER_PORT, BUZZER_PIN); dms(le); cbi(BUZZER_PORT, BUZZER_PIN); dms(le); } } /* ** initializing */ void Init(void){ // init buzzer PIN sbi(BUZZER_DDR, BUZZER_PIN); // as output cbi(BUZZER_PORT,BUZZER_PIN); // Pin is low //### GLOBAL INTERRUPT CONTROLLER ### // enable disable the interrupts over // the global control register GICR |= (1<<INT0); // enable INT0 - PD2 GICR |= (1<<INT1); // enable INT1 - PD3 GICR |= (1<<INT2); // enable INT2 - PB2 // INT2 fallende Flanke MCUCSR&= ~(1<<ISC2); //### SET SLEEP MODE ### // SLEEP_MODE_IDLE // SLEEP_MODE_PWR_DOWN set_sleep_mode(SLEEP_MODE_PWR_DOWN); //### INTERRUPT PINS INITIALIZATION ### // as input to read from any key // INT0 cbi(DDRD, PD2); // input for read sbi(PORTD,PD2); // set pullups // INT1 cbi(DDRD, PD3); // input for read sbi(PORTD,PD3); // set pullups // INT2 cbi(DDRB, PB2); // input for read sbi(PORTB,PB2); // set pullups // wachdog enable 2 secounds //wdt_enable(WDTO_2S); } /* ** INT0 - PD2 */ ISR(INT0_vect) { Beep(3, 500); while ( bit_is_clear(PIND, PD2)){ dms(1); } gSleepCnt= 0; return; } /* ** INT1 - PD3 */ ISR(INT1_vect) { Beep(5, 500); while ( bit_is_clear(PIND, PD3)){ dms(1); } gSleepCnt= 0; return; } /* ** INT2 - PB2 */ ISR(INT2_vect) { Beep(8, 500); while ( bit_is_clear(PINB, PB2)){ dms(1); } gSleepCnt= 0; return; } /* **############# MAIN ########################### */ int main(void) { u08 gMainDelay; Init(); sei(); Beep(3,200); // init buzzer PIN sbi(BUZZER_DDR, BUZZER_PIN); // as output cbi(BUZZER_PORT,BUZZER_PIN); // Pin is low // init member gMainDelay = 1; // 1 ms delay gSleepDelTime = 3000; // 3 secounds gSleepCnt = gSleepDelTime; // now to sleep wdt_disable(); //###################################################################### ######### //### Main Loop function //###################################################################### ######### for (;;) { //#### // tue irgend was .... //### sleep if (gSleepCnt >= gSleepDelTime) { gSleepCnt= 0; dms(1); sei(); Beep(1,1); sleep_mode(); } // increment the sllep counter gSleepCnt++; // main delay dms(gMainDelay); }// for (;;) }
**GlaskugelModus An** Am Int2 Pin fehlt der PullUp-Widerstand. **GlaskugelModus Aus** Ein Schaltplan wäre von Vorteil.
Ja, hätte ich dazuschreiben sollen Anschlussplan: Taster _ _|_ GND -------| |----+---| 1 Kilo |----------->> +5V | | | --- |xxx| <<--- INT2 PB2 ---
>hier mal ein komplett abgespecktes Teil. Sicher? Bei mir fangen AVR-Programme eigentlich immer mit
1 | #include <avr/io.h> |
an. Zeig doch mal was kompilierbares. Und in der avr-libc gibt es wunderschöne delay-Funktionen. Die funktionieren sogar :-) Oliver
Oliver, ich habe jetzt mal das kleine Testprog angehangen. Eventuell kannst du ja den / die Fehler erkennen. Danke vorab für dein Bemühen. Mario..
Fehler sehe ich erstmal nicht, aber externer Interrupt mit einem mechanischen Taster ist ein rotes Tuch. ISR mit einem delay drin ebenfalls. Du hast das Pferd irgendwie von hinten aufgezäumt. Mechanische Taster fragt man im `heartbeat'-Timer-Interrupt ab, in dem man auch die Entprellung macht. (Den IRQ würde ich wohl via JTAG debuggen wollen, wenn ich das Problem hätte.)
Also, in der Simulation in VMLAB springt er in die ISR2, wie erwartet. Aber die delay-Funktionen sind arg seltsam. Nimm doch die aus der avrlibc. Oliver
Hallo, bin wieder da. Erst einmal vielen Dank für die Hilfe. Meine Hardware habe ich überprüft, alles soweit ok. Delay Funktion werde ich tauschen. Hat von Euch einer einen Code-Schnipsel mit dem ich es doch eventuell testen kann? Jörg, wie sieht denn solch eine Abfrage der Taster aus, wenn der Controller im Sellep Mode ist - set_sleep_mode(SLEEP_MODE_PWR_DOWN) und er durch den Taster aufgweckt werden soll??
Holger Patz schrieb: > Jörg, wie sieht denn solch eine Abfrage der Taster aus, wenn der > Controller im Sellep Mode ist - set_sleep_mode(SLEEP_MODE_PWR_DOWN) und > er durch den Taster aufgweckt werden soll?? Dann muss man natürlich einen Interrupt haben, aber beim ATmega32 kannst du meiner Erinnerung nach den INT2 dafür vergessen, da bei diesen alten AVRs nur ein pegelgetriggerter Interrupt den Controller aus dem Sleep holen kann, und das wiederum geht beim INT2 nicht einzustellen. Wenn du das willst, dann nimm einen pinkompatiblen ATmega324P. Nach dem Aufwecken klemmt man dann den Externinterrupt sofort ab, und die normale (zeitgesteuerte) Tastaturabfrage der Applikation erkennt dann die gedrückte Taste.
Beim Mega32 weckt aus dem Power-down-mode auch der INT2 wieder auf. Steht zumindest mal so im Datenblatt. >Hat von Euch einer einen Code-Schnipsel mit dem ich es doch eventuell >testen kann? Tja, dummerweise tut dein Code. Der springt in die ISR. Etwas anderes würde mit anderem Code auch nicht passieren. Oliver
Ok, dann bin ich jetzt ein wenig ratlos, was oder wie ich das lösen soll. Eventuell Vorschlag vom Jörg den ATmega324P zu probieren. Problem ist im Moment, dass ich von 3 verschiedenen Taster den Mega aufwecken muss. INT0 und INT1 funktionieren ja aaaber INT2 halt nicht. Oliver, einen Taster hattest du bei deinem Test nicht angeschlossen oder ?? Wenn das mit einem physikalisch angeschlossenen Taster bei dir geht, dann kann es ja wirklich nur an meine Hardware liegen. Ok, danke erst einmal ...
>Problem ist im Moment, dass ich von 3 verschiedenen Taster den Mega >aufwecken muss. INT0 und INT1 funktionieren ja aaaber INT2 halt nicht. Das Problem ist, daß du bisher immer noch nicht gesagt hast, WAS nicht funktioniert. Springt er gar nicht in die ISR für INT2, auch nicht, wenn der Prozessor nicht im sleepmode ist? Oder wird er nur nicht aufgeweckt? Oliver
Oliver schrieb: > Beim Mega32 weckt aus dem Power-down-mode auch der INT2 wieder auf. > Steht zumindest mal so im Datenblatt. OK, stimmt, sehe ich jetzt auch. Ich hatte mich nur dran erinnert, dass INT0/1 nur level triggered aufwecken können.
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.