Hallo, ich würde gerne einen Pinchange Interrupt auslösen ( eine led soll leuchten und wieder aus) um besser zu verstehen was das genau ist. Habe folgenden Code dazu geschrieben, aber irgendwie bringe ich ihn nicht zum laufen. Was mache ich den hier falsch? grüsse huber ich benütze; Attiny24a Atmelstudio6.0 mit original Avr isp mk2 /* * Attiny24A_test.c * * Created: 05.08.2016 11:23:30 * Author: Huber */ #define F_CPU 1000000UL #include <util/delay.h> #include <avr/io.h> #include <avr/interrupt.h> ISR(PCINT1_vect) { PORTA|= (1<<PA0); _delay_ms(1000); PORTA &= ~(1<<PA0); } int main(void) { //Ausgänge festlegen DDRA|= (1<<PA0); //Eingänge festlegen pullups PORTA|= (1<<PA1); //Interrupt Service Routine PCINT eintellen GIFR|= (1<<PCIF0); PCMSK0|= (1<<PCINT1); sei(); while(1) { } }
Huber M. schrieb: > GIFR|= (1<<PCIF0); GIFR ist ein Flag-Register, da gibt es nichts zum Einstellen, nur die IRQ Flags werden hier gelöscht und/oder abgefragt. Was du einstellen willst/sollst ist das GIMSK (INT0) und das MCUCR (Interrupt Sense Control Bits).
Mahlzeit, nein, ich wollte schon gezielt die PCINT nutzen. Um zu verstehen was ich mit denen anfangen kann. Oder für was man diese benützt. Denn vom lesen alleine verstehe ich es einfach nicht. Ich bräuchte irgend ein beispiel. Denn int0 das kann ich, das sind ja externe interrups. Wie gesagt die PCINT verstehe ich nicht. danke huber
Huber M. schrieb: > nein, ich wollte schon gezielt die PCINT nutzen. Dann must du die auch erlauben, dass versuchte dir Mitlesa in seinem Beitrag zu erklären.
1 | //Interrupt Service Routine PCINT einstellen
|
2 | PCMSK0 |= (1<<PCINT1); //* PCINT auf PA.1 erlaubt |
3 | GIMSK |= (1<<PCIE0); //* PA.0 - PA.7 PCINT erlaubt |
4 | sei(); |
Und du darfst natürlich nicht mehr am PA.1 wackeln, denn selbst als Ausgang wird PA.1 einen Interrupt auslösen.
Nun, da hat mitlesa leider einen Fehler gemacht. Es handelt sich nicht um das Bit namens "INT0" sondern das Bit namens "PCIEO". Das GIFR brauchst Du nicht zu setzen. Das dient dazu das Interrupt-Flag zurückzusetzen, falls der Interrupt mal aufgetreten ist. Das braucht man aber bis auf Ausnahmefälle nicht selbst zu tun, da es, wie im Datenblatt steht, selbsttätig zurückgesetzt wird, sobald die Interrupt-Routine angesprungen wird. Aber das steht alles im Datenblatt. Selbst wenn Du daraus nicht entnehmen kannst, wozu es gut ist, solltest Du aber die Funktionsweise erkennen können. In einer Bedienungsanleitung eines Autos steht ja auch nur, wie es zu bedienen ist, nicht was man damit machen kann oder soll. Du solltest Du auch angewöhnen, genau zu beschreiben, was nicht funktioniert. Was geschieht und was stattdessen geschehen soll. Das hilft bei der Fehlersuche ungemein. Und noch eins: Auch wenn es in Deinem Fall nur eine Rolle spielt, wenn Interrupts in kürzeren Abständen als 1s auftreten, solltest Du delays in Interrupt-Routinen vermeiden. In diesem Fall nur zu Übungszwecken, aber Du kannst ja mal die Interrupts in kurzen Abständen auslösen, dann siehst Du, das Du Probleme bekommst.
Moing, so sieht der abgeänderte Code jetzt aus. Und, wenn jetzt irgend eine Veränderung an PCINT1 mittels Taster auftritt, soll PA0, 1sec. lang leuchten, und danach wieder ausgehen. Es tut sich aber gar nichts. Und wenn ich das richtig übersetzt habe, dann löst jede Veränderung an PCINT 7-0 ein interrupt aus oder? -die LED ist Ordnungsgemäß an PA0 angeschlossen -der Taster an PA1(schaltet PA1 gegen GND). Und war testweise auch an andere pins. Es müsste doch eigentlich funktionieren? /* * Attiny24A_test.c * * Created: 05.08.2016 11:23:30 * Author: Huber */ #define F_CPU 1000000UL #include <util/delay.h> #include <avr/io.h> #include <avr/interrupt.h> ISR(PCINT1_vect) { PORTA|= (1<<PA0); _delay_ms(1000); PORTA &= ~(1<<PA0); } int main(void) { //Ausgänge festlegen DDRA|= (1<<PA0); //Eingänge festlegen pullups PORTA|= (1<<PA1); //Interrupt Service Routine PCINT einstellen PCMSK0 |= (1<<PCINT1); //* PCINT auf PA.1 erlaubt GIMSK |= (1<<PCIE0); //* PA.0 - PA.7 PCINT erlaubt sei(); while(1) { } }
Huber M. schrieb: > ISR(PCINT1_vect) Huber M. schrieb: > GIMSK |= (1<<PCIE0); Die Freigabe muß zum Handler passen.
Huber M. schrieb: > Moing, > > so sieht der abgeänderte Code jetzt aus. Und, wenn jetzt irgend eine > Veränderung an PCINT1 mittels Taster auftritt, soll PA0, 1sec. lang > leuchten, und danach wieder ausgehen. Es tut sich aber gar nichts. Und > wenn ich das richtig übersetzt habe, dann löst jede Veränderung an PCINT > 7-0 ein interrupt aus oder? nein, Im PCMSKx Register legst du fest welche der zugeordneten 8 Pins einen INT auslösen kann. Im GIMSK wiederum musst du festlegen welche Gruppe von PCINTs einen INT auslösen dürfen. Die ISR gibts immer nur für jede Gruppe, deshalb muss die auch die Nummer aus dem entspechenden PCMSK haben. Solange du aus einer 8'er Gruppe genau einen Pin freigibst verhält sich die ISR genau wie bei INT0 o. INT1. Gibst du mehrere frei musst du in der ISR erst noch herausfinden welcher Pin den INT ausgelöst hat. Wenn du für PA1 also PCINT1 in PCMSK*0* setzt, und PCIE*0* im GISMK setzt und dann den richtigen INT PCINT0_vect nimmst, dann sollte es auch funktionieren. Sascha
danke, ok, an PCINT1 wird jetzt ein interrupt ausgelöst. An den anderen nicht. Aber müsste es jetzt nicht egal sein an welchen (PCINT 7-0)ich den Taster anschliesse. Es müsste doch jetzt an jeden pin ein interrupt ausgelöst werden ?
Und gewöhne dir bitte ganz schnell ab, _delay_ms() in einer ISR zu benutzen. Das ist ein ganz böser Fehler.
Huber M. schrieb: > Es müsste doch jetzt an jeden pin ein interrupt > ausgelöst werden ? Nein, nur die Pins, die du mittels PCMSK0 definiert hast, lösen einen Interrupt der Gruppe PCINT0_vect aus. Hast du nur Pin 1 definiert werden die Pins 0, 2-x keinen Interrupt der Gruppe auslösen.
ps, war wohl mit der antwort zu schnell, danke jetzt glaube ich habe ich es verstanden.
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.