?
Neben der Schleifenkiste muust du für den Taster PINC abfragen, nicht PORTC.
Aber da stellen sich noch mehr Fragen - wenn jemand kürzer als 50ms braucht, um den Taster zu drücken, hast du ein Problem. Wenn (wahrscheinlicher) jemand länger als 100ms braucht, auch. Eigentlich willst du nur auf der steigenden Flanke auslösen, und da der Taster vermutlich nicht entprellt ist (das macht man aus Kostengründen meistens in Software) bedeutet das, den Button häufig, am besten über einen Timer, zu pollen.
Was hängt da für ein Quartz dran? Ich rechne mal mit 8MHz.
Ich stelle mir das (völlig ungetestet)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define TASTER_DDR DDRC
#define TASTER_PORT PORTC
#define TASTER_PIN PINC
#define LED_DDR DDRD
#define LED_PORT PORTD
uint8_t taster_event(uint8_t event) {
static uint8_t taster_wurde_gedrueckt = 0;
uint8_t tmp;
// Hier Race-Condition, daher kurzzeitig Interrupts ausschalten.
cli();
tmp = taster_wurde_gedrueckt;
taster_wurde_gedrueckt = event;
sei();
return tmp;
}
ISR(TIMER0_OVF_vect) {
// 4 * 8,192ms = 32,768ms; das dürfte für die meisten Taster ausreichen.
static uint8_t const required = 4;
static uint8_t counter = 0;
static uint8_t taster_status = 0;
if(TASTER_PIN == 0) {
counter = 0;
taster_status = 0;
} else if(counter == required) {
// Wenn viermal hintereinander der Taster gedrückt aussah, sollte die
// Prellphase vorbei sein, und jemand hat da den Finger drauf.
if(!taster_status) {
// Taster war vorher nicht gedrückt, jetzt ist er gedrückt -> steigende Flanke.
taster_event(1);
}
taster_status = 1;
} else {
++counter;
}
}
void taster_init(void) {
// Alle Pins Input-Low.
TASTER_DDR = 0;
TASTER_PORT = 0;
// Prescaler = 256. Bei 8MHz bedeutet das,
// dass der Timer alle 8,192ms überläuft.
TCCR0 = _BV(CS02);
TIMSK = _BV(TOIE0);
sei();
}
int main(void) {
taster_init();
LED_DDR = 0xff;
for(uint8_t led_mask = 1; ; led_mask = led_mask ? led_mask << 1 : 1) {
LED_PORT = led_mask;
while(!taster_event(0)) {
// Alle 50ms mal nach dem Taster kucken.
_delay_ms(50);
}
}
return 0;
}