Forum: Mikrocontroller und Digitale Elektronik Hilfe zum C-Code eines LCD-Moduls


von Stefanie (Gast)


Lesenswert?

Hi,

wisst ihr eine Lösung, wie ich an dieses Problem (jedenfalls ist es für
mich eins) am Besten rangehe?

Also an sich verwende ich das Ethernut-Betriebssystem für meinen
ATmega128. Dort ist auch schon ein LCD-Modul implementiert. Dort sind
die Daten für die 4-Bit Ansteuerung des Moduls von PD4-PD7 und bei mir
in echt leider total verteilt (D0=Pb5, D1=PE3, D2=PF1 und D2=PF0). In
der Headerdatei sind folgende Define-Anweisungen:

#define LCD_DATA_PORT   PORTD   /*!< Port output register of \ref
LCD_DATA_BITS. */
#define LCD_DATA_DDR    DDRD    /*!< Data direction register of \ref
LCD_DATA_BITS. */
#define LCD_DATA_BITS   0xF0    /*!< \brief LCD data lines, either
upper or
lower 4 bits. */

und so sieht z.B. ein Teil des Codes aus:

outp(inp(LCD_DATA_DDR) | LCD_DATA_BITS, LCD_DATA_DDR);
outp((inp(LCD_DATA_PORT) & ~LCD_DATA_BITS) | (nib & LCD_DATA_BITS),

    LCD_DATA_PORT);

Wie programmiere ich es nun, dass er unter LCD_DATA_BITS meine
richtigen PINS erkennt und was schreibe ich für LCD_DATA_PORT und
LCD_DATA_DDR.
Gibt es da einen Trick, oder muss ich den C-Code ändern. Habe leider
keine Möglichkeit die Pinbelegung zu ändern.

Für Hilfe wär ich sehr dankbar!!!

Gruß, Stefanie

von Vex (Gast)


Lesenswert?

na eigentlich kann man die Ansteuerung der Portpins so machen:

#define LCD_RS P0RTD.0
#define LCD_RW PORTD.1
bzw. ..
#define LCDPORT PORTD
#define EN 2
und dann evtl.(??) so ansteuern
LCDPORT.EN = 1;

und hier im Text
"#define LCD_DATA_BITS   0xF0    /*!< \brief LCD data lines, either
upper or
lower 4 bits. */"  denke ich, daß es für die Übertragung im Nibblemode
von 4 Bits gemeint war

l.G Ulli

von Stefanie (Gast)


Lesenswert?

Ja, dass ist mir schon irgendwie so klar.
Ich versteh nur nicht, wie ich es bei meinen Pins machen soll, da die
Datenpins auch noch auf verschiedene Ports verteilt sind.
Wie sieht den dann z.B. das Codebeispiel aus.
Ich denke, dass muss ich doch dann komplett umschreiben und wie sieht
sowas dann aus??
Gibt es da nicht vielleicht einen Trick?

von Rahul (Gast)


Lesenswert?

Du wirst wohl nicht drumherumkommen, das Zeug selberzubauen.
Du musst dir also darüber klar werden, was bei den einzelnen
Anweisungen passiert.

Bei
outp(inp(LCD_DATA_DDR) | LCD_DATA_BITS, LCD_DATA_DDR);

Passiert scheinbar nichts anderes als die Datenrichtung des für das LCD
vorgesehene Port festzulegen.

Du kannst dich aber am vorhanden Code (Timing etc) orientieren...
Es ist für den Lerneffekt sogar recht nützlich, nicht nur vorhanden
Code zu benutzen...

von Stefan (Gast)


Lesenswert?

Sind es viele solche Stellen?

Als Softwarelösung würde ich mir Wrapperfunktionen als Ersatz für
outp/inp schreiben und die an den Stellen verwenden, an denen die
Datenleitungen vom LCD angesprochen werden. Wenn es eine Stelle zentral
ist, dann direkt den C-Code dort ändern.

Hast du was anderes an PD4-PD7 dranhängen, was man im Code
berücksichtigen muss? Und wie ist die Umsetzung nochmal genau? D0 (LCD)
=> PD4 (Ist) => PB5 (soll)... Und bei PF1/PF0 ist kein Dreher drin, bzw.
könnte das auch in der "richtigen Reihenfolge" angeschlossen werden?

Andere Idee: Je nachdem was jetzt an PORTD hängt, könntest du
vielleicht auch einen Multiplexer in Hardware auf PD4-PD7 ansetzen.
Einen der Pins oben z.B. PB5 könntest du zum Umschalten benutzen. Das
LCD ist ja jetzt kein soo zeitkritisches Teil.

von Vex (Gast)


Lesenswert?

nen Multiplexer müsste man nicht unbedingt nehmen, da ja eigentlich mit
den Enable Signal am LCD dieses in den Tristate Zustand gesetzt wird.

von Rahul (Gast)


Lesenswert?

@Stephanie: wo liegen denn die Steuerleitungen für das LCD?
Vielleicht kann man so etwas am Aufbau drehen...

von Stefanie (Gast)


Lesenswert?

Also, E ist PF3 und RS ist PD7.
Aber Hardwaremäßig kann ich nichts mehr ändern, die Platine ist
komplett fertig aufgebaut und die anderen Pins sind belegt!

Ist es dann so, dass ich z.B. so eine Zeile

outp((inp(LCD_DATA_PORT) & ~LCD_DATA_BITS) | (nib & LCD_DATA_BITS),
LCD_DATA_PORT);

für jedes der 4 Datenbits schreiben muss??

von Rahul (Gast)


Lesenswert?

ich würde eine Funktion schreiben, an die du die "normalen" Werte
übergibts, und die sich dann darum kümmert.

void LCD_Data_put(unsigned char nib)
{
 if (nib & (1<<0)) PORTB |= (1<<5);
 else PORTB &= ~(1<<5);
 if (nib & (1<<1)) PORTE |= (1<<3);
 else PORTB &= ~(1<<3);
 if (nib & (1<<2)) PORTF |= (1<<1);
 else PORTB &= ~(1<<1);
 if (nib & (1<<3)) PORTF |= (1<<0);
 else PORTB &= ~(1<<0);
}

Übrigens verstehe ich den Konstrukt mit "outp(inp..." nicht so ganz.
Wieso lesen die erst den Eingangszustand des Ports ein, und schreiben
ihn dann an den Ausgang?

von Karl H. (kbuchegg)


Lesenswert?

> Übrigens verstehe ich den Konstrukt mit "outp(inp..." nicht so
ganz.
> Wieso lesen die erst den Eingangszustand des Ports ein, und
> schreiben ihn dann an den Ausgang?

Weil sie die anderen Port Bits nicht veraendern wollen/koennen.

Ist quasi ein ODER mit den bereits am Port vorhandenen Bits.

von Rahul (Gast)


Lesenswert?

> Übrigens verstehe ich den Konstrukt mit "outp(inp..." nicht so
ganz.
Also Kombination PORTD &= 0xF0; PORTD |= nib;

Ich hatte wohl einfach keine Lust...

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.