Hallo Forum, wie muß ich eine Funktion in C (für AVR; avrlib-c) der ich als Parameter einen Port-Pin übergebe, und diese Funktion mir den dann toggeln soll? Danke für Hilfe Wolfgang
Gast
#787648
soll sich bei jedem Aufruf der Funktion der Zustand ändern? Oder soll das selbstständig ablaufen? Wozu soll das gut sein? Oder wie schnell willst du umschalten?
Ich so ungefähr in dieser Art aufrufen: toggel(PIND3); danach soll sich der Zustand des Pins invertiert haben.
Wolfgang Birner wrote: > Ich so ungefähr in dieser Art aufrufen: > toggel(PIND3); > danach soll sich der Zustand des Pins invertiert haben. So gehts gar nicht. Du musst den Port und den Pin getrennt übergeben. Den Port übergibst du als Pointer zu volatile uint8_t void Toggle( volatile uint8_t* Port, uint8_t Pin ) { *Port ^= ( 1 << Pin ); } void foo() { Toggle( PORTD, PD7 ); } Das Schieben in der Funktion ist nicht so toll, da es zur Laufzeit gemacht werden muss. Besser wäre es daher, die Schieberei in den Aufruf zu verlagern void Toggle( volatile uint8_t* Port, uint8_t Value ) { *Port ^= Value; } void foo() { Toggle( PORTD, 1 << PD7 ); }
Danke. Genau das ist es.
Die Übergabe der Adresse und das generische Abarbeiten innerhalb von Toggle() erzeugt aber einiges an Overhead. Mit einem Makro kann man das eleganter lösen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
Wenn man einen neueren AVR hat, kann der seine Portpins umschalten, indem man das PINx-Register beschreibt. Dafür obiges Stück mit -DUSE_PINx_TOGGLE compilieren. Bei älteren AVRs geht das nicht, da muss dann read/modify/write-Code generiert werden.
Was zählt denn zu den neueren/älteren AVRs?
Wolfgang Birner wrote: > Was zählt denn zu den neueren/älteren AVRs? Musste ins jeweilige Datenblatt gucken. Wenn die Funktionalität existiert, gibt es eine eigene Zwischenüberschrift "Toggling the Pin" unter "I/O-Ports" -> "Ports as General Digital I/O". Idealerweise sollte der Compiler das wissen und könnte dann die XOR-Operation gleich entsprechend optimieren, aber das hat ihm noch keiner beigebracht (und es würde den Rahmen der derzeitigen Klassifizierung der AVR-Cores im GCC sprengen, es müsste also ziemlich viel neu gemacht werden).
Danke für den Hinweiß. Meiner kanns: AT90CAN128; hab gerade nachgeschaut.
Karl heinz Buchegger wrote: > void foo() > { > Toggle( PORTD, PD7 ); > } Beim ersten compilieren ist mir aufgefallen: müsste ich hier nicht eigentlich die Adresse mit
1 | |
2 | |
3 | |
4 | |
übergeben?
Wolfgang Birner wrote: > Karl heinz Buchegger wrote: >> void foo() >> { >> Toggle( PORTD, PD7 ); >> } > > Beim ersten compilieren ist mir aufgefallen: müsste ich hier nicht > eigentlich die Adresse mit >
1 | |
2 | |
3 | |
4 | |
5 | |
> übergeben?
Mea culpa. Ich habs vorher nicht compiliert.
Danke nochmal für die Hilfe, ich war wirklich irgendwie auf dem Schlauch gestanden und hab mein Brett vorm Kopf nicht gesehen.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.