Pointer auf PORT oder bessere Lösung

Gast #1148984
Hallo Leute!

Ich erklär kurz mal das Problem welchem ich gegenüber stehe:

Bspw. habe ich 8 verschiedene Lampen, die sich (andere Elektronik 
vernachlässigt) über einen verschiedenste Pins am AVR ein und 
ausschalten lassen. Genauso hab ich wild verteilt über den AVR Eingänge, 
die mir sagen, ob eine Lampe ein ist.

Was ich jetzt gerne machen würde wäre eine intelligente Gruppierung des 
Ganzen, so dass ich flexibel bin aber trotzdem gut aussehenden Code hab. 
Bspw (pseudocode!):

#define... Lampe-ON[0] PORTA.3
#define... Lampe-ON[1] PORTD.7
#define... Lampe-ON[2] PORTH.2
...
#define... Lampe-FB[0] PINA.1
#define... Lampe-FB[1] PING.7
......

void lampe_ein(n) {
     toller_befehl[n]..
}

void lampe_aus(n) {
     toller_befehl2[n]..
}


und so weiter. Ich will also ungern in jeder Funktion, irgendwelche 
switch oder if abfragen oder sonstiges haben, sondern würde gern alles 
einmal definieren und dann ist Ruhe im Karton ;)


Besten Dank für Input! :-)

Euer -Tom
Gast
Also etwa so:
1
#ifndef _LAMPEN_H_
2
  #define _LAMPEN_H_ 1
3

4
  #define Lampe_0 PORTA.3
5
  #define Lampe-1 PORTD.7
6
  #define Lampe-2 PORTH.2
7

8
  #define Lampe_0_ON (Lampe_0 = 1)
9
  #define Lampe-1_ON (Lampe_1 = 1)
10
  #define Lampe-2_ON (Lampe_2 = 1)
11

12
  #define Lampe_0_OFF (Lampe_0 = 0)
13
  #define Lampe-1_OFF (Lampe_1 = 0)
14
  #define Lampe-2_OFF (Lampe_2 = 0)
15
#endif

Dann diese Headerdatei überall einbinden, wo's nötig ist, und fertig.

Ralf
Gast
Hey, erstmal danke für die bisherigen Antworten!

was ich ein bisschen "doof" fand ist dann halt in jeder Routine 
schreiben zu müssen...

void lampe_on (int n) {
if (n == 0) Lampe_0_ON;
if (n == 1) Lampe_1_ON;
if (n == 2) Lampe_2_ON;
if (n == 3) Lampe_3_ON;
if (n == 4) Lampe_4_ON;
if (n == 5) Lampe_5_ON;
if (n == 6) Lampe_6_ON;
if (n == 7) Lampe_7_ON;
}

void lampe_off (int n) {
if (n == 0) Lampe_0_OFF;
if (n == 1) Lampe_1_OFF;
if (n == 2) Lampe_2_OFF;
if (n == 3) Lampe_3_OFF;
if (n == 4) Lampe_4_OFF;
if (n == 5) Lampe_5_OFF;
if (n == 6) Lampe_6_OFF;
if (n == 7) Lampe_7_OFF;
}

Dagegen hab ich einen heiligen Grahl gesucht ;)

Besten Dank!
Tom wrote:
>
> Dagegen hab ich einen heiligen Grahl gesucht ;)
>

Hmm.
1
volatile uint8_t* LampPorts[] = { &PORTA, &PORTH, &PORTC, &PORTA, &PORTE };
2
volatile uint8_t  LampPins[]  = { 1<<PA0, 1<<PH1, 1<<PC5, 1<<PA4, 1<<PE4 };
3

4
void lampe_on (int n)
5
{
6
  *(LampPorts[n]) |= LampPins[n];
7
}
8

9
void lampe_off (int n)
10
{
11
  *(LampPorts[n]) &= ~LampPins[n];
12
}

So ungefähr. Soll heißen: ungetestet
Moderator Persönliche Seite
Da du hier im GCC-Forum bist, mal in der Syntax vom AVR-GCC.  Ich
vermute, du suchst sowas:
1
#include <avr/io.h>
2

3
#define LAMPE1 PORTA, 0
4
#define LAMPE2 PORTB, 2
5
#define LAMPE3 PORTC, 5
6

7
#define ON 1
8
#define OFF 0
9

10
#define LAMPE_SWITCH_int(port, bit, onoff) \
11
  if (onoff) { (port) |= (1 << (bit)); } \
12
  else { (port) &= ~(1 << (bit)); }
13
#define LAMPE_SWITCH(arg, onoff) LAMPE_SWITCH_int(arg, onoff)
14
#define LAMPE_N_SWITCH(n, onoff) LAMPE_SWITCH(LAMPE##n, onoff)
15

16
int
17
main(void)
18
{
19
        LAMPE_N_SWITCH(3, ON);
20
        LAMPE_N_SWITCH(1, OFF);
21
        LAMPE_N_SWITCH(2, ON);
22

23
        return 42;
24
}

Edith: Micha war schneller. ;-)
Gast
Hi,

jetzt meld ich mich nochmal zu Wort! :-) Wenn ich das richtig 
durchschaut hab, ist das nun eine Lösung für "Schreibfaule", die das so 
hardcoded in der Applikation benutzen wollen.

Mein Szenario sah so aus:

- Ein Auswahlfeld in einem HTML Formular am AVR, wo man die Lampe 1 - 30 
auswählen kann und dann auf den button ausschalten oder einschalten 
drückt.


- Programmcode empfängt den HTTP POST Request und extrahiert die zu 
schaltende Lampennummer in eine Variable n

dann soll aufgerufen werden "lampe_ein(n)"


Es handelt sich also um ne Sachlage, die nicht durch den precompiler 
gelöst werden kann. ich bräuchte einen pointer auf ein bit eines Ports 
in einem array.

bspw:

Lampe[0] = PINA.3;
Lampe[1] = PIND.5;


aber so, dass ich dann halt Lampe[n] = 0 schreiben kann und sie geht 
aus.

Wenns nicht geht, nicht so tragisch aber schön wärs ;)


Sorry falls ich die Lösung nicht verstanden hab von oben und das schon 
so geht.

-Tom
Persönliche Seite
Prinzipiell hast du 2 Möglichkeiten "Dynamik" reizubringen, die bereits 
genannt wurden:

1) Die benörigten SFR-Adressen, Masken etc. werden in einem Array 
abgelegt und per Lampen-Index drauf zugegriffen und die Aktion 
ausgeführt.

2) Eine if-else-Orgie resp. switch-case unterscheidet die einzelnen 
Lampen, in den Fällen stehen direkt die SFR-Adressen, die sich zur 
Laufzeit ja nicht ändern.

Bei Ansatz 1) ist zu beachten, daß die so erzeugten Zugriffe nicht 
atomar sind, d.h. wenn eine ISR auf dem selben Port rumnudelt, kann's 
durch den nicht-atomaren Code sporatische Fehler geben.

Johann

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.