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