Hallo erstmal an alle :)
Ich hoffe Ihr könnt mir bei einem Problem helfen.
Ich steuere einen KS0066-LCD mit 4 Zeilen zu je 20 Zeichen via
4-bit-modus mit einem ATMega16 Mikrocontroller an. Nur will das
irgendwie nicht funktionieren und ich weiß nicht mehr weiter. Das
einzige was ich zu sehen bekomme sind 2 Balken, jeweils in 1. & 3.
Zeile.
Fehlerquellen die ich bis jetzt schon ausschließen konnte:
-kalte Lötstellen
-schaltungstechnische fehler
-bauteile
es muss also an der software, sprich an meinem Programm liegen.
Dieses sieht wie folgt aus:
------------------------------------------------------------------------
1
#define PORT_LCD PORTB
2
#define LCD_RS PB0
3
#define LCD_EN PB1
4
5
voidlcd_data(unsignedchartemp1)
6
{
7
unsignedchartemp2=temp1;
8
PORT_LCD=(temp1&0xF0)|LCD_RS;
9
_delay_us(41);
10
lcd_enable();
11
temp2=temp2<<4;
12
PORT_LCD=(temp2&0xF0)|LCD_RS;
13
_delay_us(41);
14
lcd_enable();
15
_delay_us(44);
16
}
17
18
voidlcd_command(unsignedchartemp1)
19
{
20
unsignedchartemp2=temp1;
21
PORT_LCD=(temp1&0xF0);
22
_delay_us(41);
23
lcd_enable();
24
temp2=temp2<<4;
25
PORT_LCD=(temp2&0xF0);
26
_delay_us(41);
27
lcd_enable();
28
_delay_us(44);
29
}
30
31
voidlcd_enable(void)
32
{
33
PORT_LCD|=LCD_EN;
34
_delay_us(21);
35
PORT_LCD&=~LCD_EN;
36
}
37
38
39
voidlcd_init(void)
40
{
41
_delay_ms(31);
42
lcd_command(0x30);
43
_delay_us(5);
44
lcd_enable();
45
lcd_command(0x30);
46
_delay_us(101);
47
lcd_enable();
48
lcd_command(0x30);
49
lcd_enable();
50
51
lcd_command(0x20);
52
53
lcd_command(0x07);// I/D=1, S=1
54
lcd_command(0x0E);// D=1, C=1, B=0
55
lcd_command(0x10);// S/C=0, R/L=0
56
lcd_command(0x2C);// 4bit, 5x10
57
}
58
59
voidlcd_clear(void)
60
{
61
PORT_LCD=0x01;
62
_delay_ms(2);
63
lcd_enable();
64
}
65
66
voidlcd_home(void)
67
{
68
PORT_LCD=0x20;
69
_delay_ms(2);
70
lcd_enable();
71
}
72
73
voidlcd_setcursor(uint8_tx,uint8_ty)
74
{
75
uint8_ttemp=0;
76
if(y==0){temp=x;}
77
elseif(y==1){temp=40+x;}
78
elseif(y==2){temp=14+x;}
79
elseif(y==3){temp=54+x;}
80
lcd_command(temp);
81
}
------------------------------------------------------------------------
Im Anhang findet Ihr noch das Datenblatt des LCDs.
Ich bitte um schnelle Antwort beziehungsweise Hilfe.
Die Ansteuerung des LCD ist Teil meiner Diplomarbeit für den Abschluss
der HTL. Somit bekommt das Problem eine gewisse Wichtigkeit ^^
Das Fehlerbild ist typisch für eine misslungene Initialisierung. Der
Controller geht in die default Einstellung (bei 4 zeiligen Displays sind
meist Zeile 1 und 3 logisch zwei Hälften einer einzigen Zeile).
Zeig uns doch bitte deinen Schaltplan. Wie ist RW beschaltet?
Hi
>Nur will das>irgendwie nicht funktionieren und ich weiß nicht mehr weiter.
Das heißt ganz einfach, das die Initialisierung nicht passt.
> PORT_LCD = ....> _delay_us(41);> lcd_enable();
Tausche mal bei allen Ausgaben dieser Art delay und enable. Der Befehl
wird nämlich erst mit dem enable ausgeführt und das delay muss zwischen
zwei Ausgaben liegen.
MfG spess
>Er pulst enable schon in der Befehls-schreib-Routine. Das zusätzliche>lcd-enable ist imho überflüssig.
Nö, das lcd_command() darf er bei den drei 0x30 einfach nicht machen.
spess53 schrieb:> Aber nicht bei den ersten drei Befehlen der Initialisierung.
Wie kommst du da drauf? Zweimal enable ist nicht notwendig.
So mach ich es seit Jahr und Tag und hatte noch nie Probleme:
lcd_write(0x28,0); // Vorspann laut Displaytech Datenblatt
_delay_ms(10);
lcd_write(0x28,0); // Busyflag funktioniert sonst nicht richtig
_delay_ms(1);
lcd_write(0x28,0);
@Georg G.
Das habe ich auch schon gelesen. Anschließend habe ich viel Zeit in die
Initialisierung gesteckt - erfolglos.
RW ist auf GND, weil ich ohnehin nie etwas von LCD auslesen werde. Das
sollte letztendlich ein Tacho sein.
@all
also wie ist jetzt die richtige Reihenfolge bzw. Syntax? ^^
Hallo Ryan,
weine Lösung habe ich Dir aufgezeigt, wenn Du weiter nur rumstochern
möchtest Bitte.
Wenn Du mit einer der beiden Libs deine HW testen solltest, siehst Du
vielleicht den wald vor lauter bäumen.
ok ich werde jede dieser Libs am Abend testen, da ich jetzt leider weg
muss.
ich werde mich schnellstmöglich wieder melden.
Und danke schonmal an alle helfenden :)
@Uwe S.
ich hab die Libs jetzt auf meine Hardware angepasst und sie getestet.
Leider erfolglos.
Was mir aber auffällt ist dass alle Libs im Internet die Zeile
#include "irgendwas.h"
haben.
wenn ich die *.h datei einbinde erkennt er keine einzige Funktion.
daraufhin ändere ich es immer so wie es für mich sinn macht, sprich
#include "irgendwas.c"
ist das egal in welcher reihenfolge das aufgerufen wird oder auf was
sollte man hier achten?
Ryan Polster schrieb:> Was mir aber auffällt ist dass alle Libs im Internet die Zeile>> #include "irgendwas.h">> haben.
Ja.
Genau so soll das ja auch sein.
> wenn ich die *.h datei einbinde erkennt er keine einzige Funktion.
... beim Linken
> daraufhin ändere ich es immer so wie es für mich sinn macht, sprich>> #include "irgendwas.c"
Und genau das macht man eben nicht.
C ist als Sprache so designed, dass ein komplettes Programm aus mehreren
C-Dateien bestehen kann. Jede einzelne C-Datei wird getrennt von allen
anderen compiliert und die einzelnen Übersetzungsergebnisse werden von
einem Linker zum kompletten Programm zusammengesetzt.
OK, auf den kleinen µC ist das nicht so wichtig. Aber in der
professionellen Entwicklung IST das wichtig. Dann da besteht ein
komplettes Projekt schon auch mal aus ein paar hundert C-Files. Da ist
es wichtig, dass jede einzelne für sich übersetzbar ist. Denn dann sind
Programmänderungen in ein paar Sekunden realisierbar: das geänderte
C-File wird neu kompiliert und mit den immer noch vorhandenen
vorhergehenden Überstzungsergebnissen der anderen C-Files ein neues
Programm zusammengelinkt. Das dauert ein paar Sekunden bis ein paar
Minuten, während eine komplette neue Übersetzung des kompletten Source
Codes schon auch mal ein paar Stunden dauern kann.
Nichts desto trotz kannst du dasselbe Vorgehen wie die Profis benutzen.
Wenn du eine Entwicklungsumgebung hast, dann fügst du der ganz einfach
das 2.te C-File noch mit dazu, und dann sorgt die IDE, dass der
komplette Ablauf genau so durchläuft: beide C-Files werden getrennt
voneinander kompiliert und dann die Überstzungsergebnisse
zusammengelinkt.
Wenn du keine IDE hast, dann hast du zumindest ein makefile. IM makefile
das 2.te C-File eintragen und dann erledigt das makefile (wenn es
richtig geschrieben ist) all diese Schritte. Wenn du noch nicht mal ein
makefile hast: Warum hast du keines?
> Die Ansteuerung des LCD ist Teil meiner Diplomarbeit für den> Abschluss der HTL.
Gerade dann solltest du aber eigentlich den Enstehungsprozess eines
Programmes aus mehreren Source Code Files kennen. Denn als dein
potentieller Arbeitgeber würde ich mich schön gefrotzelt vorkommen, wenn
ich dich in die Programmierung einstelle und dir dann die Grundlagen
erst mal beibringen muss, wie eigentlich Programme gebaut werden - wie
Compiler und Linker zusammenspielen.
Mittlerweile hab ich mich daran gewöhnt. Schöne Verarsche, die das
Ministerium da mit euch treibt, indem sie das alles 'Diplomarbeit'
nennt. Eine Diplomarbeit ist für mich eine Arbeit, die an einer Uni
gemacht wird um den akademischen Grad 'Diplom-Ingenieur' zu erwerben
(ja, ich weiss, den gibt es nicht mehr). Eine Abschlussarbeit an einer
HTL ist für mich eine Abschlussarbeit. Aber sicher keine Diplomarbeit.
Seit wann gibt es da ein Diplom dafür?
Ryan Polster schrieb:> ok, hab jetzt den fehler bei lcd_home entfernt & alle unnötigen enables> weggegeben.. immernoch das gleiche bild
Du bellst den falschen Baum an.
Wenn ein HD_hamstibamsti LCD das bekannte Bild mit den Balken zeigt,
dann liegt das Problem am Anfang der INitialisierung. Also hier
> void lcd_init(void)> {> _delay_ms(31);> lcd_command(0x30);> _delay_us(5);> lcd_command(0x30);> _delay_us(101);> lcd_command(0x30);>> lcd_command(0x20);>
Da ist weder ein lcd_clear beteiligt, noch ist sonst irgendeine deiner
Funktionen beteiligt. Da geht es einzig und alleine darum, dass an den 4
verbundenen Dtaenleitungen das richtige Muster anliegt und dass Zeiten
eingehalten werden. Punkt.
Denn:
du kannst an dieser Stelle deine lcd_command Funktion noch nicht
benutzen.
Die lcd_command Funktion kannst du erst dann benutzen, wenn das LCD
schon im 4-Bit Modus IST. Dazu muss es aber erst mal in diesem Momdus
SEIN. Schlussfolgerung: an dieser Stelle kann die Funktion nicht benutzt
werden, sondern mann muss händisch die Bitmuster auf die Portpins geben
und den Enable-Toggler aufrufen.
Das ist wie der Baron von Münchhausen, der sich nicht selbst am
Haarschopf
aus dem Sumpf ziehen kann.
Und natürlich sich an die zeitlichen Vorgaben halten.
Und natürlich muss die Verkabelung stimmen.
Georg G. schrieb:> spess53 schrieb:>> Aber nicht bei den ersten drei Befehlen der Initialisierung.>> Wie kommst du da drauf? Zweimal enable ist nicht notwendig.
Doch ist es.
Eine robuste Initialisierung eines HD44780 (bzw. KS0066) kann ein LCD
aus jedem beliebigen Zustand wieder in einen geordneten 4-Bit Modus
holen.
Selbst dann, wenn der ansteuernde Prozessor mitten in der Befehlsausgabe
nach dem ersten Nibble resettet wird und das HD44780 bis zum St.
Nimmerleinstag auf die 2.te Hälfte des Befehlsbytes warten würde.
Genau darauf ist die ganze Initialisierung ausgelegt. Das LCD mit
absoluter Sicherheit aus jedem beliebigen Ansteuerzustand wieder
geordnet in den 4.Bit Modus zu holen und zu initialisieren. Und zwar
ohne Power down / Power up.
Daher stammen zum Teil nämlich auch die diversen einzuhaltenden
Wartezeiten :-) Das LCD könnte zufällig gerade das erste Nibble eines
Clear Befehls erhalten haben, wenn der Reset kommt. Mit der ersten
Übertragung der versuchten Neuinitialisierung wird dieser Clear
abgeschlossen und das LCD führt den erst mal aus ... was abgewartet
werden muss, ehe der 2.te Versuch gestartet wird, das LCD in den 8 Bit
Modus zurück zu schalten, von wo man es dann in den 4 Bit Modus
schaltet.
die 3-fache Ausgabe einer 0x3 auf den 4 Datenleitungen hat nur diesen
einen Zweck: das LCD erst mal sicher in den 8 Bit Modus zu holen. Das
kann je nach Betriebszustand nach 3 Nibble der Fall sein. Aber
spätestens nach 3 Nibbles (und entsprechenden Wartezeiten) ist es im 8
Bit Modus, von wo es dann mit einem einzigen 0x2 in den 4 Bit Modus
geschaltet wird.
Also ich kann die Dateiendung auf *.txt ändern um Einsicht zu bekommen.
Ich werde sie im Anhang hinzufügen.
Ich benutze Atmel Studio 6.1.
Damit kompiliere und programmiere ich.
Ryan Polster schrieb:> Also ich kann die Dateiendung auf *.txt ändern um Einsicht zu bekommen.
Brauchst du nicht.
So ist das gut.
> Ich benutze Atmel Studio 6.1.
OK, dann ist das makefile im Grunde uninteressant, denn Atmel Studio
erzeugt sich selber eines.
Nur der Vollständigkeit halber
Im Makefile
1
....
2
# Add inputs and outputs from these tool invocations to the build variables
3
C_SRCS+= \
4
../Diplomarbeit.c
5
6
...
Im Atmel Studio machst du über dem Projekt-Baum einen Rechtsklick, aus
dem Kontextmenü "Add existing Source File" und fügst das andere C-File
zum Projekt mit dazu. Ab sofort kümmert sich Atmel Studio darum, dass es
mitcompiliert und mitgelinkt wird.
jetzt habe ich dei *.c Datei erfolgreich eingebunden.
Aber es geht immer noch nicht.
Habe es jetzt auch wieder mit der Lib von Peter Fleury ausprobiert, da
mir seine die liebste von den oben genannten drei ist.
Ryan Polster schrieb:> Habe es jetzt auch wieder mit der Lib von Peter Fleury ausprobiert, da> mir seine die liebste von den oben genannten drei ist.
Im Header File von den Fleury Funktionen gibt es einen Schalter für
KS0066 LCD. Hast du den richtig gesetzt?
Und für die Fleury Lib musst du die R/W Leitung verbinden (oder
alternativ die Funktion busywait durch eine Wartezeit ersetzen)
Gibt es sonst noch etwas auf das man bei der Ansteuerung eines LCD
achten muss bzw. sollte?
oder etwas erwähnenswertes zu Peter Fleurys library?
Im Anhang hab ich alle relevanten Dateien hinzugefügt.
Ich brauche unbedingt eure Hilfe.
so, ks0066 bit ist auf 0
jetzt ist nur noch xtal auf 4mhz in lcd.h
@holger: den bildschirm löschen habe ich jetzt aus der schleife genommen
@hubert: tatsächliche taktfrequenz?
was ist eigentlich der unterschied zwischen XTAL und F_CPU?
oder wann verwendet man das eine und wann das andere?
ich habe jetzt nämlich eine Warnung dass F_CPU von delay.h genommen wird
und das wären 1Mhz.
und was bedeutet "UL" bei F_CPU 1000000UL ?
Ryan Polster schrieb:> was ist eigentlich der unterschied zwischen XTAL und F_CPU?> oder wann verwendet man das eine und wann das andere?
An sich ist es egal wenn es mit dem Namen im laufenden Programm
übereinstimmt. F_CPU kann man im AVR-Studio4 unter configuration options
einstellen. Wird in den anderen Versionen ähnlich sein. Damit muss ich
das nur einmal machen.
F_CPU sollte aber auch mit der Taktfrequenz übereinstimmen mit der der
Controller tatsächlich läuft.
Das Problem liegt an der Initialisierung.
Eine Initialisierung besteht ja nur aus 2 Teilen:
-Die Kommandos
-Das Timing dazwischen
Das alles ist aus dem Datenblatt zu entnehmen.
Dieses habe ich als Anhang hinzugefügt.
Den Code(von Peter Fleury) zur Initialisierung habe ich hier, angepasst
an meine Hardware:
> Den Code(von Peter Fleury) zur Initialisierung habe ich hier, angepasst> an meine Hardware:
Oh mein Gott.
>Weiß jemand von euch weiter?
Ja, hör auf in der lcd.c etwas zu ändern.
Nur die lcd.h musst du an deine LCD Beschaltung anpassen.
In dieser Lib von Fleury musst du nur in der lcd.h Datei deine
Einstellungen machen. Du verschleierst nur deine Probleme mit den
Änderungen in der lcd.c.
Die Frequenz mit der dein Controller läuft musst du in die lcd.h
eintragen.
Ich verwende die Fleury Lib schon seit Jahren. Wenn es mal nicht
funktionierte dann war die Frequenz falsch oder es war ein
Hardwarefehler.
Welche Leitungen vom Display hast du angeschlossen?
Laut deinem Code müsste das
PORTB4 - DB4
PORTB5 - DB5
PORTB6 - DB6
PORTB7 - DB7
für den 4 Bit Mode sein.
Ich liste dir mal sämtliche auffindbaren Frequenzen auf:
ISP Clock: 115.2 kHz
Clock generator: 3,686 Mhz
XTAL: 4 Mhz (in lcd.h von Peter Fleury)
F_CPU: 4 Mhz (zusätzlich in Hauptprogramm, schadet ja nicht)
Ryan Polster schrieb:> Habe es jetzt mit der originalen lcd.c Datei von Peter Fleury versucht.> Funktioniert auch nicht.
Hast du es mal mit der Doku zum Chip versucht? ("_Lesen_" meine ich)
Ich frage mich so langsam, ob das Posten von funktionierenden Quellen
hier in diesem Forum etwas Gutes oder etwas völlig Kontraproduktives
ist. Eigentlich meint unsereiner, daß es was Gutes ist, aber was zieht
man damit groß? Leute, die solche Quellen nicht verstehen wollen,
sondern bloß blind benutzen wollen - und sich selbst für Fachleute
halten: "Hab die Lib von P.D. genommen, funzt nich, nu die von P.F. oh
die funzt auch nich, watt für ein Mist in diesem Forum.."
Irgendwann sehe ich die Zeit kommen, daß die Moderatoren gemeinsam
dieses Forum mitsamt dessen Trolls in die Luft sprengen und dann unter
Absingen unanständiger Stoßgebete des Weges ziehen...
W.S.
Ich habe gehört bzw. gelesen dass man mit den Fuses sehr vorsichtig
umgehen sollte (bei meinem Wissenstand).
Daher ändere ich erstmal nichts.
Da steht bei SUT_CKSEL "INTROSC_1MHZ_6CK_64MS"
also ich schätze mal 1Mhz?
und was bedeutet der Rest?
Ein wenig sollte man sich schon mit der Materie beschäftigen, besonders
wenn es um einen Abschlußarbeit geht.
Es ist interner Takt, 1MHz, 6Takte und 64msek Verzögerung bis der
Controller läuft.
Also jetzt mal die 1MHz als F_CPU eintragen.
Und schön langsam tippe ich auch einen Hardwarefehler in deiner
Schaltung.
Ein Foto der Schaltung habe ich grad nicht auf dem Rechner und finde es
zu viel Arbeit eines zu machen und hochzuladen weil die Schaltung so
trivial ist.
1 µC
1 LCD
fertig ^^
Schaltungstechnische Fehler schließe ich aus, da ich ja nicht komplett
inkompetent bin.
Lötstellen berühren sich nirgends.
Wenn es so einfach ist, bist du sicher das der Controller überhaupt
läuft?
Nicht glauben sondern testen. Lass mal eine LED blinken.
Wie hast du deinen Timer eingestellt, wenn du nicht mal die Taktfrequenz
weiss.
Ryan Polster schrieb:> Ein Foto der Schaltung habe ich grad nicht auf dem Rechner und finde es> zu viel Arbeit eines zu machen und hochzuladen weil die Schaltung so> trivial ist.
Na dann sollten Deine Probleme ja alle zu deiner Zufriedenheit gelöst
sein.
Viel Spaß noch mit dem Display habe auch solche sind echt nicht
verkehrt.
Gruß Ronny
In meinem Programm verwende ich keine Timer.
Ich habe keine Kondensatoren verschalten.
Die Spannungsversorgung habe ich von einem normalen Netzteil. Einfach
abgeschnitten & Krokodilklemmen drauf ^^
Habe jetzt einen komplett neuen, noch nie benutzten ATMega16 genommen
und ihm das Programm verpasst. Auch der geht nicht.
Ich versuche das mit der LED mal.
Ja der Controller läuft. Der gesamte PORTB funktioniert einwandfrei.
Habe es mit den LEDs vom STK500 probiert. Erwähnenswert ist nur das die
invertiert sind.
>Ein Foto der Schaltung habe ich grad nicht auf dem Rechner und finde es>zu viel Arbeit eines zu machen und hochzuladen weil die Schaltung so>trivial ist.
Ich bin dann mal raus. Bringt nichts mehr.
Ryan Polster schrieb:> Habe es mit den LEDs vom STK500 probiert.
Das heißt aber nicht das es in deiner Schaltung auch funktioniert, bzw.
der Controller läuft.
@holger: Ich habe versucht die Fotos direkt via Iphone hochzuladen. Das
ging leider nicht. Da habe ich einfach die Verbindungen gepostet. Ob
sich zwei Lötstellen berühren oder ob kalte Lötstellen vorhanden sind
kann ich selbst nachsehen, hoffentlich ^^
Ryan Polster schrieb:> Das verstehe ich nichts ganz. Wie werden denn dann die LEDs auf dem> Board angesteuert wenn nicht vom µC?
Auf dem STK ist der Controller optimal versorgt.
Ob das in deiner Schaltung mit dem LCD auch so ist, bezweifle ich laut
deinen Ausführungen ohne Kondensatoren, doch etwas.
Also so war das gemeint.
Die Initiative mit den Kondensatoren ergreife ich später.
Habe gerade beim Ausmessen bemerkt dass sich 3 Datenleitungen berührten.
Bin grad am Ausbessern.
Dieser große Fehler blieb unerkannt weil ich so eine Busleitung für die
Daten genommen habe zwecks Übersichtlichkeit.
Falls das auch nicht funktioniert werde ich wohl ein paar Kondensatoren
verschalten müssen.
Weißt du zufällig auch wo die überall hingehören?
TaTa!
Ryan Polster schrieb:> Weißt du zufällig auch wo die überall hingehören?
Steht in der AP zum Datenblatt des AVR und ja Stichwort -
Stromversorgung, AVcc, Quarz Bürde usw.
Ryan Polster schrieb:> Erwähnenswert ist nur das die invertiert sind.
Invertiert gegenüber was?
Hast du irgendeine Vorstellung wie die LEDs zum Leuchten angesteuert
werden müssen und warum?
Ryan Polster schrieb:> Weißt du zufällig auch wo die überall hingehören?
Guck dir einfach 100 Schaltungen mit 'nem ATmega16 an. Geh' davon aus,
dass 30% ok sind und beim Rest kommt schnell das Gemecker über die
Kondensatoren.
Ryan Polster schrieb:> Ich liste mal alle Verbindungen auf:
Mach das in einem Schaltplan. Damit unterhalten sich Elektroniker.
Hast du eigentlich schon mal eine LED zum Blinken gebracht? Und einen
Taster eingelesen?
Ich frage mich immer: wie kommen die Leute auf die Idee, ohne jede
Ahnung von der Materie gleich in der Oberliga spielen zu wollen?
Es ist nicht schwer, ein LCD anzusteuern. Nur muss man an irgendeiner
Stelle dann selber anfangen zu Denken...
Hi
Deine Aussagen:
>Schaltungstechnische Fehler schließe ich aus, da ich ja nicht komplett>inkompetent bin.>Lötstellen berühren sich nirgends.>Problem gelöst.. In der Daten-Busleitung berührten sich 3 Leitungen.
Mit deiner Inkompetenz hast du hier Völkerstämme beschäftigt.
MfG Spess