Hallo zusammen,
ich bin neu hier und habs noch nicht so drauf, also gleich mal sorry für
evt. einfache Fragen.
Ich versuche mit einem Infineon XC164CM Easy Kit ein ANAG VISION AV0820
8x2 (KS0066) anzusteuern. Leider scheitere ich bereits bei der
Initialisierung.
Die Pins sind alle richtig belegt (hab alle nachgemessen).
Mein Versuch zur Initialisierung über Port1
1
typedefunsignedcharubyte;
2
typedefunsignedintuword;
3
typedefunsignedlongulong;
4
5
#include<XC164.h>
6
7
volatileuwordreload;
8
uwordi;
9
10
voiddelay(){
11
for(i=reload;i<=0xEFFF;i++){}
12
for(i=reload;i<=0xEFFF;i++){}
13
for(i=reload;i<=0xEFFF;i++){}
14
for(i=reload;i<=0xEFFF;i++){}
15
for(i=reload;i<=0xEFFF;i++){}
16
for(i=reload;i<=0xEFFF;i++){}
17
for(i=reload;i<=0xEFFF;i++){}
18
for(i=reload;i<=0xEFFF;i++){}
19
for(i=reload;i<=0xEFFF;i++){}
20
for(i=reload;i<=0xEFFF;i++){}
21
for(i=reload;i<=0xEFFF;i++){}
22
for(i=reload;i<=0xEFFF;i++){}
23
for(i=reload;i<=0xEFFF;i++){}
24
for(i=reload;i<=0xEFFF;i++){}
25
for(i=reload;i<=0xEFFF;i++){}
26
for(i=reload;i<=0xEFFF;i++){}
27
for(i=reload;i<=0xEFFF;i++){}
28
for(i=reload;i<=0xEFFF;i++){}
29
for(i=reload;i<=0xEFFF;i++){}
30
for(i=reload;i<=0xEFFF;i++){}
31
}
32
33
34
35
voidmain(void){
36
37
reload=0xEEEE;
38
39
DP1L=(DP1L&~(uword)0x00FF)|0x00FF;//Die letzten 8 Bits auf Ausgangs setzten
40
DP1H=(DP1H&~(uword)0x00FF)|0x003F;//Die letzten 8 Bits auf Ausgangs setzten
41
42
delay();
43
44
//Initialisierung
45
P1H=(P1H&~(uword)0x00FF)|0x00C0;
46
delay();
47
P1H=(P1H&~(uword)0x00FF)|0x00C0;
48
delay();
49
P1H=(P1H&~(uword)0x00FF)|0x00C0;
50
delay();
51
52
53
P1H=(P1H&~(uword)0x00FF)|0x000D;
54
P1L=(P1L&~(uword)0x00FF)|0x00C0;
55
56
P1H=(P1H&~(uword)0x00FF)|0x0002;
57
P1L=(P1L&~(uword)0x00FF)|0x00C0;
58
59
P1H=(P1H&~(uword)0x00FF)|0x0000;
60
P1L=(P1L&~(uword)0x00FF)|0x0040;
61
62
P1H=(P1H&~(uword)0x00FF)|0x0000;
63
P1L=(P1L&~(uword)0x00FF)|0x0040;
64
65
66
while(1){}
67
68
}
Vielleicht kann mir evt. jemand helfen.
Vielen Dank schon mal für eure Antworten.
MfG Ronald
Funktioniert dein delay?
Eine funktionierende Delayfunktion ist das A und O beim LCD. Da ist ein
striktes Timing einzuhalten, das auch im Datenblatt des LCD-Controllers
angegeben ist. Hast du ein solches Datenblatt für den KS0066?
Die Delayfunktion kann man mit einem einfachen LED-Blinkprogramm grob
testen.
Der Rest deines Quellcodes kann kaum kontrolliert werden, weil dem
Zuschauer nicht klar ist, welche Spieler auf dem Platz stehen ähm
Leitungen des LCD an welche Pins des µC gehen. Ein Schaltplan (auch
handgezeichnet) wäre da sehr hilfreich.
Was am Quellcode auffällt ist, dass anscheinend die essentiellen RS und
E (und ggf. die RW, sieht man nicht weil Schaltplan fehlt) Leitungen des
LCD zusammen mit den Datenleitungen D0..D7 gesetzt werden (Veroderung?)
oder komplett fehlen. Das entspricht überhaupt nicht dem einzuhaltenden
Timing aus dem Datenblatt!
verwendest du eine codeoptimierung? dann würde ich drauf tippen, dass
der optimierer deine ganzen leeren (und daher für ihn sinnfreien)
zählschleifen rauswirft ;-)
Hallo,
danke für die Antworten. Ja ich glaub es liegt am Timing. Ich werde mal
einen Schaltplan erstellen und das Programm umstellen.
Eine Frage hätte ich aber noch: bei einem Infineon XC164 40MHz, wie kann
ich mir ein passendes delay basteln? 1/Takfrequenz sind 25ns....aber wie
gehts weiter? Ich verwende Keil (Compiler).
Nochmals danke für die Anworten
MfG Ronald
Ronald schrieb:> Eine Frage hätte ich aber noch: bei einem Infineon XC164 40MHz, wie kann> ich mir ein passendes delay basteln?
Wenn man es professionell machen willl, nimmt man nen timer. Ich mache
es es aber der einfachheit halber immer so:
1
#include<REG164.H>
2
3
4
#define LED_PORT P1L
5
#define LED_MASK 0xFF
6
#define LED_DIR DP1L
7
8
#define led_init() LED_DIR |= LED_MASK
9
#define led_on() LED_PORT &=~LED_MASK
10
#define led_off() LED_PORT |= LED_MASK
11
12
#define COUNTER_1MS 2000UL // muss noch so verändert werden, dass ca. 1Hz Blinktakt herauskommt
13
14
void_delay_ms(intms)
15
{
16
intcount_ms;
17
longintcounter;
18
19
for(count_ms=0;count_ms<ms;count_ms++)
20
for(counter=0;counter<COUNTER_1MS;counter++);// Schleife für einzelne Millisekunden
21
}
22
23
intmain(void)
24
{
25
led_init();
26
27
while(1)
28
{
29
led_on();
30
_delay_ms(500);
31
led_off();
32
_delay_ms(500);
33
}
34
}
Jetzt muss nur noch COUNTER_1MS angepasst werden, dass eine LED im
Sekundentakt blinkt. Damit hat man ne Verzögerungsschleife für Vielfache
einer Millisekunden. Die sollte eigentlich reichen, um das LCD zu
initialisieren, auch wenn an manchen Stellen Mikrosekunden reichen
würden. Länger darfs immer sein.
Gruß
Skriptkiddy
Der klassische weg:
Schreibe dir eine Funktion, die im µs Bereich warten kann.
Dazu in einer Schleife so viele Nichtstun-Assembler-Anweisungen benutzen
wie nötig.
Es hängt vom Instruction Set des µC ab, wie diese Anweisung heisst.
Bei anderen µC heisst sie üblicherweise NOP
http://www.keil.com/dd/docs/datashts/infineon/c166sv2um.pdf
Und es hängt von deiner Entwicklungssoftware (Kein µVision3?) ab, wie
man die Nichtstun-Assembler-Anweisung in C verwendet (inline Assebler).
Und eine die im ms Bereich warten kann. Die ms wartefunktion kann die us
Wartefunktion benutzen.
Wie man das implementieren kann (bei anderem Prozessor)
http://www.keil.com/forum/1940/
Diese Funktionen sind so grundlegend, dass ich mir nicht verstellen
kann, dass es diese noch nicht gibt.
Skript Kiddy schrieb:> for(counter=0 ; counter<COUNTER_1MS ; counter++); // Schleife für
Gleicher Fall den abc schon angesprochen hat. Manche Compiler
optimieren solche Zeilen gnadenlos weg, wenn Codeoptimierung
eingeschaltet ist. Wenn das der Fall ist: counter volatile machen.
Stefan B. schrieb:> Manche Compiler> optimieren solche Zeilen gnadenlos weg, wenn Codeoptimierung> eingeschaltet ist. Wenn das der Fall ist: counter volatile machen.
Ok dann gehen wir auf Nummer Sicher.
1
...
2
3
void_delay_ms(intms)
4
{
5
intcount_ms;
6
volatilelongintcounter;
7
8
for(count_ms=0;count_ms<ms;count_ms++)
9
for(counter=0;counter<COUNTER_1MS;counter++);// Schleife für einzelne Millisekunden
Hallo zusammen,
nochmals danke für eure tolle Hilfe! Ich habs nun wie folgt modifiziert:
(Schaltplan + Dokumentation fürs Display + Beschreibung des Ports ist
auch dabei). ...leider funktionierts immer noch nicht :(
Das Delay funktioniert (habs mit einer Diode ausprobiert)
1
typedefunsignedcharubyte;
2
typedefunsignedintuword;
3
typedefunsignedlongulong;
4
5
#include<XC164.h>
6
#define COUNTER_1MS 2700UL
7
8
9
voiddelay(uwordms)
10
{
11
uwordcount_ms;
12
ulongcounter;
13
14
for(count_ms=0;count_ms<ms;count_ms++)
15
for(counter=0;counter<COUNTER_1MS;counter++);// Schleife für einzelne Millisekunden
16
}
17
18
19
voidmain(void){
20
21
DP1L=(DP1L&~(uword)0x00FF)|0x00FF;//Die letzten 8 Bits auf Ausgangs setzten
22
DP1H=(DP1H&~(uword)0x00FF)|0x003F;//Die letzten 6 Bits auf Ausgangs setzten
23
P1L=(P1H&~(uword)0x00FF)|0x0000;//Startwert alles auf 0
24
P1L=(P1H&~(uword)0x00FF)|0x0000;//Startwert alles auf 0
25
26
delay(40);
27
28
//Initialisierung laut Datenblatt....die delay`s sind immer ein Bisschen länger
Die korrekte Kontrastspannung Vee muss entsprechend dem Datenblatt
angeschlossen werden.
Extrem ungünstige Verkabelung von Port 1, weil alle Bitmuster aus dem
LCD-Controller Datenblatt verwurstet werden müssen.
Kannst du nicht die DB0 bis DB7 komplett auf P1H legen und zwar so, dass
Bit 0 von P1H auch DB0 entspricht? Und P1L für RS, E und RW nehmen?
Arbeitet die delay jetzt korrekt? Kannst du damit eine LED im 1s
(1000ms) Abstand blinken lassen? Exakt 60 "Herzschläge" pro Minute?
Hallo Stefan,
leider kann ich DB0-DB0 nicht auf P1H legen, da P1H nur 6 Bits zur
Verfügung stellt. Ich könnte jedoch evt. DB0 - DB7 auf P1L setzten und
die anderen auf P1H wenn das besser ist. Bei Vee bin ich mir nicht
sicher (häng ich da Vref vom Controller dran?). Beim Delay hab ich für
10000ms mitgestoppt, und komm ziemlich genau auf 10s.
MfG Ronald
Hallo zusammen,
so hab jetzt alles mal umgestellt, dass man leichter programmieren kann.
Im Anhang nochmal der vereinfachte Schaltplan. Evt. kann mir nun jemand
weiterhelfen.
Vielen Dank schon mal:
1
typedefunsignedcharubyte;
2
typedefunsignedintuword;
3
typedefunsignedlongulong;
4
5
#include<XC164.h>
6
#define COUNTER_1MS 2700UL
7
8
9
voiddelay(uwordms)
10
{
11
uwordcount_ms;
12
ulongcounter;
13
14
for(count_ms=0;count_ms<ms;count_ms++)
15
for(counter=0;counter<COUNTER_1MS;counter++);// Schleife für einzelne Millisekunden
16
}
17
18
19
voidmain(void){
20
21
DP1L=(DP1L&~(uword)0x00FF)|0x00FF;//Die letzten 8 Bits auf Ausgangs setzten
22
DP1H=(DP1H&~(uword)0x00FF)|0x003F;//Die letzten 6 Bits auf Ausgangs setzten
23
P1L=(P1L&~(uword)0x00FF)|0x0000;//Startwert alles auf 0
24
P1H=(P1H&~(uword)0x00FF)|0x0001;//Startwert alles auf 0
25
26
delay(40);
27
28
//Initialisierung laut Datenblatt....die delay`s sind immer ein Bisschen länger
Ronald schrieb:> leider kann ich DB0-DB0 nicht auf P1H legen, da P1H nur 6 Bits zur> Verfügung stellt. Ich könnte jedoch evt. DB0 - DB7 auf P1L setzten und> die anderen auf P1H wenn das besser ist.
Das wäre deutlich besser als die Anfangsverkabelung! Über P1L setzt du
dann ausschliesslich die Datenleitungen und über P1H ausschliesslich die
Steuerleitungen.
Im Moment bin ich fit für die Falle. Morgen mehr.
> Bei Vee bin ich mir nicht> sicher (häng ich da Vref vom Controller dran?).
Das ist wahrscheinlich ein zu hohes Spannungspotential. Du brauchst dort
so um die typ. 0.7V. Muss ich aber im Datenblatt nachsehen und dafür ist
es mir zu spät.
Um die Vee runter zu setzen: Hast du 10K oder 25K Potentiometer in der
Bastelkiste oder auf dem Board? Mit dem kannst du einen
Spannungsteiler aufbauen:
1
Vcc --###-- Gnd
2
^
3
|
4
+--- Vee
> Beim Delay hab ich für> 10000ms mitgestoppt, und komm ziemlich genau auf 10s.
Das ist schon gut. Damit hättest du die delay_ms Funktion. Kannst du
auch eine delay_us Funktion schreiben, also eine Funktion, die im
Microsekunden-Bereich wartet.
Die delay_us ist nicht unbedingt nötig, aber bestimmte Timings speziell
beim Enable An/Aus können im us Bereich liegen und mur mit delay_ms
würde man da immer mindestens 1 ms verbraten.
Das folgende orientiert sich stark am Artikel
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
Dort geht es um einen anderen µC, aber ich werde auf deinen µC Rücksicht
nehmen.
Zunächst wird die Pinzuordnung in Makros definiert, damit der Quellcode
später lesbarer wird.
1
#define LCD_RS 4
2
#define LCD_RW 5
3
#define LCD_EN 6
4
5
#define LCD_DATAPORT P1L
6
#define LCD_CTRLPORT P1H
7
#define LCD_DATADIR DP1L
8
#define LCD_CTRLDIR DP1H
Damit kann die "1<<BITNUMMER Schreibweise" zur Bitmanipulation
verwenden.
Dann die wichtigsten LCD Funktionen. Fehlende Funktionen (lcd_clear) und
Definitionen (LCD_Makros) aus dem Artikel holen. Bei den Zeiten aus dem
Artikel (Bsp. LCD_ENABLE_US) im Datenblatt des eigenen LCD nachsehen, ob
die so passen.
1
void_delay_us(unsignedintus)
2
{
3
// us Microsekunden warten alternativ: _delay_ms(1) aufrufen
4
// zu implementieren...
5
}
6
7
void_delay_ms(unsignedintms)
8
{
9
// ms Millisekunden warten
10
// zu implementieren...
11
}
12
13
// Erzeugt einen Enable-Puls
14
staticvoidlcd_enable(void)
15
{
16
LCD_CTRLPORT|=(1<<LCD_EN);// Enable auf 1 setzen
17
_delay_us(LCD_ENABLE_US);// kurze Pause
18
LCD_CTRLPORT&=~(1<<LCD_EN);// Enable auf 0 setzen
19
}
20
21
// Sendet eine 8-bit Ausgabeoperation an das LCD
22
staticvoidlcd_out8(unsignedchardata)
23
{
24
LCD_DATAPORT=data;// Bits setzen
25
lcd_enable();
26
}
27
28
// Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.
29
voidlcd_init(void)
30
{
31
// verwendete Pins auf Ausgang schalten
32
unsignedcharpins=(1<<LCD_RW)|// R/W Leitung
33
(1<<LCD_RS)|// R/S Leitung
34
(1<<LCD_EN);// Enable Leitung
35
36
LCD_CTRLDIR|=pins;
37
LCD_CTRLPORT&=~pins;
38
LCD_DATADIR|=0xFF;
39
LCD_DATAPORT&=~0xFF;
40
41
// warten auf die Bereitschaft des LCD
42
_delay_ms(LCD_BOOTUP_MS);
43
44
// Soft-Reset muss 3mal hintereinander gesendet werden
Hallo Stefan,
vielen vielen Dank, dass du deine Zeit opferst. Vee hab ich mit einem
Poti mit 0.7V belegt. Nun versuch ich gleich mal mit deiner Vorlage das
ding zum Laufen zu kriegen.
Bis später, und nochmals danke!
MfG Ronald
Hallo Stefan,
das mit den 0.7V hat gut funktioniert. Vorweg, es funktioniert leider
immer noch nicht. Folgendes hab ich am Code geändert:
Stefan B. schrieb:> #define LCD_RS 4> #define LCD_RW 5> #define LCD_EN 6
...ich glaube da hast du dich vertippt (siehe Schaltplan)
E = Pin3
RW = Pin2
RS = Pin1
Vee = Pin0
..also müsste es doch so passen...?
#define LCD_RS 1
#define LCD_RW 2
#define LCD_EN 3
Komisch ist auch, dass die Hintergrundbeleuchtung nicht
funktioniert...!?!
Port1 kann man als Input und als Output betreiben.
DP1L und DP1L muss man zuerst auf 0xFF setzten. Wenn ich das probiere,
kommt eine Fehlermeldung: redefinition...
Macht man das jedoch nicht, kommen bei jedem Pin nur 3,5V Statt 4.8 raus
(da noch andere Funktionen am Port laufen, oder so). Im Anhang hab ich
nochmal das gesamte Datenblatt zu Port1.
Langsam bin ich echt am Verzweifeln.
Ich bitte nochmals um Hilfe.
MfG Ronald
Ronald schrieb:> ...ich glaube da hast du dich vertippt (siehe Schaltplan)> E = Pin3> RW = Pin2> RS = Pin1> Vee = Pin0>> ..also müsste es doch so passen...?> #define LCD_RS 1> #define LCD_RW 2> #define LCD_EN 3
Stimmt, gut aufgepasst. Ich hatte falsch an der LCD Seite die Pinnummern
abgeschrieben.
Vee gehort nicht an den µC, sondern an den Schleifer des
Potentiometers.
Beitrag "Re: LCD mit Infineon Entwicklungsboard"
Aber mit Vee bist du ja durch bzw. das klappt.
> Komisch ist auch, dass die Hintergrundbeleuchtung nicht> funktioniert...!?!
Das ist ein komplett anderes Thema.
Die Hintergrundbeleuchtung hat getrennte Anschlüsse (K und A an der
Seite der Platine),
Die legt man über einen Vorwiderstand zur Begrenzung des
Durchflußstromes der Hintergrund-LED an Vcc2 und GND. Bei manchen LCDs
kann Vcc2 gleich Vcc sein, bei anderen nicht.
In deinem Datenblatt stehen die Werte zur Berechnung (s. Artikel
LED) des Vorwiderstandes bei LED Forward Voltage und LED Forward
Current. Dabei auf die Unterschiede weisse Hintergrund-LED vs. andere
Hintergrund-LED achten! Vcc 5V können für die Hintergrundbeleuchtung
benutzt werden.
Aufpassen wenn du auf die Idee kommst hier einen Potentiometer zu
verwenden, um die Beleuchtung zu dimmen! Unbedingt einen
Mindestwiderstand in Serie dazuschalten. Ohne passiert es sehr leicht,
dass der Potentiometer in Richtung 0 Ohm gedreht wird und die
Hintergrund-LED geröstet wird!
> Port1 kann man als Input und als Output betreiben.> DP1L und DP1L muss man zuerst auf 0xFF setzten. Wenn ich das probiere,> kommt eine Fehlermeldung: redefinition...
Achso das betrifft vielleicht diesen Teil:
#define LCD_DATADIR DP1L
#define LCD_CTRLDIR DP1H
und die folgenden Stellen mit LCD_DATADIR und LCD_CTRLDIR.
Um das exakt zu klären, müsste man sich die Definitionen von DP1L und
DP1H in deinen µC spezifischen Includefiles und die exakte Fehlermeldung
(oder Warnung?) des Compilers betrachten, also die berühmten fehlenden
Teile bei ...
Die Schnelllösung sieht so aus, dass du die beiden Redefinitionen
entfernst (auskommentierst) und im restlichen Quellcode direkt DP1L und
DP1H statt der beiden Makronamen LCD_*DIR einsetzt.
> Macht man das jedoch nicht, kommen bei jedem Pin nur 3,5V Statt 4.8 raus> (da noch andere Funktionen am Port laufen, oder so). Im Anhang hab ich> nochmal das gesamte Datenblatt zu Port1.> Langsam bin ich echt am Verzweifeln.> Ich bitte nochmals um Hilfe.
Brauchst du nicht zu verzweifeln. Das ist noch die ganz normale Härte im
Geschäft.
Juhuuuuuuuuu!!!!!!!!!!!!!!!!!!!!!!
\o/\o/\o/\o/\o/\o/\o/\o/\o/\o/\o/
Man erkennt die 4 und die 2 am Display (Sie laufen von links nach
rechts).
Vielen Danke für die Hilfe!
Danke danke danke! Who`s the man? --> Stefan :)
Ist es normal, dass die 2te Zeile nicht aktiv ist?
MfG Ronald
Klasse. Das ist schon mal ein Start.
Die Zeile in der aktuell ausgegeben werden soll, musst du gezielt
ansteuern (oder du initialisierst anders und zwar mit eingeschaltetem
Scrollmodus, wird aber seltener gemacht).
Die Zeilenpositionierung kannst du mit der
> void lcd_setcursor( uint8_t spalte, uint8_t zeile );
machen (s. Artikel
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung).
Dafür musst du diese Makrodefinitionen mit Hilfe des Datenblatts des LCD
kontrollieren:
> #define LCD_SET_DDADR 0x80>> // Zeilendefinitionen des verwendeten LCD> // Die Einträge hier sollten für ein LCD mit einer Zeilenlänge von> // 16 Zeichen passen> // Bei anderen Zeilenlängen müssen diese Einträge angepasst werden>> #define LCD_DDADR_LINE1 0x00> #define LCD_DDADR_LINE2 0x40> #define LCD_DDADR_LINE3 0x10> #define LCD_DDADR_LINE4 0x50
Soweit ich das Datenblatt interpretiere kannst du den Wert 0x80 für
LCD_SET_DDADR übernehmen.
LCD_DDADR_LINE1 und LCD_DDADR_LINE2 passen auch bei deinem 8x2 Display.
Zeile 3 und 4 gibt es nicht, d.h. LCD_DDADR_LINE3 und LCD_DDADR_LINE4
ist egal was dort steht.
Hallo,
ich musste leider uint8_t auf unsigned int ändern, da Keil uVision
gemeint hat, dass das ein alter identifyer ist. Die erste Zeile
funktioniert toll,
jedoch bekomm ich nichts auf die 2te Zeile. Die Werte für line 2 hab ich
mit dem Datenblatt auch nochmal überprüft (die müssten eigentlich
stimmen).
Ist die 2te Zeile evt. hinüber?
MfG Ronald
Ronald schrieb:> Ist die 2te Zeile evt. hinüber?
Sehr unwahrscheinlich.
Möglicherweise geht die 8-Bit Initialisierung in lcd_init() schief und
die Hardware-Initialisierung in den Einzeilenmodus wird wirksam.
// 8-bit Modus 2 Zeilen 5x7
lcd_command( LCD_SET_FUNCTION |
LCD_FUNCTION_8BIT |
LCD_FUNCTION_2LINE |
LCD_FUNCTION_5X7 );
1. Mach vor und nach diesem Block je eine Wartezeit von 5ms.
2. Hast du die Definitionen der Wartezeiten nach deinem Datenblatt
vorgenommen? Also die LCD_BOOTUP_MS aus dem Artikel von 15 ms auf
mindestens 30 ms hochgesetzt? Zur Sicherheit auch mal auf 300ms
hochsetzen. Längere Zeiten "schaden" nie, kürzere immer.
Hab die Wartezeit auf 300ms raufgesetzt. Es sieht tatsächlich so aus,
als würde nur in dein einzeilenmodus geschalten, da man eine leichte
hinterlegung nach dem Start in der ersten Zeile erkennt. Trotz der
Anpassung funktioniert jedoch nur die erste Zeile.
MfG Ronald
Die sind IMHO nicht fragwürdig.
Im Datenblattausschnitt (Anhang) geht es mit N, F und L etwas kreuz und
quer zu, aber es sollten letztendlich diese Definitionen (= die gleichen
wie im AVR Artikel) vorhanden sein:
#define LCD_SET_FUNCTION 0x20
#define LCD_FUNCTION_8BIT 0x10 // Bit DL
#define LCD_FUNCTION_2LINE 0x08 // Bit N bzw. L
#define LCD_FUNCTION_5X7 0x00 // Bit F
Im Moment gehen mir die Ideen für die Ferndiagnose aus. Ich melde mich,
wenn mir was einfällt.
Ich habe nur wenige weitere Projekt im Netz gefunden, bei dem dieses
Display verwendet wurde.
Eines davon hatte auch Sourcecode, leider kein öffentlicher, sondern mit
Copyright von Elektor, deshalb hier nachprogrammiert:
1
voidlcd_init(void)
2
{
3
// verwendete Pins auf Ausgang schalten
4
unsignedcharpins=(1<<LCD_RW)|// R/W Leitung
5
(1<<LCD_RS)|// R/S Leitung
6
(1<<LCD_EN);// Enable Leitung
7
8
// hier deine Anpassung für die Ausgabe an den Pins...
9
10
// warten auf die Bereitschaft des LCD
11
_delay_ms(LCD_BOOTUP_MS);// 15ms bzw. 30ms default ggf. erhöhen
12
13
// Soft-Reset muss 3mal hintereinander gesendet werden
@ Spess
Kann man probieren, worst-case hat man 5x10 bit große Zeichen, kaputt
gehen kann nix, aber ich denke das ist ein Fehler mit der 0x04.
Die Legende zum Bit F fehlt im Datenblatt. Bei dem roten Kreuz ist aber
eine Legende zu Bit N, die IMHO eigentlich die Legende zu F sein soll.
Und Bit N definiert die Wunschanzahl der Zeilen...
Im Tutorial
(http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung)
steht auch
#define LCD_FUNCTION_5X7 0x00
#define LCD_FUNCTION_5X10 0x04
Hallo,
hab
#define LCD_FUNCTION_5X7 0x04
ausprobiert. Das funktioniert leider nicht (aber danke für den Versuch).
Jetzt probier ich mal die neue lcd_init.
Meld mich dann gleich.
MfG
// hier deine Anpassung für die Ausgabe an den Pins...
9
DP1H|=pins;
10
P1H&=~pins;
11
DP1L|=0xFF;
12
P1L&=~0xFF;
13
14
// warten auf die Bereitschaft des LCD
15
_delay_ms(300);// 15ms bzw. 30ms default ggf. erhöhen
16
17
// Soft-Reset muss 3mal hintereinander gesendet werden
18
// zur Initialisierung
19
lcd_out8(LCD_SOFT_RESET);
20
_delay_ms(10);// 5ms default ggf. erhöhen
21
22
lcd_enable();
23
_delay_ms(10);// 1ms default ggf. erhöhen
24
25
lcd_enable();
26
_delay_ms(10);// 1ms default ggf. erhöhen
27
28
29
// 8-bit Modus / 2 Zeilen / 5x7
30
lcd_command(LCD_SET_FUNCTION|
31
LCD_FUNCTION_8BIT|
32
LCD_FUNCTION_2LINE|
33
LCD_FUNCTION_5X7);
34
35
// Modifizierte Sequenz für LCD ANAG VISION AV0820 angelehnt an
36
// Elektor.DE 1/2004 "Uhr mit Mehrfach-Alarm"
37
38
lcd_command(LCD_SET_DISPLAY|
39
LCD_DISPLAY_OFF);// auch im Datenblatt
.....LCD_DISPLAY_OFF 0x08....
1
lcd_command(LCD_SET_DISPLAY|
2
LCD_DISPLAY_ON|
3
LCD_CURSOR_ON|
4
LCD_BLINKING_ON);// zusätzlich bei Elektor
5
6
lcd_command(LCD_CLEAR_DISPLAY);// auch im Datenblatt
7
_delay_ms(10);// 2ms default ggf. erhöhen
8
9
lcd_command(LCD_CURSOR_HOME);// zusätzlich bei Elektor
10
_delay_ms(10);// 2ms default ggf. erhöhen
11
12
// Cursor inkrement / kein Scrollen
13
lcd_command(LCD_SET_ENTRY|
14
LCD_ENTRY_INCREASE|
15
LCD_ENTRY_NOSHIFT);// auch im Datenblatt
16
17
// hier ist die Initialisierung laut Datenblatt zu Ende
18
19
lcd_command(LCD_SET_DISPLAY|
20
LCD_CURSOR_OFF);// zusätzlich bei Elektor
21
}
mit dieser Initialisierung funktionierts leider nicht. Habs noch mal mit
der urpsrünglichen gegengecheckt. Ich nehme an, dass die Verdrahtung
passt (sonst würd ja die Initialisierung und die erste Zeile nicht
funktionieren).
MfG Ronald
MfG Ronald
Die Funktion der lcd_init kann man so nicht nachweisen. Leider steht im
Datenblatt nicht wie die Hardware-Initialisierung nach dem Power on des
Displays aussieht.
Bei anderen LCD ist üblich, dass die HW-Init sich in einen einzeiligen
Modus mit 8-Bit-Ansteuerung hochschafft. Die Software-Initialisierung
mit lcd_init() soll dann erst in den mehrzeiligen Modus umschalten.
Du merkst die Beobachtung spricht dafür, dass die SW-Init nicht
funktioniert. Vermutlich könntest du zum jetzigen Stand lcd_init() auch
weglassen und nur das delay_ms() machen (mit Textausgaben zu warten bis
das LCD hardwaremäßig initialisiert ist).
Ich versuche mal Mitte bis Ende der Woche ein solches LCD aufzutreiben.
Hey Danke! Sollte das Ding jemals komplett laufen, stell ich eine
komplette Anleitung ins Internet (Schaltpläne, Bilder vom Aufbau,
Erklärungen usw..), damit auch andere profitieren können.
MfG Ronald
So, das Display ist da.
Und funktioniert auch beim Setzen des Cursors in eine andere Zeile mit
dem lcd_init() Code aus
Beitrag "Re: LCD mit Infineon Entwicklungsboard"
Die ganzen folgenden Änderungen ala Elektor waren also unnötig.
Diesem Satz von dir habe ich zu wenig Beachtung gegeben:
>> DP1L und DP1L muss man zuerst auf 0xFF setzten. Wenn ich das probiere,>> kommt eine Fehlermeldung: redefinition...
bzw. auf die Nachfrage
> Um das exakt zu klären, müsste man sich die Definitionen von DP1L und> DP1H in deinen µC spezifischen Includefiles und die exakte Fehlermeldung> (oder Warnung?) des Compilers betrachten, also die berühmten fehlenden> Teile bei ...
kam nach dem ersten Erfolgserlebnis keine Antwort.
Im Anhang ist der komplette Quellcode. Dabei habe ich die Definitionen
bei Keil nachgesehen und wegen deren SFR Schreibweise meine die
LCD_*PORT und LCD_*DIR Definitionen zurück gebaut.
Im Code kann man auch zwei Definitionen AVR oder XC164 sehen. Die AVR
Definition habe ich benutzt, um das Display an einem AVR zu testen. Du
musst die AVR Definition entfernen und dafür XC164 definieren (ist schon
gemacht)
Probiere den Quellcode aus und wenn der Compiler Warnungen rausgibt, die
mit Copy&Paste hier zeigen. Ebenso wenn du Anpassungen machst.
Hallo Stefan,
derzeit bin ich auf Besuch bei der Omi (bis Montag). Danach werd ich's
gleich ausprobieren und das Ergebnis sofort online stellen. Schon mal
vielen Dank!
MfG Ronald
Hallo Stefan,
folgende Anpassung habe ich gemacht:
1
DP1L=(DP1L&~(unsignedint)0x00FF)|0x00FF;//Die letzten 8 Bits auf Ausgangs setzten
2
DP1H=(DP1H&~(unsignedint)0x00FF)|0x003F;//Die letzten 6 Bits auf Ausgangs setzten
Ich dachte der Tag wird nie kommen, aber das Ding läuft! Anbei zwei
Bilder vom Aufbau im Betrieb.
Who's the man? Stefan is the man!
Danke danke danke.
Nun werd ich gleich mal probieren das alles nochmal ganz alleine
hinzukriegen. Und wenn alles sitzt evt. einen Temperatursensor
ansteuern. Alles zusammen werd ich dann komplett vom Aufbau bis zur
Fertigstellung komplett hochladen. Nochmals danke Stefan!
MfG Ronald
Hallo Stefan,
ich bins nochmals. Nun hab ich auch mal probiert, das Display auf einem
ATMEGA8 zu betreiben. Es scheint auch zu funktionieren. Die Buchstaben
werden jedoch trotz richtiger Kontrastspannung nicht richtig dargestellt
(verblasst, zum Teil verschwinden ganze Bereiche eines Buchstaben).
Herumregeln an der Kontrastspannung hilft auch nicht wirklich.
Hättest du evt. eine Idee? Ich bitte um Hilfe.
MfG Ronald
Ronald, die Beschreibung deutet eher auf ein Hardwareproblem als auf ein
Softwareproblem hin. Eventuell ein Versorgungsproblem. Zu beidem kann
ich aber nix genaueres sagen, weil Programm und Schaltplan/Bild vom
Aufbau fehlen. Tipp: Vielleicht beteiligen sich mehr Helfer, wenn du
dafür einen extra Thread auf machst (mit ggf. Link hierher). Infineon im
Titel schreckt viele AVR-ianer schon ab.