Pins und Bits verknüpfen

Gast #4656065
Lesenswert?

Hallo,

ich fange gerade mit C an und versuche einzelne Pins meines Atmega8 
einem Bit der Ausgabevariable zuzuordnen.

der folgende Code macht komische Sachen, wo ist mein Denkfehler?
1
DDRC = (1 << DDRC1) |(0 << DDRC2) | (0 << DDRC3) | (0 << DDRC4) | (0 << DDRC5);
2
PORTC =         (1 << PORTC2)| (1 << PORTC3)| (1 << PORTC4)| (1 << PORTC5);
3

4
Ausgabe = (PINC5 << 0) | (PINC4 << 1) | (PINC3 << 2) | (PINC2 << 3);
5
//Ich will hier Bit 0-3 entsprechend der PINC's setzen

Mit freundlichem Gruß
Dietmar
Moderator (Firma: Titel) Persönliche Seite #4656083
Lesenswert?

Dietmar schrieb:
> Ausgabe = (PINC5 << 0) | (PINC4 << 1) | (PINC3 << 2) | (PINC2 << 3);
Das ist unüblich. Selber ausgedacht? Was macht der '<<' Operator in C?
Er schiebt das, was links von ihm steht um so viele Bits nach links, 
wie das angibt, was rechts von ihm steht.
Was ist z.B. PINC2? Wenn du genau nachschaust: es ist die Zahl 2. Und 
warum sollte man jetzt die Zahl 2 um 3 Stellen nach links schieben?

Also: tritt einen Schritt zurück und überleg, was denn eigentlich 
passiert...

Ein kleiner Tipp: so ein "0<<" ist eigentlich unnötig und wird nur 
eingesetzt, um zu zeigen: ich habe nichts vergessen, ich mache das 
bewusst so.
Hauptsächlich verwendet ist ein "1<<", also eine binäre 000000001, die 
um eine bestimmte Anzahl Bits nach links geschoben wird...
Gast #4656268
Lesenswert?

Okay, den Fehler erkenne ich jetzt.
Selbst mit langem studieren der Tutorials komme ich nicht darauf wie ich
den Bits einer Variable den logischen Status eines Portpins zuordnen 
kann.
Angeschlossen hab ich dort 3x BCD Codierschalter die bunt durcheinander 
mit dem µC verdrahtet sind.
In Bascom oder Luna würde ich es aus dem Stand schaffen, aber mit C ist 
das nicht so komfortabel.
so leider nicht: Ausgabe.1 = pinb.2

MfG Dietmar
Gast #4656299
Lesenswert?

> Selbst mit langem studieren der Tutorials komme ich nicht darauf
> wie ich den Bits einer Variable den logischen Status eines Portpins > zuordnen 
kann.

Wenn Du uns sagst, an welcher Stelle genau es hakt, dann könne wir 
helfen und evtl. das Tutorial an dieser Stelle noch verbessern.

Also: Ich versuche Dir mal Hinweise zu geben, wie Du den Text anschauen 
solltest und was Du uns mitteilen solltest, wo und wie es hakt.

Gehe Satz für Satz, Bild für Bild, durch.

Welchen Satz kannst Du im Moment noch nicht deuten? Welches Bild?

Was ist genau das Problem? Liegt es an einem bestimmten Teilsatz, einer 
Phrase oder einem Wort?

Oder falls es um ein Bild geht: Um welches grafische Element geht es?

Was ist genau das Problem? Ist es an sich keinem Begriff zuzuordnen? Ist 
unklar in welcher Beziehung es mit anderen Teilen des Bildes steht? Oder 
unklar, in welcher Beziehung es zu dem Text steht? Wenn letzteres: 
Welchen Teil des Textes?

Einfach den ersten Satz, das erste Bild bei dem es hakt, hier posten und 
erklären, was das Problem ist. Dann helfen hier bestimmt Leute weiter.
#4656308
Lesenswert?

Dietmar schrieb:
> Ausgabe = (PINC5 << 0) | (PINC4 << 1) | (PINC3 << 2) | (PINC2 << 3);

PINCx sind defines in avr/io.h. Diese werden vor dem Kompilieren durch 
den Präprozessor ersetzt.
1
#define PINC5 5
Dies bedeutet nun, dass überall in deinem Code (sofern der Header 
eingebunden ist), PINC5 durch 5 ersetzt wird. Dies geschieht analog für 
alle defines.

