Hilfe zum C-Code eines LCD-Moduls

Gast #316482
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
Gast #316483
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
Gast #316484
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?
Gast #316485
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...
Gast #316486
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.
Gast #316489
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??
Gast #316490
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?
#316491
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.

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