www.mikrocontroller.net

Forum: Compiler & IDEs Pointer auf PORT oder bessere Lösung


Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Header-Datei?

Ralf

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also etwa so:
#ifndef _LAMPEN_H_
  #define _LAMPEN_H_ 1

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

  #define Lampe_0_ON (Lampe_0 = 1)
  #define Lampe-1_ON (Lampe_1 = 1)
  #define Lampe-2_ON (Lampe_2 = 1)

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

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

Ralf

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom wrote:
>
> Dagegen hab ich einen heiligen Grahl gesucht ;)
>

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

void lampe_on (int n)
{
  *(LampPorts[n]) |= LampPins[n];
}

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

So ungefähr. Soll heißen: ungetestet

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da du hier im GCC-Forum bist, mal in der Syntax vom AVR-GCC.  Ich
vermute, du suchst sowas:
#include <avr/io.h>

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

#define ON 1
#define OFF 0

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

int
main(void)
{
        LAMPE_N_SWITCH(3, ON);
        LAMPE_N_SWITCH(1, OFF);
        LAMPE_N_SWITCH(2, ON);

        return 42;
}

Edith: Micha war schneller. ;-)

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.