Daher hast du über diese defines keinen direkten Zugriff auf die Pins, 
das musst du von Hand erledigen. Die defines dienen nur dazu, den Code 
lesbarer und portabler gestalten zu können.
Gast #4656309
Lesenswert?

Ach ja. Es wird auch hilfreich sein, wenn Du das, was Du zu verstehen 
meinst, einmal in eigenen Worten (und Bildern) beschreibst. So können 
wir auch noch besser erkennen, wo es hakt, selbst wenn Du das nicht 
ausdrücklich beschreiben kannst.
Gast #4656835
Lesenswert?

Guten Morgen,

ich habe die Pins 5/4/3/2 vom PortC mit der Wertigkeit 1/2/4/8
Meine aktuelle Idee ist es:
- den Port komplett abzufragen und die einzelnen Bits zu maskieren 
(logisch und)
- dann hab ich die Information welchen logischen Zustand mein Pin hat
- das ganze in eine If-Abfrage und dann das entsprechende Bit in meiner 
Ausgabevariable ändern.

Das Bit setzten muss ich aber noch komfortabler gestalten als ich es in 
der Ausgaberoutine programmiert habe
1
//macros
2
#define Heizung_an (PORTC |= (1 << PORTC1));    // Funktion um das Relais zu schalten
3
#define Heizung_aus (PORTC &= ~(1 << PORTC1));    // Funktion um das Relais zu schalten

Gruß
Dietmar
(Firma: Vescomp) #4657122
Lesenswert?

Dietmar schrieb:
> Bei den anderen sind die Pins auch an verschiedenen Ports...

 Hier, auf die Schnelle, sollte funktionieren:
1
#define chkB(vVar, pPin, vBit)  ((-((PINB >> pPin) & 1) ^ vVar) & (1 << vBit))
2
#define chkC(vVar, pPin, vBit)  ((-((PINC >> pPin) & 1) ^ vVar) & (1 << vBit))
3
#define chkD(vVar, pPin, vBit)  ((-((PIND >> pPin) & 1) ^ vVar) & (1 << vBit))
4

5
int main(void)
6
{
7
 Ausgabe ^= chkB(Ausgabe, 5, 0);    //* PinB.5 ==> Ausgabe.0
8
 Ausgabe ^= chkB(Ausgabe, 4, 1);
9
 Ausgabe ^= chkB(Ausgabe, 3, 2);
10
 Ausgabe ^= chkB(Ausgabe, 2, 3);
11

12
 Ausgabe ^= chkC(Ausgabe, 2, 4);    //* PinC.2 ==> Ausgabe.4
13

14
 Ausgabe ^= chkD(Ausgabe, 7, 5);    //* PinD.7 ==> Ausgabe.5
15
}

 Es geht wahrscheinlich schöner aber das macht auch den Job.

 EDIT:
 Oder du machst Macros daraus:
1
#define chkB(vVar, pPin, vBit)  ((-((PINB >> pPin) & 1) ^ vVar) & (1 << vBit))
2
#define chkC(vVar, pPin, vBit)  ((-((PINC >> pPin) & 1) ^ vVar) & (1 << vBit))
3
#define chkD(vVar, pPin, vBit)  ((-((PIND >> pPin) & 1) ^ vVar) & (1 << vBit))
4

5
#define mapB(vVar, pPin, vBit) { vVar ^= chkB(vVar, pPin, vBit); }
6
#define mapC(vVar, pPin, vBit) { vVar ^= chkC(vVar, pPin, vBit); }
7
#define mapD(vVar, pPin, vBit) { vVar ^= chkD(vVar, pPin, vBit); }
 und dann:
1
int main(void)
2
{
3
 mapB(Ausgabe, 5, 0);    //* PinB.5 ==> Ausgabe.0
4

5
 mapC(Ausgabe, 2, 4);    //* PinC.2 ==> Ausgabe.4
6

7
 mapD(Ausgabe, 7, 5);    //* PinD.7 ==> Ausgabe.5
8
}

 EDIT2:
 Mit macros wird jedesmal der zugehörige Code übersetzt, falls du
 eine function daraus machst (Hausaufgabe) wird der entsprechende
 Codeschnipsel nur aufgerufen, etwa so:
1
  Ausgabe = mapB(5, 0);    //* PinB.5 ==> Ausgabe.0
 oder so:
1
  Ausgabe = map(PINB, 5, 0);    //* PinB.5 ==> Ausgabe.0

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