Ports Splitten

Gast #284883
Lesenswert?

Hallo,

Ich mache gerade meine ersten Schritte mit WinAVR und C. Ich habe
bereits einzelne Ports erfolgreich angesprochen, nun zu meiner Frage
Problem:

Ich möchte gerne bei einem Atmage8 ein "virtuelles Port" durch C
erstellen.
Genau genommen so:
PB.4 = Bit1
PB.5 = Bit2
PC.0 = Bit3
PC.1 = Bit4
PC.2 = Bit5
PC.3 = BIT6
PC.4 = Bit7
PC.5 = Bit8

Es soll dann die Möglichkeit bestehen das virtuelle Port mit einem Byte
zu füttern, und dieses Byte soll dann richtig an den einzelnen Pins von
Portb und Portc rauskommen.

Ich war bereits fleißig und hab gegoogelt und auch ihr im Forum
folgenden Beitrag gefunden:

http://www.mikrocontroller.net/forum/read-2-219856.html#new

darin steht folgende Lösung:
#define MYPORT ((PINB & 0x01)<<8 | (PINB & 0x04)<<7 | ....)

uint8_t bla;
bla = MYPORT;

Leider, da ich c anfänger bin versteh ich das leider nicht ganz:

(PINB & 0x01)<<8

Was bedeutet diese Zeile den genau?

(PINB & 0x01) bedeutet dies, dass Pinb.0 angesprochen werden soll?

...<<8 bedeutet dies, dass bit8 von myport zugeordnet wird?

Demnach sollte das bei mir dann so gehen?:

#define MYPORT ((PORTC & 0x20)<<8 | (PINC & 0x10)<<7 |
(PINC & 0x08)<<6 | (PINC & 0x04)<<5 | (PINC & 0x02)<<4 |
(PINC & 0x01)<<3 | (PINB & 0x20)<<2 | (PINB & 0x10)<<1 | )

Stimmt das?Danke schon mal!
Gast #284884
Lesenswert?

Sollen natürlich Ausgänge sein!

Also dann so:

#define MYPORT ((PORTC & 0x20)<<8 | (PORTC & 0x10)<<7 |
(PORTC & 0x08)<<6 | (PORTC & 0x04)<<5 | (PORTC & 0x02)<<4 |
(PORTC & 0x01)<<3 | (PORTB & 0x20)<<2 | (PORTB & 0x10)<<1 | )

uint8_t test;
MYPORT = test;
Moderator Persönliche Seite #284885
Lesenswert?

1
#define MYPORT(x) \
2
  do { \
3
    PORTC = (PORTC & 0xc0) | ((x) & 0xfc) >> 2); \
4
    PORTB = (PORTB & 0xcf) | ((x) & 3) << 4); \
5
  } while(0)
6
...
7
MYPORT(test);

Verstehen musst du es bitte selbst.  Lies dir im C-Buch oder -Artikel
deiner Wahl das Kapitel über Bitoperatoren durch.  Die Bedeutung des
do ... while(0)-Konstrukts ist hier im Forum schon paarmal durchgekaut
worden.  Nur kurz dazu: überleg dir, wie sich der Makro verhält, wenn
du
1
if (some_condition)
2
  MYPORT(test);
3
else
4
  do_something_else();

schreibst.
Gast #284889
Lesenswert?

ich komm da nicht so zurecht, bitte helft mir! Hier mal nochmal eine
Idee von mir:

#include <io.h>
#include <inttypes.h>

void setport (unsigned char x)



main()
{
DDRC = 0xff;
DDRB = 0xff;


setport(0x0f)

};

void setport(unsigned char x)
{


(PORTC & 0x20)<<Myport.b8;
(PORTC & 0x10)<<Myport.b7;
(PORTC & 0x08)<<Myport.b6;
(PORTC & 0x04)<<Myport.b5;
(PORTC & 0x02)<<Myport.b4;
(PORTC & 0x01)<<Myport.b3;
(PORTB & 0x20)<<Myport.b2;
(PORTB & 0x10)<<Myport.b1;
};

typedef struct {
  unsigned char b1:1;
  unsigned char b2:1;
  unsigned char b3:1;
  unsigned char b4:1;
  unsigned char b5:1;
  unsigned char b6:1;
  unsigned char b7:1;
  unsigned char b8:1;
} Myport;
#284891
Lesenswert?

Jörg hat Recht.
Dir fehlen zuviele Grundlagen. Lies ein C-Buch.

> (PINB & 0x01) bedeutet dies, dass Pinb.0 angesprochen werden soll?

Nein. Es bedeutet, dass der Wert von PINB geholt wird und
mit einer Maske von (hex) 01 ein einzelnes Bit isoliert wird
(alle anderen Bits werden definiert auf 0 gesetzt).

> ...<<8 bedeutet dies, dass bit8 von myport zugeordnet wird?

Nein: << ist in C der Links-Schiebe-Operator
Der vorher erhaltene Wert wird um 8 bits nach links geschoben.
Gast #284893
Lesenswert?

Hallo Sebastian,

ich hatte ein ähnliches Problem.
Beschäftige mich nach über 20 Jahren zum ersten mal wieder mit uC´s.
Teilweise war das LCD mit 3 Segmenten so an einen Atmega16
angeschlossen, dass ein Segment auf 3 Ports verteilt war.
Den Tipp habe ich von einem Kollegen bekommen.

Du kannst das ganze lösen indem du mit Shift und logischen Operatoren
arbeitest. z.B.
PORTB = (LCD.d2&0x1c)|((LCD.d3<<4)&0xc0)|((LCD.d1>>3)&0x03)|(1>>PB5);

LCD.dx ist die Variable die die Segmentausgabe enthält.
Wie du siehst war das PORTB auf 3 Segmente verteilt PB5 steuerte den
Dezimal Punkt des Displays.
z.B. PB2-PB4 bildeten die bits 2-4 von LCD.d2 mit
(LCD.d2&0x1c) maskierst du die restlichen Bits
PB6 und PB7 bildeten die Bits 2 und 3 von LCD.d3 mit
((LCD.d3<<4)&0xc0 shiftest du die Stellen auf die richtige Position für
dein PORTB und maskiert Sie wieder durch die Oder Verknüpfung werden Sie
in dein PORTB stellenrichtig integriert. usw.
Damit kannst du jede Verdrahtung realisieren.

Gruß
Bernhard

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren