Hallo,
bin grad ein bisschen durcheinandergekommen bei der LCD
Ansteuerungsroutine, die es hier gibt.
Es wird ja erwartet, dass alle Pins an einem Port liegen und
aufeinanderfolgend sind. Das trifft bei mir auch zu, jedoch erwartet das
Programm für DB4-7 die Pins PB0-3. Bei mir liegt DB4-7 jedoch auf den
Pins PB3-0. Also genau umgekehrt.
Hab nun angefangen mir Bitweise die lcd-routines.c anzusehen bzw.
genauer was in der Funktion lcd_out() passiert.
z.B. wird mit
1
lcd_out(LCD_SOFT_RESET);
auf DB4 und DB5 ein Bit gesetzt. Mit
1
LCD_PORT|=(data>>(2-LCD_DB));
kriegt man das auch wieder hin. Werden nun jedoch andere Daten
übergeben, stimmt das alles nicht mehr.
1
lcd_out(LCD_SET_FUNCTION|
2
LCD_FUNCTION_4BIT);
Hier z.B. wird mit der obigen Veränderung Bit 3, anstatt Bit 1 gesetzt
(von 0 gezählt), also an DB4, anstatt an DB5.
Hat jemand eine ganz einfache Methode um das zu umgehen/anzupassen, oder
sollte ich mich lieber nach einer anderen Routine umsehen?
gru schrieb:> Hallo,>> bin grad ein bisschen durcheinandergekommen bei der LCD> Ansteuerungsroutine, die es hier gibt.>> Es wird ja erwartet, dass alle Pins an einem Port liegen und> aufeinanderfolgend sind. Das trifft bei mir auch zu, jedoch erwartet das> Programm für DB4-7 die Pins PB0-3. Bei mir liegt DB4-7 jedoch auf den> Pins PB3-0. Also genau umgekehrt.
Man kann es in Software ausgleichen, indem man die Bits entsprechend in
sich spiegelt. Aber eigentlich ist das ein Fall, den man besser 'im
Kabel' löst.
> kriegt man das auch wieder hin.
Nein, kriegst du nicht.
Du brauchst eine Spiegelung und kein Verschieben.
Du argeumentierst gerade so: da 2+2 gleich 4 ist und das auch dasselbe
ist wie 2*2, braucht eigentlich kein Mensch Multiplikation.
> Werden nun jedoch andere Daten> übergeben, stimmt das alles nicht mehr.
Du zäumst das Pferd an der falschen Stelle auf.
Alles was dich interessiert, ist die eine Funktion, die 1 Byte in die 4
Bits zerlegt und auf die Reise schickt. Diese 4 Bits musst du in sich
spiegeln, um deine Torheit die Datenleitungen genau falsch herum
anzuschliessen, wieder auszugleichen. So etwas macht man nicht ohne Not,
die Bitnummern zu vertauschen. Und wenn dann nur mit vorgehaltener
Waffe.
Die Platine ist leider fertig und das Display wird direkt aufgesteckt.
Die Pins jetzt noch umzulenken wäre eine sehr unschöne Lösung.
Den Inhalt von data spiegeln wäre natürlich eine Lösung, aber ist das
denn auch so ohne weiteres möglich? bzw. wie genau?
Hmm, sonst wäre mein weiterer Ansatz die Bitmasken in der LCD
Headerdatei zu ändern, sodass es wieder passen dürfte.
gru schrieb:> Die Platine ist leider fertig und das Display wird direkt aufgesteckt.> Die Pins jetzt noch umzulenken wäre eine sehr unschöne Lösung.
Es gibt nichts was man nicht mit Teppichmesser und Fädeldraht lösen
könnte.
In Zukunft wird es dich lehren erst mal einen Testaufbau zu machen, ehe
du dann eine Platine ätzt (oder ätzen lässt). Das werd ich sowieso nie
verstehen, wie man ohne Vortest, ob auch alles funktioniert, gleich mal
eine Platine ätzt.
> Den Inhalt von data spiegeln wäre natürlich eine Lösung, aber ist das> denn auch so ohne weiteres möglich? bzw. wie genau?
Du musst hier
1
staticvoidlcd_out(uint8_tdata)
2
{
3
data&=0xF0;// obere 4 Bit maskieren
4
5
// --------------------------------- <<<<<<<<<
6
7
LCD_PORT&=~(0xF0>>(4-LCD_DB));// Maske löschen
8
LCD_PORT|=(data>>(4-LCD_DB));// Bits setzen
9
lcd_enable();
10
}
eingreifen (das ist eine Möglichkeit).
Die Bits müssen die Plätze tauschen
1
+---+---+---+---+---+---+---+---+
2
| | | | | | | | |
3
+---+---+---+---+---+---+---+---+
4
| | | |
5
| | | |
6
| | | /
7
| | / /
8
\ \ / /
9
\ \ /
10
\ / \
11
\ / \
12
| \ |
13
|/ \ |
14
/ \|
15
/| \
16
/ | |\
17
| | | \
18
| | | |
19
+---+---+---+---+---+---+---+---+
20
| | | | | | | | |
21
+---+---+---+---+---+---+---+---+
22
23
Bit 7 kommt nach Bit 4
24
Bit 6 kommt nach Bit 5
25
Bit 5 kommt nach Bit 6
26
Bit 4 kommt nach Bit 7
Das 'spiegelt' die Bits genau so, dass durch die nochmalige Spiegelung
in der Hardware wieder alles richtig rauskommt.
> Hmm, sonst wäre mein weiterer Ansatz die Bitmasken in der LCD> Headerdatei zu ändern, sodass es wieder passen dürfte.
Das ist Quatsch. Und zwar richtig großer Quatsch.
Mach es richtig!
Hi
>Den Inhalt von data spiegeln wäre natürlich eine Lösung, aber ist das>denn auch so ohne weiteres möglich? bzw. wie genau?
so:
Beitrag "Re: LCD Datenleitungen invertieren"
MfG spess
spess53 schrieb:> Hi>>>Den Inhalt von data spiegeln wäre natürlich eine Lösung, aber ist das>>denn auch so ohne weiteres möglich? bzw. wie genau?>> so:>> Beitrag "Re: LCD Datenleitungen invertieren"
Die spiegelt allerdings 8 Bit und ist somit hier nicht anwendbar.
eine andere Möglichkeit wäre, die eigentliche Ausgabe
1
LCD_PORT|=(data>>(4-LCD_DB));// Bits setzen
in 4 Einzelbitoperationen aufzudröseln und sich inklusive der
gewünschten Verschiebung durch LCD_DB zu überlegen, wo welches der 4
interssierenden Bits wieder auftauchen muss.
Es gibt sicher auch eine clevere Methode wie man mit Bitoperationen die
4 Bits spiegeln kann (wie es im 8 Bit Beispiel gemacht wurde), nur weiß
ich die nicht auswendig und bin jetzt auch zu faul, das auszutüfteln.
Eine Konstantentabelle mit 16 Einträgen wäre auch eine Lösung.
uint8_t NibbleTabelle[] = { 0xF0, 0xE0, 0xD0, 0xC0, 0xB0 ... etc. bis
0x10, 0x00}
Beim Zugriff wird das High-Nibble des auszugebenden Datenworts als Index
verwendet, so daß aus
LCD_PORT = Wert;
ein
LCD_PORT = NibbleTabelle[(Wert >> 4) & 0xF];
werden kann.
Allerdings ist der Shift-Operator eine recht "teuere" Rechenoperation;
der Compiler könnte allerdings erkennen, daß hier auf das High-Nibble
zugegriffen wird und swap verwenden, dann ist das ganze sogar recht
flott.
Auf diese Art und Weise ließen sich auch einzelne vertauschte
Datenleitungen korrigieren.
Karl Heinz schrieb:> Die spiegelt allerdings 8 Bit und ist somit hier nicht anwendbar.
Natürlich ist die (mit einer klitzekleinen Anpassung) hier anwendbar.
Die letzte der drei Zeilen einfach durch ein "n = n & 0xf;" ersetzen.
Das spart sogar noch ein paar Takte. Jedem, der versteht, was da
passiert, ist das sofort klar.
Es bleibt allerdings die unbestreitbare Tatsache, daß es trotzdem recht
teuer ist und ohne wirkliche Not nicht getan werden sollte, da gebe ich
dir absolut Recht. EIN falsch angelöteter Stecker ist sicher kein
hinreichender Grund. 1000 oder vielleicht auch nur 100 allerdings
schon...
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang