Hilfe zum C-Code eines LCD-Moduls

Gast #316482
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
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
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
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
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
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
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?
> Ü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.
Gast
> Übrigens verstehe ich den Konstrukt mit "outp(inp..." nicht so
ganz.
Also Kombination PORTD &= 0xF0; PORTD |= nib;

Ich hatte wohl einfach keine Lust...

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 20 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.