mikrocontroller.net

Forum: Compiler & IDEs Ports Splitten


Autor: Sebastian (Gast)
Datum:

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

Autor: Sebastian (Gast)
Datum:

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

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

Bewertung
0 lesenswert
nicht lesenswert
#define MYPORT(x) \
  do { \
    PORTC = (PORTC & 0xc0) | ((x) & 0xfc) >> 2); \
    PORTB = (PORTB & 0xcf) | ((x) & 3) << 4); \
  } while(0)
...
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
if (some_condition)
  MYPORT(test);
else
  do_something_else();

schreibst.

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

Bewertung
0 lesenswert
nicht lesenswert
p.s.: Sonderlich effektiv wird das Ganze nicht sein.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mh... danke!
aber da versteh ich jetzt leider nich viel...
also geht mein vorschlag nicht, oder?

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

Bewertung
0 lesenswert
nicht lesenswert
> also geht mein vorschlag nicht, oder?

Ja, er geht nicht.

Autor: Sebastian (Gast)
Datum:

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

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

Bewertung
0 lesenswert
nicht lesenswert
Nein, das geht alles so nicht, glaub's doch.

Du kannst meinen Macro gern nehmen, auch als ,blackbox', aber
bevor du weiter mit trial&error irgendwelchen unsinnigen (sorry)
Code zusammennagelst, bitte, bitte, lies' dir die Geschichte mit
den Bitmanipulationsoperatoren in einem ordentlichen C-Buch durch.

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

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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst auch schon sehr viel lehrreiches im hiesigen AVR-GCC Tutorial
finden:

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Autor: Bernhard Ahorn (Gast)
Datum:

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

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.