Hallo,
ich möchte mit einem AtMega16 einen HD61830B-LCD-Controller ansteuern.
Ich steh noch ziemlich am Anfang meiner Programmier-Karriere, deshalb
kann es sein, dass ich mir das ganze ein wenig einfach vorstelle, aber
ich würde euch gern bitten einmal einen Blick auf meinen Code zu werfen.
Auf dem LCD wird nichts und teilweise vertikale Striche angezeigt.
1
#define F_CPU 8000000UL
2
3
#define DATAPORT PORTA
4
#define DATADDR DDRA
5
#define DATAPIN PINA
6
#define CTRLPORT PORTB
7
#define CTRLDDR DDRB
8
#define RS 0
9
#define RW 1
10
#define E 2
11
#define CS 3
12
#define RESET 4
13
#define LED 5
14
15
#include<util/delay.h>
16
#include<stdint.h>
17
#include<avr/io.h>
18
19
voidlcdWaitIdle(void){
20
// waits until busy flag is cleared
21
22
DATAPORT=0x00;// Datenport wird gelöscht
23
DATADDR=0x00;// Datenport wird als Eingang deklariert
24
25
CTRLPORT|=(1<<RW);// R/W auf logisch 1 -> R
26
CTRLPORT|=(1<<RS);// RS auf logisch 1 -> aktiv
27
CTRLPORT|=(1<<E);// E auf logisch 1 -> lesen
28
29
do{
30
CTRLPORT|=(1<<E);
31
CTRLPORT&=~(1<<E);// fallende Flanke am Pin E
32
}while(DATAPIN&(1<<7));// Schleife bis Busy Flag logisch 0 wird
33
34
DATADDR=0xff;// Datenport wird als Ausgang deklariert
35
}
36
37
voidlcdWriteCommand(uint8_tcommand){
38
// Kommandobyte -> HD61830
39
40
lcdWaitIdle();
41
CTRLPORT&=~(1<<RW);// R/W auf logisch 0 -> W
42
CTRLPORT|=(1<<RS);// RS auf logisch 1 -> aktiv
43
DATAPORT=command;// übergebenes Kommandobyte wird ausgegeben
44
CTRLPORT|=(1<<E);
45
CTRLPORT&=~(1<<E);// fallende Flanke am Pin E -> Portdaten werden ins Register geschrieben
46
}
47
48
voidlcdWriteData(uint8_tdata){
49
// Datenbyte -> HD61830
50
51
lcdWaitIdle();
52
CTRLPORT&=~(1<<RW);// R/W auf logisch 0 -> W
53
CTRLPORT&=~(1<<RS);// RS auf logisch 0 -> inaktiv
54
DATAPORT=data;// übergebenes Datenbyte wird ausgegeben
55
CTRLPORT|=(1<<E);
56
CTRLPORT&=~(1<<E);// fallende Flanke am Pin E -> Portdaten werden ins Register geschrieben
57
}
58
59
voidlcdWritePair(uint8_tcommand,uint8_tdata){
60
// Kombination aus Kommando- und Datenbyte
61
62
lcdWriteCommand(command);
63
lcdWriteData(data);
64
}
65
66
voidlcdInit(void){
67
DATADDR=0xff;// Datenport wird als Ausgang deklariert
68
CTRLDDR=0xff;// Kommandoport wird als Ausgang deklariert
69
70
CTRLPORT&=~(1<<CS);// CS auf logisch 0 -> aktiv
71
CTRLPORT|=(1<<RESET);// RESET auf logisch 1 -> aktiv
72
73
lcdWaitIdle();
74
75
lcdWritePair((1<<RS),0x34);// Erstmal nur einen blinkenden Cursor
Da hast du dir aber 'nen mächtigen Display-Controller ausgesucht ;)
Was mir auffällt ist z.B. "lcdWritePair((1<<RS), 0x34);" in deiner
Init-Funktion, das muss falsch sein (wahrscheinlich meinst du
"lcdWritePair(0, 0x34);").
- wahrscheinlich brauchst du beim ENABLE-Signal ein paar nops/eine
Verzögerung (s. "Enable cycle time" / "Enable Pulse width").
- Mach dir doch auch Macros für die LCD-Befehle (MODE_CTRL, CHR_PITCH
usw...).
- Nenn die Funktion für die Befehle lieber LcdPutCmd, oder so - dass da
zwei bytes übertragen werden ist nicht weiter interessant, wenn man den
Code liest, dass da Befehle übertragen werden dagegen schon.
- den Reset Pin musst du wahrscheinlich nicht mit dem AVR ansteuern,
häng den doch einfach an Vcc oder an den Reset-Pin des AVR.
hth. Jörg
ps.: AVCC des AVR ist aber angeschlossen, oder?
> Was mir auffällt ist z.B. "lcdWritePair((1<<RS), 0x34);" in deiner> Init-Funktion, das muss falsch sein (wahrscheinlich meinst du> "lcdWritePair(0, 0x34);").
Ach verdammt, da hast du natürlich Recht!
> - wahrscheinlich brauchst du beim ENABLE-Signal ein paar nops/eine> Verzögerung (s. "Enable cycle time" / "Enable Pulse width").
Kann ich da nicht einfach auch wieder mit dem Busy-Flag arbeiten? Die
Anzahl nops, die benötigt wird, ist ja von der Taktfrequenz abhängig.
> - Mach dir doch auch Macros für die LCD-Befehle (MODE_CTRL, CHR_PITCH> usw...).
später...
> - Nenn die Funktion für die Befehle lieber LcdPutCmd, oder so - dass da> zwei bytes übertragen werden ist nicht weiter interessant, wenn man den> Code liest, dass da Befehle übertragen werden dagegen schon.
später...
> - den Reset Pin musst du wahrscheinlich nicht mit dem AVR ansteuern,> häng den doch einfach an Vcc oder an den Reset-Pin des AVR.
Da hast du natürlich recht, aber im Moment habe ich noch I/O-Pins en
masse, also sollte es auch so gehen.
> ps.: AVCC des AVR ist aber angeschlossen, oder?
Ja klar ;)
Ich werde gleich nachher die Änderungen im Code vornehmen und testen.
mfG
DATADDR=0x00;// Datenport wird als Eingang deklariert
12
13
CTRLPORT|=(1<<RW);// R/W auf logisch 1 -> R
14
CTRLPORT|=(1<<RS);// RS auf logisch 1 -> aktiv
15
CTRLPORT|=(1<<E);// E auf logisch 1 -> lesen
16
17
do{
18
asm("nop");
19
}while(DATAPIN&(1<<7));// Schleife bis Busy Flag logisch 0 wird
20
21
DATADDR=0xff;// Datenport wird als Ausgang deklariert
22
}
Ein delay von 100µs in der Funktion E sollte ja locker reichen (Enable
fall/rise time 25 ns). in der do...while-Schleife bin ich mir unsicher,
was da rein muss. eigendlich soll doch gewartet werden also asm("nop"),
oder? Generell ist keine Besserung sichtbar.
> Ein delay von 100µs in der Funktion E sollte ja locker reichen
Ja, natürlich (_delay_us(2) sollte auch gehen )
> (Enable fall/rise time 25 ns).
Vorsicht! Es geht hier um Enable High(resp. Low-) time (die Zeit, die
Enable high bzw. Low ist und NICHT um fall/rise time (= die Zeit, die es
dauert, bis enable umgeschaltet hat)
> in der do...while-Schleife bin ich mir unsicher, was da rein muss.> eigendlich soll doch gewartet werden also asm("nop"),
Nein!
1
shiftEnable();
2
voidlcdWaitIdle(void){
3
// waits until busy flag is cleared
4
unsignedchartmp;
5
6
DATAPORT=0x00;// Datenport wird gelöscht
7
DATADDR=0x00;// Datenport wird als Eingang deklariert
8
9
CTRLPORT|=(1<<RW)|(1<<RS);// R/W auf logisch 1 -> R
10
// RS auf logisch 1 -> aktiv
11
do{
12
CTRLPORT|=(1<<E);
13
_delay_us(1);
14
tmp=DATAPIN;
15
CTRLPORT&=~(1<<E);
16
_delay_us(1);
17
}while(tmp&(1<<7));// Schleife bis Busy Flag logisch 0 wird
18
// Das Flag (d.h. alle LCD-Daten) kann sich nur
19
// mit der fallenden Flanke von E ändern !
20
21
DATADDR=0xff;// Datenport wird als Ausgang deklariert
22
}
hth. Jörg
ps.: wenn's funktioniert/wenn du verstanden hast ;) schau dir mal die
LCD-Lib. von P. Fleury an (http://jump.to/fleury), da kannst du dir auf
jeden Fall die 'höheren' Funktionen (und die Namen :) ) abschauen
pps.: Mach auf jeden Fall die Optimierung an (falls noch nicht
geschehen)!
Halli Hallo,
es tut sich was!!! Ich drehte vorhin testweise den Kontrast ganz auf und
erkannte sehr schwache Zeichen, also spielte ich mit dem Wert von "Set
Number of Time Divisions" herum, sodass endlich was sichtbar wurde.
Zeichen, die ich an das Display schicke, werden korrekt dargestellt. Nur
leider werden viele weitere Zeichen gezeigt - wirre Zeichen (arabisch?!
;)). Außerdem sehen immer drei Zeilen gleich aus. Inhalt kann nicht im
Speicher des HD61830 sein, weil ich auch schon RESETS ausprobiert habe.
Hat jemand eine Idee, woran das liegen könnte?
mfG
hallo !
der thread is schon etwas älter, ich weiß, aber ich grab ihn trotzdem
nochmal aus...
>>Außerdem sehen immer drei Zeilen gleich aus. Inhalt kann nicht im>>Speicher des HD61830 sein, weil ich auch schon RESETS ausprobiert habe.>>Hat jemand eine Idee, woran das liegen könnte?
ich hab ein sehr ähnliches problem, nur dass bei mir nicht drei zeilen
sondern alle zeilen gleich aussehen. wie hast du das problem lösen
können und was war die ursache ?? ich benutze deinen codeschnippsel,
aber bei funktioniert er nicht...
mfg martin
ich hatte das problem glaube ich damit gelöst, indem ich den wert für
"Time Division" geändert habe in der init-funktion. den wert entnimmst
du dem datenblatt des lcd-panels.
Hallo,
könnte ihr mir bitte sagen welche Funktionen ich aufrufen muss um das
LCD zu starten? Zuerst die Initialisierung und dann nur noch die
Funktion zum senden der Zeichen?
Entschuldigt bitte aber ich bin noch ein Anfänger was die Programmierung
in Bascom angeht. Ich habe aber in LCD mit dem HD Controller und würde
es gerne testen.
Vielen Dank!
Danke für deine Antwort. Leider passiert weiterhin nichts. Ich bin mir
nicht sicher ob ich alles richtig in der LCD.h konfiguriert habe.
Das sind meine Einstellungen:
1
#define DATAPORT PORTA
2
#define DATADDR DDRA
3
#define DATAPIN PINA
4
#define CTRLPORT PORTB
5
#define CTRLDDR DDRB
6
#define RS 1
7
#define RW 2
8
#define E 0
9
#define CS 3
10
#define RESET 4
11
#define LED 5
Wobei mein Datenport auf dem Port A des AVR liegt, das müsste
übereinstimmen.
RS auf PB.1
RW auf PB.2
E auf PB.0
CS und RESET habe ich nicht angeschlossen.
Ich muss dazu erwähnen das, dass Display aus einer Hicom Telefonanlage
stammt. Ich habe die ganze Hauptplatine des Telefons genommen und mich
dort an eine Anschlussleiste (alle Ausgänge des HD61830 sind dort
ausgeführt) angeschlossen. Die RESET Leitung ist über einen 100kOhm
Widerstand an GND angeschlossen und CS ebenfalls über einen Widerstand
auf GND...
Soll das vl. eine Art sicherung sein um das Display nicht
umprogrammieren zu können? Sollte Reset nicht auf VCC liegen?
Vielen Dank für eure Hilfe!
Hm, sicher bin ich mir nicht.
Ich kann versuchen alle Leitungen die irgendwo andershin verlaufen zu
trennen. Auf der Platine befindet sich noch ein Eeprom in dem
anscheinende sich die Library mit den Characters befindet. Vom HD Chip
gehen Leitungen zu diesem Eprom.
Im Prinzip aber brauche ich doch nur den HD61830 Chip, den
Spannungsinverter für das LCD und mehr nicht, oder? Der HD Chip brauch
im Prinzip auch nur die Datenleitungen sowie Steuerleitungen und die 8
Leitungen die zu dem LCD gehen, denn Rest könnte ich abschalten.
LG
Hallo all !
Ich versuche auch gerade ein Powertip PG240128X mit einem LC7981
Controller
an einem Atmega 16 zu laufen zu bringen. Dieser Controller scheint ja
wohl mit dem HD61830 kompatibel zu seien.
Jetzt zu meinem Problem :
Wie bekomme ich das hin das ich den Code von oben in einem Bascom
Programm einbauen kann das dann die Zeichen zum Display sendet ??
gruss, TV freak
Ich habe ebenfalls ein PowerTip PG240128X-P1 Display gekauft und dieses
mit einem Mega32 verbunden. Mit dem oben genannten Sourcecode kann ich
das Display zwar löschen, wenn ich das Display allerdings derart
initialisiere:
1
lcdInit('g');
2
lcdClear('g');
3
lcdSetCursor('g',0,0);
und dann
1
for(cntx=0;cntx<100;cntx++){
2
lcdSetPixel(cntx,cntx,'s');
3
}
ausführe, erscheint nicht eine 100-Pixel lange, diagonale Linie auf dem
Display, sondern es werden gleichzeitig vier Linien aufgebaut, die um
1/4 der Displayhöhe versetzt sind und am linken Rand beginnen. Die Länge
der Linien beträgt etwa 30 Pixel, allerdings mit Lücken ^^. Das Display
hat eine Auflösung von 240x128 Pixel. Was ist das für ein komisches
Problem? Ist mein Grafik-Controller etwa kaputt?
Mittlerweile vermute ich, dass die Datenleitungen 0 und 1 auf der
Display-Steuerbaugruppe defekt sind - die Signale vom Mega32 kann ich an
den Anschlusspins messen, aber sie werden nicht verarbeitet. Einen 4-Bit
Modus gibt es nicht zufällig bei diesem Display-Controller, oder?
Hallo, ich sehe das der thread etwas älter ist, aber, ich versuche seit
einige Nächte Zeichen/Buchstaben aus zu geben, klappt aber nicht. Ich
benutze die lib weiter oben. Habe diese korrekt angepasst (denke ich),
linien zeichnen geht problemlos, text lässt sich aber nicht anzeigen.
nach dem ich auf char mode umschalte werden die Linien gelöscht, der
Cursor ist zu sehen (blinkend), mehr aber auch nicht. kann mir da jemand
einen tipp geben, evtl hinwies auf eine "bessere"lib mit mehr
Funktionen?
1
#include<lcd.h>
2
#include<util/delay.h>
3
#include<stdint.h>
4
#include<avr/io.h>
5
intmain(void){
6
7
lcdInit('g');
8
lcdClear('g');
9
lcdSetCursor('g',0,0);
10
unsignedcharcntx;
11
12
for(cntx=0;cntx<240;cntx++){
13
lcdSetPixel(cntx,10,'s');
14
15
}
16
17
18
//ich habe versucht auch mit lcdinit('c'); ins char mode zu wechseln aber geht auch nicht
19
20
21
lcdWritePair(0x00,0x3c);// Mode Control
22
lcdWritePair(0x01,0x75);// Set Character Pitch
23
lcdWritePair(0x02,0x27);// Set Number of Characters
24
lcdWritePair(0x03,0x7f);// Set Number of Time Divisionsn
25
lcdWritePair(0x04,0x07);// Set Cursor Position
26
_delay_ms(500);
27
lcdWriteData(65);//sollte doch A oder e angezeigt werden
28
29
30
}
Ich habe es mit dem programmieren nicht so leicht, daher brauche ich
eure hilfe. mfg.