Du hast da noch ein paar Sachen drin, mit denen du dich gewaltig in die
Nesseln setzen kannst...
1 | #define led_A_on PORTB |=_BV(PB0)
|
2 | #define led_A_off PORTB &= ~_BV(PB0)
|
3 | #define led_B_on PORTB |=_BV(PB1)
|
4 | #define led_B_off PORTB &= ~_BV(PB1)
|
5 | #define led_C_on PORTB |=_BV(PB2)
|
6 | #define led_C_off PORTB &= ~_BV(PB2)
|
Hast du schon mal probiert, was passiert, wenn in einem dieser Makros
ein Fehler drin ist? Dann wird der Compiler bei der Fehlermeldung nicht
die Zeile angeben, in der das Makro steht, sondern die Zeile, in der das
Makro verwendet wird. Da kann das Fehlersuchen ekelhaft werden. Du
kannst stattdessen inline-Funktionen erstellen, also welche, die der
Compiler selber anstelle des Funktionsaufrufs einfügt. Das macht im
Gegensatz zu den Makros nicht der Präprozessor, du kriegst also eine
exakte Fehlermeldung:
1 | inline void led_A_on() {
|
2 | PORTB |= (1 << PB0);
|
3 | }
|
4 |
|
5 | inline void led_A_off() {
|
6 | PORTB &= ~(1 << PB0);
|
7 | }
|
8 |
|
9 | inline void led_B_on() {
|
10 | PORTB |= (1 << PB1);
|
11 | }
|
12 |
|
13 | inline void led_B_off() {
|
14 | PORTB &= ~(1 << PB1);
|
15 | }
|
16 |
|
17 | inline void led_C_on() {
|
18 | PORTB |= (1 << PB2);
|
19 | }
|
20 |
|
21 | inline void led_C_off() {
|
22 | PORTB &= ~(1 << PB2);
|
23 | }
|
Dieses _BV-Makro halte ich auch für überflüssig, mehr zu schreiben ist
es so auch nicht.
1 | DDRB =7; //Ausgänge definieren (LED PB0-PB2)
|
Das ist sehr schwer zu lesen. Jemand, der kein Datenblatt hat, ist da
schnell verloren ("Wo kommt denn die 7 her?"). Besser ist es so:
1 | DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2);
|
Diese Ausdrücke berechnet der Compiler beim Kompilieren, das Programm
wird also nicht größer.
1 | while (i<sizeof(program)-1)
|
"sizeof" ist in C mit Vorsicht zu genießen. Hier funktioniert es, aber
wie wäre es so:
1 | for (uint8_t i = 0; program[i] != '\0'; i++) {
|
Schließlich wird der String, den du oben festlegst, von einem '\0'
abgeschlossen.
Ich hab deinen Code mal etwas umgeschrieben und angehängt.