Hallo zusammen,
ich habe einen Atmega328P und spiele mit externen Interrupts. Genauer
mit den externen Pin Change Interrupts. PC0 bis PC3 ist meine Ausgabe,
PB0 bis PB2 sind meine Eingabe Pins. Findet ein beliebiger Pegelwechsel
an PB0 bis PB2 statt, soll die Interruptroutine ISR (PCINT0_vect)
aufgerufen werden und eine Zählsequenz 1 bis 15 an PC0 bis PC3
ausgegeben werden. Beim Eintritt in die ISR deaktiviere ich die globalen
Interrupts. Bei Austritt gegebe ich sie wieder frei. Meine
Erwartungshaltung war nun diese, dass beim ersten Pegelwechsel die
Zählsequenz genau einmal abläuft. Da ich ja beim Eintritt die globalen
Interrupts deaktiviert habe. Nun ist es aber so, dass wenn ich einen
Taster an z.B PB0 schließe und sofort wieder öffne, die Sequenz zweimal
abläuft. Halte ich den Taster jedoch geschlossen wird erst beim öffnen
die Sequenz wieder durchlaufen.
Vielleicht kann mir jemand erklären, warum die Sequenz beim schließen
und sofortigen öffnen des Tasters trotz dann deaktivierter interrupts
zweimal abläuft. Danke!
1 | #define F_CPU 16000000
|
2 | #include <util/delay.h>
|
3 | #include <avr/io.h>
|
4 | #include <avr/interrupt.h>
|
5 |
|
6 | int main(void)
|
7 | {
|
8 | // -- Konfiguration der Status-LEDs PC0, PC1, PC2, PC3
|
9 | DDRC |= ((1<<DDC0)|(1<<DDC1)|(1<<DDC2)|(1<<DDC3)|(1<<DDC4));
|
10 | PORTC &= ~((1<<PORTC0)|(1<<PORTC1)|(1<<PORTC2)|(1<<PORTC3)|(1<<PORTC4));
|
11 |
|
12 |
|
13 | // -- Konfiguration PCINT0 Interrupt an Pin PB0, PB1 & PB2 --
|
14 | DDRB &= ~((1<<DDB0)|(1<<DDB2)|(1<<DDB2));
|
15 | PORTB |= ((1<<PORTB0)|(1<<PORTB1)|(1<<PORTB2));
|
16 |
|
17 | PCICR |= (1<<PCIE0);
|
18 | PCMSK0 |=((1<<PCINT0)|(1<<PCINT1)|(1<<PCINT2));
|
19 | sei(); // Globale Interrupts aktivieren
|
20 |
|
21 | while(1)
|
22 | {
|
23 | PORTC = 0x03; //Kein Interrupt? Dann LED 1&2 anschalten.
|
24 | }
|
25 | return 0;
|
26 | }
|
27 |
|
28 | ISR (PCINT0_vect)
|
29 | {
|
30 | cli(); //Interrupt erkannt? Interrupts deaktivieren.
|
31 | for (unsigned char i = 1; i <=15; i++)
|
32 | {
|
33 | PORTC = i;
|
34 | _delay_ms(200);
|
35 | }
|
36 | sei(); //LED Sequenz beendet? Interrupts aktivieren.
|
37 | }
|