Forum: Mikrocontroller und Digitale Elektronik Elegante Pinabstraktion


von Franz (Gast)


Lesenswert?

Hallo,

ich möchte meinen code etwas übersichtlicher und wartbarer machen.
Ich habe ein LCD Display an meinen XMega angeschlossen und möchte nun 
die einzelnen Leitungen benennen.

Beispiel: Für die LEDOff Leitung des LCDs welche die Beleuchtung steuert 
möchte ich
#define LCD_LED PA0

um anschließend im Code wie folgt die Beleuchtung steuern zu können

LCD_LED = 1;

Ist das überhaupt möglich?

Gruß Franz

von Phil J. (sunflower_seed)


Lesenswert?

Ja in dem du Makros im Präprozessercode anlegst.
Beitrag "einzelne Prozessorpins per #define Ansprechen (ATmega16) AVR"

von Franz (Gast)


Lesenswert?

Du hast mich nicht richtig verstanden.

Ich möchte die pins nur "Maskieren"

nicht nur für
LCD_LED = 1
sondern auch für
if(LCD_LED == 1)
{


Gruß Franz

von Franz (Gast)


Lesenswert?

nichtmal

#define LCD_cmd  PORTA
#define LCD_nRST 0

LCD_data |= (1 << LCD_nRST);

funktioniert obwohl man es über die suche oft so findet.

invalid operands to binary & (have 'PORT_t' and 'int')

Kann mir niemand helfen?

Gruß Franz

von Ralf G. (ralg)


Lesenswert?


von MW (Gast)


Lesenswert?


von Rudi M. (rudimentaer)


Lesenswert?

Franz schrieb:
> ... hast mich nicht richtig verstanden.
im ersten Teil hattest Du nichts anderes gefragt

> nicht nur für
> LCD_LED = 1
> sondern auch für
> if(LCD_LED == 1)

Codevision kann das. Macht den Code leider nicht besonders portierbar 
aber schön übersichtlich.

Rudi

von Verwirrter Anfänger (Gast)


Lesenswert?

Franz schrieb:
> nichtmal
>
> #define LCD_cmd  PORTA
> #define LCD_nRST 0
>
> LCD_data |= (1 << LCD_nRST);
>
> funktioniert obwohl man es über die suche oft so findet.
>
> invalid operands to binary & (have 'PORT_t' and 'int')
>
> Kann mir niemand helfen?
>
> Gruß Franz

Das versteh ich nicht ganz, LCD_data ist nirgendwo definiert.
1
#define LCD_DATA PORTA
2
#define LCD_NRST PA0
3
4
LCD_DATA |= (1 << LCD_NRST);

sollte aber funktionieren.

von Achim M. (minifloat)


Lesenswert?

Verwirrter Anfänger schrieb:
> #define LCD_DATA PORTA
> #define LCD_NRST PA0

es gäbe da auch noch:
1
#define LCD_NRST_SET() LCD_DATA|=LCD_NRST
2
#define LCD_NRST_CLR() LCD_DATA&=~LCD_NRST
3
4
//und schon heißt es im Code
5
LCD_NRST_CLR();
6
//und spaeter
7
LCD_NRST_SET();
Sollte auch jeder anständige C-Compiler mit klarkommen. Nicht sowas wie 
"sieht schön aus aber geht nur bei IAR"...
mfg mf

von Achim M. (minifloat)


Lesenswert?

Es muss beim den üblichen AVR-defines natürlich heißen:
1
#define LCD_NRST_SET() LCD_DATA|=(1<<LCD_NRST)
2
#define LCD_NRST_CLR() LCD_DATA&=~(1<<LCD_NRST)
mfg mf

von Sven P. (Gast)


Angehängte Dateien:

Lesenswert?

Für GCC, Verwendung:
1
#define SOME_PORT BITWISE_CHAR(PORTD, 3)
2
3
/* ... */
4
SOME_PORT = 1;
5
if (SOME_PORT == 1)
6
  ;

von Achim M. (minifloat)


Lesenswert?

Mini Float schrieb:
>  Nicht sowas wie "sieht schön aus aber geht nur bei IAR"...

Sven P. schrieb:
> Für GCC

Und auch nicht sowas wie "sieht schön aus aber geht nur mit GCC"...

Aber gut, wenn ihr nicht wollt, dass euer Code portabel ist, dann eben 
nicht.
mfg mf

von Sven P. (Gast)


Lesenswert?

Mini Float schrieb:
> Aber gut, wenn ihr nicht wollt, dass euer Code portabel ist, dann eben
> nicht.
Über 'Portabilität' kann man sich in diesem Fall nun freilich drüber 
streiten...

von Sven P. (Gast)


Lesenswert?

Mit noch mehr Präprozessor kann man es portabel eindampfen:
1
#ifndef IO_H
2
#define IO_H
3
4
#include <avr/io.h>
5
6
/* IO ports */
7
#define IO_STRAIGHT    0
8
#define IO_INVERT      1
9
10
#define BUZZER    B, B1, IO_STRAIGHT
11
#define RELAIS    B, B5, IO_STRAIGHT
12
13
#define __IO_SET(port, bit, invert, state)      \
14
  if ( (invert) ^ ((state) ? 1 : 0) ) {         \
15
    PORT##port |= _BV(PORT##bit);               \
16
  }                                             \
17
  else {                                        \
18
    PORT##port &= ~_BV(PORT##bit);              \
19
  }
20
21
#define __IO_GET(port, bit, invert)             \
22
  ( (PORT##port & _BV(PORT##bit)) ? (1 ^ (invert)) : (0 ^ (invert)) )
23
24
25
#define IO_SET(port, state)    __IO_SET(port, state)
26
#define IO_GET(port)           __IO_GET(port)
27
28
#endif

Verwendung:
1
IO_SET(BUZZER, 1);
2
IO_SET(RELAIS, 0);

Und bitte, keine weiteren Kommentare dazu :-}

von (prx) A. K. (prx)


Lesenswert?

Sven P. schrieb:

> Mit noch mehr Präprozessor kann man es portabel eindampfen:

Inwiefern ist io.h eigentlich essentiell abhängig von GCC? Das 
Inline-Verbot ist für die Frage hier irrelevant und die structs müssten 
eigentlich auch ohne "packed" schon frei von Löchern sein. Der Rest ist 
normales C.

Dass Bitfields allgemein als schwach portabel gelten ist klar, aber ganz 
so schlimm ist es dann doch nicht, wenn man damit Portpins anspricht und 
damit die Architektur sowieso festnagelt.

von Rolf M. (rmagnus)


Lesenswert?

Franz schrieb:
> nichtmal
>
> #define LCD_cmd  PORTA
> #define LCD_nRST 0
>
> LCD_data |= (1 << LCD_nRST);
>
> funktioniert obwohl man es über die suche oft so findet.

Dann versuch's doch mal mit:
1
 LCD_cmd |= (1 << LCD_nRST);

> invalid operands to binary & (have 'PORT_t' and 'int')

Da in dem Code gar kein & vorkommt, muß da wohl ein falsches Makro 
irgendwas seltsames tun.

von Sven P. (Gast)


Lesenswert?

A. K. schrieb:
> Inwiefern ist io.h eigentlich essentiell abhängig von GCC? Das
> Inline-Verbot ist für die Frage hier irrelevant und die structs müssten
> eigentlich auch ohne "packed" schon frei von Löchern sein. Der Rest ist
> normales C.
Naja, das ist eigentlich der einzige Knackpunkt.

> Dass Bitfields allgemein als schwach portabel gelten ist klar, aber ganz
> so schlimm ist es dann doch nicht, wenn man damit Portpins anspricht und
> damit die Architektur sowieso festnagelt.
Darauf zielte ich nämlich weiter oben schon ab. Einen Abstraktionslayer 
zu abstrahieren, ist ziemlich sinnfrei. Irgendwo muss man ja an die 
Hardware anbauen.

Reine Lehre wäre dann wohl nur die vollständige Kapselung in Methoden, 
sodass man schlimmstenfalls noch mit etwas Programmlogik nachhelfen 
kann, wenn die Zuordnung der Ports nicht mehr direkt gegeben ist.

von Peter D. (peda)


Lesenswert?

Franz schrieb:
> Du hast mich nicht richtig verstanden.
>
> Ich möchte die pins nur "Maskieren"
>
> nicht nur für
> LCD_LED = 1
> sondern auch für
> if(LCD_LED == 1)
> {

Geht doch.
Wie kommst Du darauf, das das nicht gehen soll?

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=835728#835728


Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.