Ich hab's jetzt nachgeschlagen, wie ich das mal gelöst habe.
Code:
//Timer keys polling
ISR(TIMER0_COMPA_vect)
{
static uint8_t keyPrescaler = 0;
static uint8_t oldKeys = 0;
keyPrescaler++;
if (keyPrescaler >= 20)
{
keyPrescaler = 0;
uint8_t newKeys = (PINC & 0xF0); //Keys port
uint8_t keysChanged = newKeys ^ oldKeys;
uint8_t newKeysSet = keysChanged & newKeys;
keysSet |= newKeysSet;
oldKeys = newKeys;
}
}
Ich polle da wohl alle 20ms im 1ms-Timer-Interrupt die entsprechenden vier Port-Pins in die "keysSet"-Variable...
Code:
// called from Main loop
void MaskProcessFromForeground()
{
//SET KEYPRESSED, MASKTIMER ELAPSED AND CHECK READ BUFFER CALLS FROM MAIN ROUTINE
CheckReadBufferTelegrams((FIFO_t*) ReadBuffer, Admin.TelegramReceived);
if(TimerPrescalerCounter == 0)
{
TimerPrescalerCounter = Admin.TimerPrescaler;
if (Admin.TimerElapsed != 0)
Admin.TimerElapsed();
}
if (Admin.KeyPressed != 0)
{
uint8_t keysSetCopy = keysSet;
for (int i = 0; i < 4; i++)
{
if (keysSetCopy & (0x80 >> i))
Admin.KeyPressed(i);
}
cli();
keysSet &= ~keysSetCopy; // reset handled keys
sei();
}
}
...und spreche die keyPressed-callbacks (können dann schon mal etwas länger dauern) aus der main-loop an.
Nicht verwirren lassen: "Admin" ist eine Struktur mit Funktionszeigern, die auf die Funktionen der aktuell geladenen Bildschirmmaske zeigen (die werden beim Umladen der Maske in die Admin-Struktur geschrieben).
Lesezeichen