Forum: Mikrocontroller und Digitale Elektronik Port-Pins global in C definieren?


von El Noob (Gast)


Lesenswert?

Hallo alle zusammen!

Ich habe folgendes Problem, auf einem vorgefertigten Board sind beim 
PORTE die Anschlüsse verschoben und somit leuchten die LEDs wie 
folgendermaßen:

                 PORTE = (0x01);        // LED 8   PE0
     PORTE = (0x02);  // LED 1   PE1
     PORTE = (0x04);  // LED 2   PE2
     PORTE = (0x08);  // LED 3   PE3
     PORTE = (0x10);  // LED 4   PE4
     PORTE = (0x20);  // LED 5   PE5
     PORTE = (0x40);  // LED 6   PE6
     PORTE = (0x80);  // LED 7   PE7

Ich hätte es natürlich gerne so:

                 PORTE = (0x01);        // LED 1   PE0
     PORTE = (0x02);  // LED 2   PE1
     PORTE = (0x04);  // LED 3   PE2
     PORTE = (0x08);  // LED 4   PE3
     PORTE = (0x10);  // LED 5   PE4
     PORTE = (0x20);  // LED 6   PE5
     PORTE = (0x40);  // LED 7   PE6
     PORTE = (0x80);  // LED 8   PE7

Umlöten kann man da leider garnix, ist auch nicht von mir das Board. Wie 
kann ich die Ports nun vor der main global in C definieren um diesem 
f**k-up zu entgehen? Oder gibt es andere Lösungsansätze?

von Guest (Gast)


Lesenswert?

Du machst einfach

#define LED_DDR DDRE
#define LED_PORT PORTE
#define LED1 (1<<7)
#define LED2 (1<<0)
...

Und dann:

LED_PORT |= LED1

von El Noob (Gast)


Lesenswert?

Hmm? Danke erst mal für die Antwort aber das verstehe ich jetzt 
überhaupt nicht, wozu LED definieren? Also so sieht es jetzt zu 
Testzwecken aus:
1
#include <avr/io.h>
2
3
int main(void)
4
{
5
  DDRE  = 0xFF;
6
  PORTE = 0xFF;
7
8
    while(1)
9
    {
10
                 PORTE = (0x01);        /* LED 8 */
11
     PORTE = (0x02);  /* LED 1 */
12
     PORTE = (0x04);  /* LED 2 */
13
     PORTE = (0x08);  /* LED 3 */
14
     PORTE = (0x10);  /* LED 4 */
15
     PORTE = (0x20);  /* LED 5 */
16
     PORTE = (0x40);  /* LED 6 */
17
     PORTE = (0x80);  /* LED 7 */
18
    }
19
}
Im Kommentar steht nur wie es jetzt gerade ist, die erste LED soll 
natürlich mit PE0 und die zweite mit PE1 ... leuchten.

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

1
#include "sbit.h"
2
3
#define LED8 PORT_E0
4
#define LED1 PORT_E1
5
// ...
6
  LED8 = 1; // LED 8 an
7
  LED1 = 1; // LED 1 an

von micha (Gast)


Lesenswert?

El Noob schrieb:
> Im Kommentar steht nur wie es jetzt gerade ist, die erste LED soll
> natürlich mit PE0 und die zweite mit PE1 ... leuchten.

Du kannst nicht die physikalische Port-LED Zuordnung (LED1 == PE1) 
per Programm änderen (jedenfalls nicht bei AVRs). Was du allerdings 
machen kannst (und was oben schon gesagt wurde), sorg dafür, dass die 
physikalische Zuordnung richtig auf die logische/gewünschte Zuordnung 
abgebildet wird.

Anstatt "PORTE = (0x01);" schreibst Du einfach "LED_ON(LED1);" oder 
"LED_OFF(LED1);"(kann man sowiso besser lesen).

Dann musst Du noch die entsprechenden Funcktionen/Makros "LED_ON" und 
"LED_OFF" definieren z.B.
1
#define LED_PORT PORTE
2
#define LED1 PE2
3
#define LED2 PE4
4
....
5
6
#define LED_ON(led)  LED_PORT |= (1<<(led))
7
#define LED_OFF(led) LED_PORT &= ~(1<<(led))

von Karl H. (kbuchegg)


Lesenswert?

.... und wenn du das dann auch noch vernünftig machen willst, dann 
benutzt du von vorne herein gleich Namen, die die Funktion der LED 
wiederspiegeln (egal ob du das jetzt mit PeDas Lösung machst oder die 
reine Makrolösung bevorzugst.)

Denn dann steht im Code beispielsweise
1
   ...
2
   LED_ON( ERROR_LED );
3
   LED_OFF( READY_LED );
4
   ...

und das dokumentiert im Code selber schon viel besser, was der Zweck des 
Code-Stückes ist. Nämlich in diesem Fall dem Benutzer das Auftreten 
eines Fehlers durch Aufleuchten der mit 'Error' beschrifteten LED 
anzuzeigen.

Das diese LED natürlich an irgendeinem Portpin hängen muss, ist klar. 
Aber diese Information gibt es nur an einer einzigen Stelle im Programm 
zusammengefasst. Nämlich hier
1
#define ERROR_LED   PE2
2
#define READY_LED   PE4

Dem restlichen Programmtext ist das piepschnurzegal, ob eine spezielle 
LED nun an PE2 oder doch an PE0 hängt. Diese Begriffe kommen im Programm 
selber nicht mehr vor, sondern nur noch ihre durch #define eingeführten 
Ersatznamen. Das ist zum einen in der Tradition des 'Code sollte nach 
Möglichkeit selbstkommentierend sein' und zum anderen ist es eine große 
Hilfe, wenn die LED (am selben Port) auf einen anderen Pin 'umziehen' 
muss. Dann ändert man einfach nur dieses eine #define und hat diese 
Anpassung erledigt.

> ... aber das verstehe ich jetzt überhaupt nicht,
> wozu LED definieren? ....
> ...
> ... Im Kommentar steht nur wie es jetzt gerade ist

genau das ist der Zweck: Den Kommentar komplett überflüssig zu machen. 
Denn dann kann man ihn weglassen ohne dass das Programm weniger schlecht 
zu lesen wäre. Das Weglassen können ist wiederrum etwas gutes. Denn ein 
Kommentar, der nicht dasteht, kann auch nicht falsch sein. Wenn du die 
Wahl hast, zwischen
1
   PORTE |= ( 1 << PE2 );     // Error LED einschalten

und
1
   LED_ON( ERROR_LED );

dann ist zweites zu bevorzugen. Denn hier steht bereits im Code das, was 
sonst mühsam (und fehlerträchtig) kommentiert werden müsste. Im Code 
steht das, was tatsächlich passiert. Denn ob der Kommentar korrekt ist 
oder nicht hängt ganz allein lediglich von deiner Disziplin ab, jegliche 
Codeänderungen auch auf den Kommentar auszudehen.

von Oliver (Gast)


Lesenswert?

Der wesentlich Vorteil von
1
   LED_ON( ERROR_LED );

ist, daß man damit immer weiß, was gemeint ist, egal, ob die LED nun 
gegen VCC oder gegen Masse schaltet.

Oliver

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.