Hallo,
für ein Projekt in der Schule muss ich ein LCD zum laufen bringen. Die
Software soll keine fertigen Librarys verwenden, die nicht zum AVR-GCC
gehören.
Ich habe hier das Tutorial zum LCD gelesen und auch das Datenblatt von
Hitachi
http://www.alldatasheet.com/datasheet-pdf/pdf/63673/HITACHI/HD44780.html,
weil das LCD HD44780 kompatibel ist. Aufrgund der Aufschrift hinten
drauf (1602A) schließe ich darauf, dass der im Datenblatt auf Seite 18
gemeinte Zeichensatz verwendet wird.
Das LCD funktioniert, ich habe es mit einer Hex Datei aus dem Internet
getestet, am Kontrast oder der Verbindung wird es also nicht liegen.
Mein Programm sieht so aus:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
/* Connections:
4
*
5
* D4->PORTD0
6
* D5->PORTD1
7
* D6->PORTD2
8
* D7->PORTD3
9
* E-> PORTD4
10
* RW->PORTD5
11
* RS->PORTD6
12
*/
13
#define LCD_DATA_PORT PORTD
14
#define E PD4
15
#define RW PD5
16
#define RS PD6
17
18
voide_state(void)
19
{
20
_delay_us(20);
21
LCD_DATA_PORT|=(1<<E);
22
_delay_us(20);
23
LCD_DATA_PORT&=~(1<<E);
24
}
25
26
voidwrite_data(intinput)
27
{
28
inthigh_bit,low_bit;
29
LCD_DATA_PORT|=(1<<RS);//signal to write chars on display
30
high_bit=(input&0xF0);//get the higher 4 bit
31
low_bit=(input&0x0F);//get the lower 4 bit
32
LCD_DATA_PORT=high_bit;//send the higher 4 bit
33
e_state();
34
LCD_DATA_PORT=low_bit;//send the lower 4 bit
35
e_state();
36
}
37
38
voidwrite_command(intinput)
39
{
40
inthigh_bit,low_bit;
41
LCD_DATA_PORT&=~(1<<RS);//signal to write command
42
high_bit=(input&0xF0);//get the higher 4 bit
43
low_bit=(input&0x0F);//get the lower 4 bit
44
LCD_DATA_PORT=high_bit;//send the higher 4 bit
45
e_state();
46
LCD_DATA_PORT=low_bit;//send the lower 4 bit
47
e_state();
48
}
49
50
voidsend_string(charinput)
51
{
52
intoutput;
53
output=(int)input;
54
write_data(output);
55
}
56
57
voidsplit_string(char*input)
58
{
59
while(*input!='\0')
60
{
61
send_string(*input++);
62
}
63
}
64
65
voidinit_LCD(void)
66
{
67
_delay_us(100);//startup time
68
write_command(0b00110000);//8-Bit mode
69
_delay_us(45);
70
write_command(0b00110000);//8-Bit mode
71
_delay_us(45);
72
write_command(0b00110000);//8-Bit mode
73
_delay_us(45);
74
write_command(0b00101000);//4-Bit mode 2 line display 5x7 ont type
75
_delay_us(45);
76
write_command(0b00001111);//Display on, curser on, curser blink
Sven S. schrieb:> Kann mir jemand sagen, wo da der Fehler im Programm liegt?
Beim Init kannst Du noch kein Write_Command nehmen, sondern nur
Write_Nibble.
Write_Command setzt voraus, daß Du bereits im 4-Bit Mode bist, aber das
ist ja noch unbestimmt. Und spätestens nach der Schaltung in 8-Bit bist
Du es definitiv nicht mehr.
Vielen Dank schon mal für die Antworten.
>Beim Init kannst Du noch kein Write_Command nehmen, sondern nur>Write_Nibble.>Write_Command setzt voraus, daß Du bereits im 4-Bit Mode bist, aber das>ist ja noch unbestimmt. Und spätestens nach der Schaltung in 8-Bit bist>Du es definitiv nicht mehr.
Ok ich habe es mal so versucht:
1
voidinit_LCD(void)
2
{
3
_delay_us(100);//startup time
4
LCD_DATA_PORT=0b0010;//4-Bit mode
5
_delay_us(45);
6
LCD_DATA_PORT=0b0010;//4-Bit mode
7
_delay_us(45);
8
LCD_DATA_PORT=0b1000;//two line display with 5x8 font size
9
_delay_us(45);
10
LCD_DATA_PORT=0b0000;
11
_delay_us(45);
12
LCD_DATA_PORT=0b1111;//Display on, curser on, curser blink
13
_delay_us(45);
14
LCD_DATA_PORT=0b0000;
15
_delay_us(45);
16
LCD_DATA_PORT=0b0001;//clear display, cursor on line 1
17
_delay_us(45);
18
LCD_DATA_PORT=0b0000;
19
_delay_us(45);
20
LCD_DATA_PORT=0b0110;//curser auto increment
21
_delay_us(45);
22
}
>Hint:>In welchem Nibble möchtest Du die Daten haben, in welchem sendest Du sie>aus?
Nach der Hardware sende ich die Daten im unteren Nibble, Softwaremäßig
bin ich mir da nicht so sicher, aber wenn Du so fragst ist es sicher
anders herum ;)
Wegen der Unsicherheit, welches Nibble nun angesprochen wird, habe ich
auch folgendes versucht:
1
voidinit_LCD(void)
2
{
3
_delay_us(100);//startup time
4
LCD_DATA_PORT=0b00000010;//4-Bit mode
5
_delay_us(45);
6
LCD_DATA_PORT=0b00000010;//4-Bit mode
7
_delay_us(45);
8
LCD_DATA_PORT=0b00001000;//two line display with 5x8 font size
9
_delay_us(45);
10
LCD_DATA_PORT=0b00000000;
11
_delay_us(45);
12
LCD_DATA_PORT=0b00001111;//Display on, curser on, curser blink
13
_delay_us(45);
14
LCD_DATA_PORT=0b00000000;
15
_delay_us(45);
16
LCD_DATA_PORT=0b00000001;//clear display, curser on line 1
17
_delay_us(45);
18
LCD_DATA_PORT=0b00000000;
19
_delay_us(45);
20
LCD_DATA_PORT=0b00000110;//curser auto increment
21
_delay_us(45);
22
}
Bringt mich aber auch nicht weiter, könnte es sein, dass ich in
write_data() und write_command irgendwo eine 4-Bit Verschiebung einbauen
muss?
Sven S. schrieb:> könnte es sein, dass ich in> write_data() und write_command irgendwo eine 4-Bit Verschiebung einbauen> muss?
Oh ja, sehe ich gerade. Mal angenommen PD0...3 seien die Datenleitungen
dann sollte es so aussehen.
** Lötlackl schrieb:> Oh ja, sehe ich gerade. Mal angenommen PD0...3 seien die Datenleitungen> dann sollte es so aussehen.high_bit=(input&0xF0)>>4; //get the higher 4 bit> mfg
Ok jetzt werden die Daten auf die Bits 0...3 geschoben wie es sein soll,
weil ich diese Ausgänge ja an die Datenleitungen des LCDs angeschlossen
habe.
Meine Initialisierung habe ich mit dem LCD Simulator
http://www.geocities.com/dinceraydin/djlcdsim/djlcdsim.html verifiziert,
die funktioniert soweit.
Jetzt sieht das Programm so aus:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
/* Connections:
4
*
5
* D4->PORTD0
6
* D5->PORTD1
7
* D6->PORTD2
8
* D7->PORTD3
9
* E-> PORTD4
10
* RW->PORTD6
11
* RS->PORTD6
12
*/
13
#define LCD_DATA_PORT PORTD
14
#define E PD4
15
#define RW PD5
16
#define RS PD6
17
18
voide_state(void)
19
{
20
_delay_us(20);
21
LCD_DATA_PORT|=(1<<E);
22
_delay_us(20);
23
LCD_DATA_PORT&=~(1<<E);
24
}
25
26
voidwrite_data(intinput)
27
{
28
inthigh_bit,low_bit;
29
LCD_DATA_PORT|=(1<<RS);//signal to write chars on display
30
high_bit=((input&0xF0)>>4);//get the higher 4 bit
31
low_bit=((input&0x0F)>>4);//get the lower 4 bit
32
LCD_DATA_PORT=high_bit;//send the higher 4 bit
33
e_state();
34
LCD_DATA_PORT=low_bit;//send the lower 4 bit
35
e_state();
36
}
37
38
voidwrite_command(intinput)
39
{
40
inthigh_bit,low_bit;
41
LCD_DATA_PORT&=~(1<<RS);//signal to write command
42
high_bit=((input&0xF0)>>4);//get the higher 4 bit
43
low_bit=((input&0x0F)>>4);//get the lower 4 bit
44
LCD_DATA_PORT=high_bit;//send the higher 4 bit
45
e_state();
46
LCD_DATA_PORT=low_bit;//send the lower 4 bit
47
e_state();
48
}
49
50
voidsend_string(charinput)
51
{
52
intoutput;
53
output=(int)input;
54
write_data(output);
55
}
56
57
voidsplit_string(char*input)
58
{
59
while(*input!='\0')
60
{
61
send_string(*input++);
62
}
63
}
64
65
voidinit_LCD(void)
66
{
67
_delay_us(100);//startup time
68
LCD_DATA_PORT=0b00000010;//4-Bit mode
69
_delay_us(45);
70
LCD_DATA_PORT=0b00000000;//two line display with 5x8 font size
71
_delay_us(45);
72
LCD_DATA_PORT=0b00001000;
73
_delay_us(45);
74
LCD_DATA_PORT=0b00000000;//Display on, curser on, curser blink
75
_delay_us(45);
76
LCD_DATA_PORT=0b00001111;
77
_delay_us(45);
78
LCD_DATA_PORT=0b00000000;//curser auto increment
79
_delay_us(45);
80
LCD_DATA_PORT=0b00000110;
81
_delay_us(45);
82
}
83
84
voidclear_lcd(void)
85
{
86
write_command(0b00000001);//clear
87
_delay_us(45);
88
}
89
90
voidhome_lcd(void)
91
{
92
write_command(0b00000010);//home position
93
_delay_us(45);
94
}
95
96
voidgoto_xy(intx,inty)
97
{
98
if(y==1)
99
{
100
write_command(0b10000000+0b00000000+x);
101
}
102
if(y==2)
103
{
104
write_command(0b10000000+0b01000000+x);
105
}
106
}
107
108
intmain(void)
109
{
110
DDRD=0xFF;
111
init_LCD();
112
while(1)
113
{
114
//split_string("TEST");
115
//_delay_ms(2000);
116
//split_string("LCD123");
117
LCD_DATA_PORT=0b01001000;//write H
118
_delay_us(50);
119
}
120
}
Ist es jetzt nicht so, dass in write_data, wenn die 4 Bit des oberen-
bzw. unteren Nibbles auf den PORTD gegeben werden, das RS Bit mit 0
gesetzt wird statt 1 zu bleiben, damit die Ausgabe als Zeichen erkannt
wird?
Aus der Überlegung folgere ich, dass ich normalerweise das RS Bit OR
Verknüpft hinzufügen muss wie hier:
1
voidwrite_data(intinput)
2
{
3
inthigh_bit,low_bit;
4
LCD_DATA_PORT|=(1<<RS);//signal to write chars on display
5
high_bit=((input&0xF0)>>4);//get the higher 4 bit
6
low_bit=((input&0x0F)>>4);//get the lower 4 bit
7
LCD_DATA_PORT=high_bit|(1<<RS);//send the higher 4 bit
8
e_state();
9
LCD_DATA_PORT=low_bit|(1<<RS);//send the lower 4 bit
10
e_state();
11
}
Danach kann ich aber immer noch keine Ausgabe sehen :(
> low_bit=((input&0x0F)>>4); //get the lower 4 bit
Und was soll da jetzt noch übrig bleiben, wenn du dir die 4 Bits, die du
dir frei maskiert hast, jetzt nach rechts rausschiebst?
Irgendwie scheint dir noch wirklich klar zu sein, was du da eigentlich
erreichen musst. Oder du probierst einfach irgendwas ohne darüber
nachzudenken, was du da eigentlich tust.
WObei: die Sache mit dem RS hast du gut erkannt.
Karl Heinz Buchegger schrieb:> Und was soll da jetzt noch übrig bleiben, wenn du dir die 4 Bits, die du> dir frei maskiert hast, jetzt nach rechts rausschiebst?
Ich versuche schon, das zu verstehen ;)
Also liege ich richtig, dass nach der Maskierung mit 0x0F das Ergebnis
immer 0b0000xxxx ist und dann mit der Verschiebung nach rechts somit
0b00000000 = 0x00 ergibt? Damit wäre es tatsächlich sinnfrei dies zu
machen :)
Sven S. schrieb:> Karl Heinz Buchegger schrieb:>> Und was soll da jetzt noch übrig bleiben, wenn du dir die 4 Bits, die du>> dir frei maskiert hast, jetzt nach rechts rausschiebst?>> Ich versuche schon, das zu verstehen ;)>> Also liege ich richtig, dass nach der Maskierung mit 0x0F das Ergebnis> immer 0b0000xxxx ist
Genau.
Wenn du µC programmieren willst, dann muss dir die Wirkung von Und und
Oder Operationen in Fleisch und Blut übergehen.
Eine binäre Und-Operation ist wie ein Sieb. Dort wo ein 1 Bit sitzt,
dort ist das Sieb offen und die 'Bits' können durch. Dort wo ein 0-Bit
sitzt kommt nichts durch und im Ergebnis taucht an dieser Stelle ein 0
Bit auf
abcdefgh
11110000 binäres Und
----------
abcd0000
da du die 4 Bits an der niederwertigen Position brauchst, musst du sie
um 4 stellen nach rechts verschieben.
abcd0000 >> 4
0000abcd
und du hast sie an den Positionen um sie auszugeben.
Die niederwertigen Bits
abcdefgh
00001111 binäres Und
-----------
0000efgh
diese 4 Bits sind aber schon an der richtigen Position. Da braucht nix
verschoben werden.
Und lern über Datentypen.
int willst du nicht für Bytes benutzen.
Auf Byteebene ist der Datentyp der Wahl ein uint8_t und kein int. Wozu
den AVR in 16 Bit Arithmetik reinjagen, wenn du nur an 8 Bit
interessiert bist, und dir ein eventuelles 'Vorzeichen' nicht in die
Quere kommen soll. Ein uint8_t hat als unsigned Wert per Definition kein
Vorzeichen. Alle Bits sind einfach nur Bits.
Da du Code hast, der funktioniert:
Es schadet auch nicht, diesen Code zu studieren und sich anzusehen, wie
andere die Sache machen. Niemand sagt, dass du diesen Code übernehmen
musst. Aber man kann viel daraus lernen, indem man anderer Leute Code
studiert und sich überlegt, warum sie manche Dinge genau so machen, wie
sie sie machen.
So ich habe es endlich geschafft zum laufen zu bringen :) In der
Initialisierung waren die Pausen zwischen den Befehlen zu kurz und ein
paar Kleinigkeiten habe ich noch geändert. Allerdings habe ich auch
feststellen müssen, dass im Displaycontroller trotz der Aufschrift 1602A
nur der kleinere Zeichensatz enthalten ist, in dem auch Japanisch o.ä zu
finden ist.
Vielen Dank nochmals an alle, die mir geholfen haben.
1
#include<avr/io.h>
2
#include<util/delay.h>
3
/* Connections:
4
*
5
* D4->PORTD0
6
* D5->PORTD1
7
* D6->PORTD2
8
* D7->PORTD3
9
* E-> PORTD4
10
* RW->PORTD6
11
* RS->PORTD6
12
*/
13
#define LCD_DATA_PORT PORTD
14
#define E PD4
15
#define RW PD5
16
#define RS PD6
17
18
voide_state(void)
19
{
20
_delay_us(50);
21
LCD_DATA_PORT|=(1<<E);
22
_delay_us(20);
23
LCD_DATA_PORT&=~(1<<E);
24
_delay_us(50);
25
}
26
voidwrite_data(uint8_tinput)
27
{
28
uint8_thigh_bit,low_bit;
29
high_bit=((input&0xF0)>>4);//get the higher 4 bit
30
low_bit=(input&0x0F);//get the lower 4 bit
31
LCD_DATA_PORT=high_bit|(1<<RS);//send the higher 4 bit and signal to write chars on display
32
e_state();
33
LCD_DATA_PORT=low_bit|(1<<RS);//send the lower 4 bit and signal to write chars on display
34
e_state();
35
}
36
37
voidwrite_command(uint8_tinput)
38
{
39
uint8_thigh_bit,low_bit;
40
LCD_DATA_PORT&=~(1<<RS);//signal to write command
41
high_bit=((input&0xF0)>>4);//get the higher 4 bit
42
low_bit=(input&0x0F);//get the lower 4 bit
43
LCD_DATA_PORT=high_bit;//send the higher 4 bit
44
e_state();
45
LCD_DATA_PORT=low_bit;//send the lower 4 bit
46
e_state();
47
}
48
49
voidsend_string(charinput)
50
{
51
uint8_toutput;
52
output=(uint8_t)input;
53
write_data(output);
54
}
55
56
voidsplit_string(char*input)
57
{
58
while(*input!='\0')
59
{
60
send_string(*input++);
61
}
62
}
63
64
voidinit_LCD(void)
65
{
66
LCD_DATA_PORT&=~0xFF;//set all outputs to 0
67
_delay_ms(30);//startup time
68
LCD_DATA_PORT=0b00000010;//4-Bit mode
69
e_state();
70
LCD_DATA_PORT=0b00000010;//two line display with 5x8 font size
71
e_state();
72
LCD_DATA_PORT=0b00001000;
73
e_state();
74
LCD_DATA_PORT=0b00000000;//Display on, curser on, curser blink
75
e_state();
76
LCD_DATA_PORT=0b00001111;
77
e_state();
78
LCD_DATA_PORT=0b00000000;//clear display and return to home position
79
e_state();
80
LCD_DATA_PORT=0b00000001;
81
e_state();
82
LCD_DATA_PORT=0b00000000;//curser auto increment scrolling on
Ist ja interessant.
Da gibt es eine Funktion namens 'send_string'
1
voidsend_string(charinput)
2
{
3
uint8_toutput;
4
output=(uint8_t)input;
5
write_data(output);
6
}
die einen einzelnen Character am LCD anzeigt aber sicher keinen String.
Klarer Fall von 'Verwirre deinen Benutzer mit nicht passenden
Funktionsnamen'.
Dafür gibt es eine Funktion namens 'split_string', die dem Namen nach
einen String in Einzelteile zerlegt (splittet), aber dem Code nach den
String auf dem LCD ausgibt
1
voidsplit_string(char*input)
2
{
3
while(*input!='\0')
4
{
5
send_string(*input++);
6
}
7
}
Weiter so! Du hast das Prinzip der Arbeitsplatzsicherung durch
unverständlichen und falsch benannten Code komplett richtig verstanden!
Genau so macht man sich in einer Firma unentbehrlich! Dein Pech nur,
dass LCD Funktionen jetzt nicht Raketentechnik sind und in ein paar
Minuten richtig gestellt werden können. Aber die Grundidee ist
ausbaufähig! Ein Funktionsname soll auf keinen Fall einen intuitiven
Rückschluss darauf zulassen, was die Funktion macht.
Und PS:
Die Zusammenfassung von 4 Bits, so wie sie in deinem Fall gemacht wird,
nennt man in der EDV ein 'Nibble'.
Ein Byte besteht also aus 8 Bit. Es besteht aber auch aus 2 Nibbles -
einem höherwertigem Nibble und einem niederwertigem Nibble.
die 8 Bit eines Bytes abcdefgh
| || |
| |+--+ Die 4 Bits des niederwertigen Nibbles
| | oder auch einfach 'Low-Nibble'
| |
+--+ Die 4 Bit des höherwertigen Nibbles
oder auch einfach 'High-Nibble' genannt.
Sven S. schrieb:> void init_LCD(void)> {> LCD_DATA_PORT &=~0xFF; //set all outputs to 0> _delay_ms(30); //startup time> LCD_DATA_PORT=0b00000010;//4-Bit mode> e_state();
Ab hier funktioniert das ganze zwar per Design, ist aber höchst
missverständlich.
Ab dem Moment, ab dem du erfolgreich auf 4-Bit Interface umgeschaltet
hast, kannst du nicht mehr Kommandos an das LCD geben, in dem du die 8
Bit des Kommandos an die Datenleitungen legst und mit dem E-Pin
wackelst! Ab dem Moment des erfolgreichen Umschaltens werden Kommandos
ausschliesslich über die Funktion write_command abgewickelt, die dann
das Kommando korrekt in 2 Happen (wegen 4 Bit Interface) an das LCD
weitergibt. Ab hier diese Zerlegung selbst zu machen, ist ein 'Ask for
trouble'.
> LCD_DATA_PORT=0b00000010;//two line display with 5x8 font size> e_state();> LCD_DATA_PORT=0b00001000;> e_state();> LCD_DATA_PORT=0b00000000;//Display on, curser on, curser blink> e_state();> LCD_DATA_PORT=0b00001111;> e_state();> LCD_DATA_PORT=0b00000000;//clear display and return to home position> e_state();> LCD_DATA_PORT=0b00000001;> e_state();
Huch. Für das 'clear Display' und 'Cursor Home' hast du eigene
Funktionen. Warum benutzt du sie nicht?
Der kritische Punkt in der Initialisierung des LCD ist das Umschalten
auf 4 Bit Modus.(*) Danach bedeutet Initialisieren nur noch Kommandos
über den offiziellen Weg der 'Kommando-Senden' Funktion an das LCD
geben, so dass jede Funktionalität einen definierten, dir genehmen Wert
einnimmt. Daztu hast du die Funktion, damit sich die um die Details wie
zb die Zerlegung in Nibbles, kümmert.
(*) Und NB. Dein Umschaltcode ist eigentlich falsch. Laut Datenblatt ist
zum sauberen Umschalten in den 4-Bit Modus mehr zu tun als du da tust.
Es reicht nicht, wenn du das LCD aus dem 'Strom-an' Zustand auf 4 Bit
umschalten kannst. Die Umschaltung muss aus JEDEM Zustand heraus
klappen. Die dokumentierte Sequenz in den Datenblättern kann das und die
wird sicherlich auch in deiner Code-Vorlage benutzt. Ich sagte schon:
studier wie andere das machen und überleg dir, warum deren Code so
aussieht wie er aussieht. Man kann viel lernen, indem man sich anderer
Leute Code ansieht und studiert.
Hallo,
das mit dem missverständlichen Namen der Funktion habe ich noch
geändert, ich hatte mich einfach so gefreut, dass es endlich
funktionierte ;D
Karl Heinz Buchegger schrieb:> Huch. Für das 'clear Display' und 'Cursor Home' hast du eigene> Funktionen. Warum benutzt du sie nicht?
Da habe ich die Funktionen nicht benutzt, weil weiter oben ja die Rede
davon war, ich könne in der Initialisierung noch nicht auf die
write_command() Funktion zurückgreifen.
Peter Dannegger schrieb:> eim Init kannst Du noch kein Write_Command nehmen, sondern nur> Write_Nibble.Karl Heinz Buchegger schrieb:> (*) Und NB. Dein Umschaltcode ist eigentlich falsch. Laut Datenblatt ist> zum sauberen Umschalten in den 4-Bit Modus mehr zu tun als du da tust.> Es reicht nicht, wenn du das LCD aus dem 'Strom-an' Zustand auf 4 Bit> umschalten kannst. Die Umschaltung muss aus JEDEM Zustand heraus> klappen.
Da habe ich was gelesen, man müsse da drei mal hintereinander die
Umschaltsequenz benutzen, aber ohne scheint es ja auch zu funktionieren.
Mein "Referenz-Quelltext" ist übrigns von hier:
http://extremeelectronics.co.in/avr-tutorials/using-lcd-module-with-avrs/
Das ist finde ich ein ziemliches Durcheinander, sodass die Quelltexte
nicht soo hilfreich waren und ich mich mehr an den Datenblättern
orientiert habe.
Karl Heinz Buchegger schrieb:> Ab hier funktioniert das ganze zwar per Design, ist aber höchst> missverständlich.> Ab dem Moment, ab dem du erfolgreich auf 4-Bit Interface umgeschaltet> hast, kannst du nicht mehr Kommandos an das LCD geben, in dem du die 8> Bit des Kommandos an die Datenleitungen legst und mit dem E-Pin> wackelst!
Ok da könnte ich ja noch versuchen, über die Bitverschiebung zu
arbeiten, wie auch in der write_command() und write_data() Funktion?
Karl Heinz Buchegger schrieb:> Die Umschaltung muss aus JEDEM Zustand heraus> klappen.
Was wäre denn beispielsweise ein Szenario, in dem das nicht
funktionieren würde?
Sven S. schrieb:> Was wäre denn beispielsweise ein Szenario, in dem das nicht> funktionieren würde?
Zum Beispiel wenn das LCD schon im 4-Bit Modus ist :-)
Zum Beispiel wenn du einen Prozessor-Reset machst, just in dem Moment in
dem von einem LCD Kommando das erste Nibble schon übertragen wurde und
das zweite noch nicht.
Karl Heinz Buchegger schrieb:> Zum Beispiel wenn du einen Prozessor-Reset machst, just in dem Moment in> dem von einem LCD Kommando das erste Nibble schon übertragen wurde und> das zweite noch nicht.
Ok das überrascht mich jetzt, ich habe noch über keine andere
Möglichkeit gelsesen, außer die Nibbles hintereinander zu senden.
Vielleicht habe ich ja was übersehen, ich schau noch mal nach.
Hier lernt man echt mehr als in der Schule thumbs up
Sven S. schrieb:> Karl Heinz Buchegger schrieb:>> Zum Beispiel wenn du einen Prozessor-Reset machst, just in dem Moment in>> dem von einem LCD Kommando das erste Nibble schon übertragen wurde und>> das zweite noch nicht.>> Ok das überrascht mich jetzt, ich habe noch über keine andere> Möglichkeit gelsesen, außer die Nibbles hintereinander zu senden.
Darum gehts aber auch gar nicht.
Es geht darum, dass dann das LCD auf das 2.te Nibble wartet um das
Kommando zu vervollständigen.
Da kommt dann auch was. Nämlich dein erstes Byte mit dem du nach dem
Prozessorreset versuchst, das LCD wieder in einen 4 Bit Modus zu
versetzen.
Karl Heinz Buchegger schrieb:> Darum gehts aber auch gar nicht.>> Es geht darum, dass dann das LCD auf das 2.te Nibble wartet um das> Kommando zu vervollständigen.> Da kommt dann auch was. Nämlich dein erstes Byte mit dem du nach dem> Prozessorreset versuchst, das LCD wieder in einen 4 Bit Modus zu> versetzen.
Ah der Reset des Displays hat gefehlt, wobei dies 3 Mal hintereinander
gemacht werden sollte.
1
LCD_DATA_PORT=0x30;
Damit ist die Initialisierung weniger verwirrend hinsichtlich der 4 Bit
Datenleitung und dem 8 Bit Wert am Port des Mikrocontrollers.