Timo wrote:
> Ich seh schon zu komplex meine Bitte.
Das ist in der Tat nicht so einfach.
Die Hauptarbeit besteht in der Auswertung. Also im Code
der mit diesen Definitionen dann tatsächlich die Bits
am Port setzt.
>
1 | > #define LCD_PORT PORTC
|
2 | > #define LCD_DATA0_PORT LCD_PORT
|
3 | > #define LCD_DATA0_PIN 1
|
4 | >
|
>
> Damit deffiniere ich doch für das Datenbit DATA0 die Adresse. In diesem
> Fall liegt Data0 an PC1.
>
> Es handelt sich hierbei doch nur um eine Zuordnung zur besseren
> Übersicht. Hinter dieser Diffinition müssen nun doch auch noch
> "Adressen" liegen.
>
> Für PIN1 zum Beispiel sowas wie 0x01. Wie geht man nun weiter vor?
Du musst dir ansehen, wo LCD_DATA0_PORT im Code benutzt wird.
Die #define da oben sind ja nur ANweisungen für Textersetzungen.
Irgendwo im Code steht dann mal:
LCD_DATA0_PORT = irgendwas
und dort passiert dann die Umsetzung deiner Definitionen in
den realen Code.
Aber wie gesagt: Den Port auf diese Art variabel zu halten,
ist nicht weiter schwer. Bei den einzelnen Bits wirds schon
haariger.
Ein Beispiel:
Du machst eine 4 Bit Ausgabe für das Datennibbel.
Normalerweise würdest du das so schreiben:
unsigned char Nibble;
Nibble = Byte & 0x0F; // um das untere Nibbel zu extrahieren
LCD_PORT &= 0xF0; // mal am Port die unteren 4 Bits definiert
// auf 0 setzen
LCD_PORT |= Nibble; // und die 4 Bits neu setzen
Willst du jetzt die Pins auch noch variabel halten, dann
wird das komplizierter, weil ja
* a priori keine Beziehung zwischen den Datenbits und den zu
beeinflussenden Port-Bits besteht
* die einzelnen Bits ja noch nicht mal am selben Port liegen
muessen
Also muss jedes Datenbit einzeln betrachtet werden. Ist es gesetzt,
dann muss auch das vereinbarte Port-Bit am vereinbarten Port
gesetzt werden und umgekehrt.
unsigned char Nibble;
Nibble = Byte & 0x0F; // um das untere Nibbel zu extrahieren
if( Nibble & 0x01 ) // das unterste Bit ist gesetzt
LCD_DATA0_PORT |= ( 1 << LCD_DATA0_PIN );
else
LCD_DATA0_PORT &= ~( 1 << LCD_DATA0_PIN );
if( Nibble & 0x02 ) // das nächste Bit ist gesetzt
LCD_DATA1_PORT |= ( 1 << LCD_DATA1_PIN );
else
LCD_DATA1_PORT &= ~( 1 << LCD_DATA1_PIN );
if( Nibble & 0x04 ) // das dritte Bit ist gesetzt
LCD_DATA2_PORT |= ( 1 << LCD_DATA2_PIN );
else
LCD_DATA2_PORT &= ~( 1 << LCD_DATA2_PIN );
if( Nibble & 0x08 ) // das vierte Bit ist gesetzt
LCD_DATA3_PORT |= ( 1 << LCD_DATA3_PIN );
else
LCD_DATA3_PORT &= ~( 1 << LCD_DATA3_PIN );
Auf sowas läuft das dann immer hinaus. Jedes Bit muss
einzeln bearbeitet werden.
Mit dieser Flexibilität erkauft man sich dann allerdings einen
Nachteil:
Im Falle von
LCD_PORT |= Nibble; // und die 4 Bits neu setzen
werden die 4 Bits gleichzeitig gesetzt.
Bei der flexibleren Lösung werden die Bits aber hintereinander
gesetzt.
Bei einer LCD Ansteuerung ist das noch kein Problem, aber wenn
am Port ein Gerät hängt, bei dem dieser Timing Unterschied nicht
egal ist, dann hat man ein Problem. Mann könnte dann zb.
im Code abfragen (ev. sogar mit dem Präprozessor) ob die
Ports für Bit0, Bit1, Bit2, Bit3 alle gleich sind, und dann
wieder zusammenfassen. Aber auch das artet in Arbeit aus
(sowohl für den Programmierer als auch für das Programm/Compiler)
Wie gesagt: Flexibilität kann manchmal schon sehr aufwändig
werden.