Hallo.
Ich lerne gerade Arduinos und C.
Gibt es ein Tutorial was ein paar "trickreiche" Beispiele zum
Präprozessor verrät?
Oder erwarte ich da vielleicht zuviel?
Der Präprozessor ist ja nicht gerade umfangreich was den Befehlssatz
betrifft.
Alle von mir bisher gesichteten Beispiele sind doch recht einfach
gehalten:
C Makros
https://www.mikrocontroller.net/articles/C_Makros
AVR Vordefinierte Makros:
http://www.microchip.com/webdoc/avrassembler/avrassembler.wb_preprocessor.Pre-defined_macros.html
AVR Assembler Preprocessor
http://www.microchip.com/webdoc/avrassembler/avrassembler.wb_preprocessor.html
Options for the C compiler avr-gcc
Machine-specific options for the AVR
http://www.nongnu.org/avr-libc/user-manual/using_tools.html
http://public.beuth-hochschule.de/~kempfer/skript_c/Kap10.html
Mit "trickreich" meine ich z. B.:
Beitrag "Re: AVR GCC Präprozessor #if funktioniert nicht !"
Erstmal zum "Aufwärmen":
Wie ist es möglich die "Version" aus Datumscode (vielleicht sogar der
Datei) zusammenzusetzen?
Macht ihr sowas?
1 | #define VERSION "Ver. 201804011155" //"Ver. __CENTURY__ __YEAR__ __MONTH__ __DAY__ __HOUR__ __MINUTE__" // Diese Version ist vom ersten April 5 vor Zwölf ;-)
|
Der Präprozessor macht mir gerade zu schaffen bei der Zuweisung der Pin Change Interrupts:
1 | // Pinzuweisung Encoder: Arduino-Pin
|
2 | #define ENC_A PD4 // 4 // CLK = A am Encoder
|
3 | #define ENC_A_DD DDD4 // zugehöriger Data-Direction-Pin
|
4 | #define ENC_A_PIN PIND // zugehörige Port-Eingangadresse
|
5 | #define ENC_A_DDR DDRD // zugehöriges Data-Direction-Register
|
6 | #define ENC_B PD5 // 5 // DT = B am Encoder
|
7 | #define ENC_B_DD DDD5 // zugehöriger Data-Direction-Pin
|
8 | #define ENC_B_PIN PIND // zugehörige Port-Eingangadresse
|
9 | #define ENC_B_DDR DDRD // zugehöriges Data-Direction-Register
|
10 | #define ENC_S PB1 // 9 // SW = Taster/Switch ist normally opened (NO) am Encoder
|
11 | #define ENC_S_DD DDB1 // zugehöriger Data-Direction-Pin
|
12 | #define ENC_S_PIN PINB // zugehörige Port-Eingangadresse
|
13 | #define ENC_S_DDR DDRB // zugehöriges Data-Direction-Register
|
14 | |
15 | #if (ENC_A_DDR == DDRD) || (ENC_B_DDR == DDRD) || (ENC_S_DDR == DDRD) // funktioniert nicht weil nur Zahlen verglichen werden können
|
16 | #define PCIE2_USED
|
17 | #endif
|
18 | #if (ENC_A_DDR == DDRC) || (ENC_B_DDR == DDRC) || (ENC_S_DDR == DDRC) // funktioniert nicht weil nur Zahlen verglichen werden können
|
19 | #define PCIE1_USED
|
20 | #endif
|
21 | #if (ENC_A_DDR == DDRB) || (ENC_B_DDR == DDRB) || (ENC_S_DDR == DDRB) // funktioniert nicht weil nur Zahlen verglichen werden können
|
22 | #define PCIE0_USED
|
23 | #endif
|
Im Programm wird dann zugewiesen:
1 | #ifdef PCIE2_USED
|
2 | PCICR |= (1 << PCIE2); // Pin-Change-Interrupts für PCINT[23:16] (PORTD). |
3 | #endif
|
4 | #ifdef PCIE1_USED
|
5 | PCICR |= (1 << PCIE1); // Pin-Change-Interrupts für PCINT[8:14] (PORTD). PCINT15 ist bei ATmega168 und ATmega328 nicht vorhanden. |
6 | #endif
|
7 | #ifdef PCIE0_USED
|
8 | PCICR |= (1 << PCIE0); // Pin-Change-Interrupts für PCINT[7:0] (PORTB). |
9 | #endif
|
Wie erledige ich die folgenden Zuweisungen automatisiert?
1 | PCMSK2 |= ((1 << PCINT20) | (1<<PCINT21)); // Pin-Change-Interrupts nur für ENC_A, ENC_B |
2 | PCMSK0 |= (1 << PCINT1); // Pin-Change-Interrupt nur für ENC_S (PORTB) |
Grüße an Alle, die mir helfen. ;-) SG