Wenn du das wirklich so machen willst, dann ginge es so:
Code:
void set_port (const char port, const uint8_t pad)
{
if ('A' == port)
{
PORTA |= (1 << pad);
}
if ('B' == port)
{
PORTB |= (1 << pad);
}
}
Das würde zunächst dazu führen, daß das Portsetzen recht lange dauert.
Anstatt diese Funktion in ein C-Modul zu schreiben, könntest du sie in den entsprechenden Header tun und die Funktion als
Code:
static inline set_port (const char, const uint8_t);
oder
Code:
static set_port (const char, const uint8_t) __attribute__((always_inline));
deklarieren. Dann weiß GCC schon zur Compilezeit, wie die Werte in der Funktion sind und optimiert das bis nur noch eine Maschineninstruktion da steht.
Aber was hat es für ein Vorteil, set_port ('A', 7) zu schreiben anstatt PORTA |= (1 << 7)
Ich selbst benutze allerdings auch Port-Support Makros, die Code folgender Gestalt erlauben:
Code:
// irgendwo in "ports.h"
#define PORT_LED PORTB_6
#define PORT_TASTER PORTC_1
// irgendwo in "module.c"
// LED anschalten
MAKE_OUT (PORT_LED);
SET (PORT_LED);
// Taster ist IN + PullUp
MAKE_IN (PORT_TASTER);
SET (PORT_TASTER);
if (IS_SET (PORT_TASTER)) ...
Das erlaubt eine zentrale Port-Definition und man muss nicht PORTx, PINx, DDRx anpassen, wenn man was an der Schaltung ändert.
Die gcc-Optimierungen führen dazu, daß die riesigen Makros zu einer einzigen Maschineninstruktion kollabieren -- ganz wichtig, weil das Setzen/Löschen von Ports ATOMAR sein muss!
Zudem muss der Port nicht physikalisch sein, sondern es kann auch ein virtueller Port sein (also zB einer, der im RAM abgebildet ist und über Kommunikation mit einem Portexpander gelesen/geschrieben wird).
Die Makros sind allerding nicht schön. Zudem müssen die Ports zur Compilezeit bekannt sein, in einer lib funktioniert des Ansatz also nicht.
Lesezeichen