Dann leg doch für jeden Zustand ein Array an mit sagen wir 32 Bits
(also 4 Bytes). Mit deinen 10 ms Abtastzeit hättest du dann eine
Periode von 32 ˙ 10 ms = 320 ms, das müsste optisch OK sein. Ein
eingeschaltetes Bit bedeutet dabei jeweils eine eingeschaltete
LED, mehrere zusammenhängende Bits ergeben eine längere Einschalt-
dauer. Durch das ganze Array schiebst du ein ,,Abtastbit'' durch,
wenn das hinten rausfällt, musst du vorn wieder anfangen.
Indem du verschiedene Arrays vorhälst und innerhalb der ISR nur
einen Zeiger auf das aktuelle, kannst du verschiedene Blinkmuster
verwalten.
Bei 32 bits kannst du das vom Schreibaufwand her ganz elegant lösen,
indem du statt eines Arrays und statt des Abtastbits jeweils 32-bit-
Zahlen benutzt (uint32_t). Das ist zwar nicht wirklich effektiv im
Hintergrund dessen, was der Compiler daraus macht, aber dafür sehr
einfach aufzuschreiben, und möglicherweise stört die Ineffektivität
hier gar nicht. Ungefähr so:
1 | uint32_t blink1 = 0xfff00fff;
|
2 | uint32_t blink2 = 0xf0f0f0f0;
|
3 | uint32_t blink3 = 0xfff00000;
|
4 | uint32_t *blinkp = &blink1;
|
5 |
|
6 | ISR(TIMER0_COMPA_vect)
|
7 | {
|
8 | static uint32_t mask = 1;
|
9 |
|
10 | if (*blinkp & mask)
|
11 | LED_ON();
|
12 | else
|
13 | LED_OFF();
|
14 |
|
15 | mask <<= 1;
|
16 | if (mask == 0) mask = 1;
|
17 | }
|
Eine Änderung des angezeigten Musters erfolgt, indem man blinkp
jeweils auf eine der Adressen von blink1, blink2 oder blink3
umschaltet. Wenn dich die kurze Inkonsistenz beim Umschalten
nicht stört (es blinkt dann eine Periode lang ,,irgendwie''),
dann würde ich mir nicht einmal die Mühe machen, das Umschalten
mit der kompletten Periode (mask läuft über und wird wieder auf
1 gesetzt) zu synchronisieren.