mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD am PIC 16F877


Autor: Marco Schulze (sharkman)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich bastel an dem ganzen jetzt schon seid ner ganzen weile, aber ich 
find den verdammten fehler einfach nicht. ich krieg das lcd leider 
einfach nicht zum laufen. hab schon eine ganze menge drüber gelesen, 
aber funktionieren mag der spaß einfach nicht.

ich hab mir das ganze auch schon in der simulation in mplap angeschaut 
und das mit funktioniernden versionen verglichen. sieht auch meiner 
meinung nach gleich aus. vielleicht kann ja jemand mal schauen wo mein 
fehler liegt oder mir sagen was ich anders machen muss.

wäre echt super und schon mal danke im voraus

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>und das mit funktioniernden versionen verglichen.

Warum nimmst du die funktionierenden Versionen nicht
einfach? Gut, dann musst du das Display auch genauso anschließen.
Zeigt das Display bei dir überhaupt irgendwas an?
Kontrast aufgedreht? Oft ist das LCD einfach nicht
richtig angeschlossen. Mindestens zehn mal kontrollieren.
Kurzschlüsse, fehlende Verbindungen suchen.
Erst danach zweifelst du an deiner Software.

Als erstes würde ich dir vorschlagen mal
auf den Busy Check zu verzichten und da einfach
ein paar Delay20ms einzufügen. Das vereinfacht die
Fehlersuche.

Autor: Marco Schulze (sharkman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also verbindungen und alles ist ok. das display ist gescheckt. ist 
mittlerweile sogar ein neues dran. ich hab es auch schon mal mit einer 
version von sprut versucht, die sollte allerdings auf nem 16f84 laufen 
und da hat das portieren irgendwie auch nicht geklappt.

das ist ja das problem an dem ich verzweifle.

das lcd funktioniert. zeigt auch brav den balken an wenn ich es ohne µC 
anschalte. mit µC verschwindet nach dem ersten durchlaufen der balken 
und das wars. dann werd ich mich wohl mal dran machen und den ganzen 
spaß nochmal durch schecken wegen den verbindungen.

dachte, vielleicht kann jemand das auch mal als testschaltung aufbauen, 
um sehen ob es an mir liegt oder an der software.

Autor: Marabel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Marco,

ich habe deinen Code mal grob überflogen und einige Unregelmässigkeiten 
gefunden.
Du benutzt z.B. einen Befehl, den es gar nicht gibt:
In OUT_LCD_DATEN steht "movfw LCD_DATEN"...
"movfw" konnte ich in keiner Literatur finden.
Um den Wert eines Registers oder Variablen ins W-Register zu kopieren, 
solltest du "movf xyzRegister,0" schreiben.
Also sollte es heissen:
"movf LCD_DATEN,0"
("movfw" steht auch an anderen Stellen im Code, die solltest du alle mal 
korrigieren, evtl. löst das schon deine Probleme!)

Ich kann mir immer nicht merken, ob 0 oder 1 für das W-Register steht, 
daher schreibe ich im Variablenteil immer die Zeilen "w equ 0" und "f 
equ 1", dann kann der Befehl lauten: "movf xyzRegister,w", um den Wert 
ins W-Register zu laden. (oder "... ,f" um ins Register selbst zu laden)

Des Weiteren ist deine Werteübergabe unsinnig:
Beim Aufruf von OUT_LCD_DATEN z.B. aus der Main-Funktion lädts du das 
auszugebende Zeichen ins W-Register und dann in die Variable LCD_DATEN.
Dann, in der Funktion OUT_LCD_DATEN lädts du den Inhalt des W-Registers 
in die Variable LCD_DATEN.
Das ist an dieser Stelle zwar nicht falsch, aber überflüssig, da der 
Wert schon in der Variablen gespeichert ist.

In OutLCD steht z.B. als dritter Befehl "movfw LCD_DATEN"
die Zeile kannst du komplett löschen, weil überflüssig...


Korrigiere deinen Code mal hinsichtlich dieser Dinge und teste noch mal.
Falls das noch nicht geht, poste den aktualisierten Code noch mal.

MfG - Marabel

PS:
Die Kombination
"#define ENABLE PORTB, 2; LCD ENABLE"
und
"bcf ENABLE"
kannte ich noch nicht, klingt aber sehr schön. Das werde ich mal testen 
und ggf. in meinem Projekt übernehmen!

Autor: Marabel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups, die Zeile in OutLCD natürlich nicht löschen, sondern korrigieren!
Sorry - mein Fehler...

Marabel

PS:
Grundsätzlich übergibst du die Parameter von einer Funktion zur nächsten 
mal über eine Variable und mal über das W-Register.
Das solltest du vereinheitlichen, damit du nicht selbst durcheinander 
kommst...
Oder Leute, die versuchen, deinen Code zu korrigieren ;-)

Autor: Marco Schulze (sharkman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok.

ich werd mir mühe geben. werde das ganze denn nachher mal umschreiben.

der befehl movfw existiert aber meines wissens nach, und er sollte 
eigentlich auch funktionieren, da ich den schon in anderen, 
funktionierenden projekten verwendet habe.


aber ich werd es einfach mal ausprobieren. vielleicht war es auch 
einfach nur zufall, dass es damals funktioniert hat.

danke schon mal für die nützlichen tipps. ich werd mich einfach mal dran 
setzen und dann berichten ob es nun geht oder nicht.

Autor: Marco Schulze (sharkman)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
so ich hab die änderungen vorgenommen und die platine nochmal gescheckt.

es sieht jetzt schon ein bisschen besser aus, aber es funktioniert immer 
noch nicht so wie es soll.

zwischenzeitlich werden jetzt einzelne blöcke schwarz, aber nicht die 
gewünschten und nicht so wie sie sollen. also sie werden einfach 
komplett schwarz. da stehen sollten ja aber eingentlich buchstaben

Autor: Marabel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe da noch einen Fehler in OUT_LCD_DATEN:
Du setzt die Steuerleitungen des Displays, prüfst dann, ob das Display 
bereit zur Datenannahme ist und versuchst dann die Daten 
hineinzuschreiben.
ABER:
Die Funktion LCD_BUSY verdreht dir die RS-Leitung!
In OUT_LCD_DATEN setzt du diese Leitung auf High, LCD_BUSY setzt sie 
wieder auf Low, denn du hast am Ende der Funktion das "bsf RS" 
auskommentiert - das ist dumm...

Aber um dieses Problem sauber zu umgehen, folgender Vorschlag:
In OUT_LCD_DATEN prüfst du zuerst, ob das Display bereit ist.
Danach setzt du die Steuerleitungen so, wie du sie brauchst und 
überträgst das Datenbyte zum Display.


Nur am Rande:
Grundsätzlich ist deine Parameterübergabe an andere Funktionen aber 
immer noch unsauber.
Zwar nicht falsch, aber du verschenkst Speicherplatz.
Z.B wird die Variable "Hilf" hier und da unnötigerweise eingesetzt.
Geh mal ganz in Ruhe den Programmablauf durch, und notiere mal den 
Datenfluss der übergebenen Werte, dann wirst du feststellen, dass du die 
an einigen Stellen doppelt speicherst.

Z.B.:
Die Funktion Init_LCD ruft die Funktion OutLCD auf:
Init_LCD speichert den zu übergebenden Wert in der Variablen "Hilf" (und 
im W-Register).
OutLCD kopiert den Inhalt von "Hilf" ins W-Register, in welchem der Wert 
aber sowieso immer noch drin steht und speichert ihn nochmal in der 
Variablen "LCD_DATEN". Zu diesem Zeitpunkt ist derselbe Wert in 3 
verschiedenen Registern vorhanden - zwei davon sind unnötig...

Aber wie gesagt, das erklärt nicht deine Probleme mit der korrekten 
Ausgabe am Display. Soll nur ein Hinweis für Optimierungen sein...

MfG - Marabel

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marabel wrote:
> Hallo Marco,
>
> ich habe deinen Code mal grob überflogen und einige Unregelmässigkeiten
> gefunden.
> Du benutzt z.B. einen Befehl, den es gar nicht gibt:
> In OUT_LCD_DATEN steht "movfw LCD_DATEN"...
> "movfw" konnte ich in keiner Literatur finden.

Doch den Befehl gibt es. Allerdings sind das Pseudobefehle, welche der 
Assembler wieder umstrickt. Es gibt auch noch andere solcher Befehle. 
Schau mal in der Hilfe zu MPASM unter "12-Bit/14-Bit Instruction Width 
Pseudo-Instructions" dort sind sie alle aufgeführt und auch was der 
Assembler daraus für einen Code erzeugt.

>
> Ich kann mir immer nicht merken, ob 0 oder 1 für das W-Register steht,
> daher schreibe ich im Variablenteil immer die Zeilen "w equ 0" und "f
> equ 1", dann kann der Befehl lauten: "movf xyzRegister,w", um den Wert
> ins W-Register zu laden. (oder "... ,f" um ins Register selbst zu laden)

Das musst du auch nicht extra definieren, da es schon in den .INC 
Dateien zu dem jeweiligen Prozessor definiert wird. Du kannst also ruhig 
W und F schreiben an den Stellen wo eine 0 oder eine 1 hingehört.

Gruß Sven

Autor: Marabel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah ja,
danke für die Hinweise.

Sehr interessant zu wissen, dass es da noch mehr Psudocodes gibt.

Allerdings werde ich die so gut ich kann ignorieren, da im Proz das 
stehen soll, was ICH will und nicht was irgendein Programm denkt, was 
ich wohl meine, im Proz stehen haben zu wollen.
Speziell bei den Pseudocodes, die in zwei Befehle gewandelt werden, kann 
man massive Kopfschmerzen bekommen, wenn ein bedingter Sprung davor 
steht.

Trotzdem besten Dank für den Hinweis - man lernt eben nie aus!

PS: die Sache mit dem w und f steht tatsächlich in der Includedatei.
Anfangs habe ich die aber garnicht eingebunden, damit ich verstehe, was 
im Prozessor vor sich geht und wo bzw. in welchen Registern ich nach 
bestimmten Bits zu suchen habe.

MfG - Marabel

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man muss diese Befehle ja auch nicht benutzen. Ich benutze von diesen 
Befehlen auch nur den movfw Befehl, weil das optisch irgendwie besser 
aussieht als ein movf  Test,w  vor allem, wenn man vorher ein movwf 
hatte.

In Bezug auf die Kopfschmerzen sind deine Bedenken durchaus berechtigt. 
Das dumme ist, dass selbst dass Disassembly Listing, diese Befehle nicht 
aufgedröselt anzeigt. Da hab ich schon mal lange einen Fehler gesucht. 
Die wirklich benutzten Befehle werden nur im Menüpunkt Program Memory 
angezeigt.
Trozdem sind solche Befehle wie lgoto oder lcall recht praktisch, 
allerdings wirkt dann ein goto $-1 tödlich.....

Im übrigen sind in den Includedateien auch die Statusbits definiert. du 
kannst also auch btfss STATUS,C oder btfss STATUS,Z schreiben. Und das 
finde ich wirklich nützlich und übersichtlicher.

Sven

Autor: Marabel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da gebe ich dir 100%ig recht!
Ist deutlich einfacher und viel verständlicher.

Natürlich könnte man jetzt sagen: Aber programmieren in C ist doch noch 
viel einfacher...

Das ist zwar richtig, aber wenn es um exaktes Timing geht, ist C eben 
doch nicht so toll.

Ausserdem kann ich jedem Einsteiger nur dringend empfehlen, mit 
Assembler anzufangen, da man nur auf diesem Wege den Proz richtig kennen 
lernt.

Dass du einiges an Fachverstand mitbringst, hast du bewiesen, aber was 
sagst du denn zu dem geposteten Quellcode?
Hast du mal drüber gesehen und noch Fehler gefunden?

@Marco Schulze: Wie sieht es aus? Kommst du voran?
Halt uns bitte auf dem Laufenden!
Ich kann mich noch sehr gut an meinen Freudensprung erinnern, als ich 
mein erstes Hello World-Programm ans Laufen bekommen habe...

MfG - Marabel

Autor: Marco Schulze (sharkman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi.

ich bin heute leider nicht zu gekommen weiter zu machen. morgen mach ich 
mich wieder dran und denn berichte ich auch weiter.

ich hab auch shcon programme auf nem pic ans laufen bekomen, aber das 
lcd wurmt mich jetzt schon fast nen vierteil jahr. zwar immer mit 
pausen, aber es ärgert mich, dass ich das mistding nicht ans laufen 
bring.

denn bis morgen

Autor: Marco Schulze (sharkman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so ich hab mich mal dran gemacht, das lcd busy an den anfang von 
out_lcd_daten gesetzt. jetzt gehts.

besten dank

Autor: Marabel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja wie? Es geht?
Ist das alles?
Kein jubeln, schreien, freuen, dass das verda..te sch..ss Dr.cksdisplay 
endlich funktioniert?

Naja, immerhin hast du jetzt vermutlich viel Spass daran, sämtliche 
Möglichkeiten des Displays mal zu testen, jetzt da es funktioniert.
(Wichtig: Das aktuelle Projekt irgendwo hin kopieren, damit du immer auf 
eine lauffähige Referenz zurückgreifen kannst, falls mal etwas nicht so 
funktioniert, wie du willst!)

Dann kommt als nächstes ein 4-zeiliges Display, dann noch eines mit 40 
Zeichen, Selbstdefinition von Sonderzeichen, Display hin- und 
herscrollen und dann endlich mal ein Grafikdisplay mit einem T6963 
Controller im Bauch ;-)

MfG - Marabel

Autor: Marco Schulze (sharkman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja. sagen wir mal ich hab ein 10minütiges freudentänzchen aufgeührt. 
das muss reichen ;)

gesichert ist es auf alle fälle. nicht das es am ende dann doch nicht 
mehr geht.

als nächstes wird das ganze denn in eine 4bit version verwandelt.

da du das mit dem grafikdisplay ansprichst, dass wird auch in nächster 
zeit kommen. hab gestern was nettes zu gesicht bekommen. war gar nicht 
so teuer und höchst interessant.
War ein farbiges 2,1" grafik lcd. wäre schon ne schicke sache, ich hab 
nur noch keine verwendung dafür.
Das jetzte soll teil einer temperatur überwachung für meinen pc werden. 
wird demnächst alles kommen und es werden sicherlich auch noch probleme 
auftreten mit denen ich euch hier auch weiter beschäftigen werde :D

MfG Marco

Autor: Marco Schulze (sharkman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so leider steh ich jetzt schon wieder vor einem Problem.

Ich hab die software nochmal überarbeitet und ein wenig optimiert, damit 
die anzeige etwas fixer wird. in 8bit funktioniert der ganze spaß jetzt 
auch wunderbar. beim versuch das ganze jetzt in eine 4 bit version 
verwandeln scheiter ich aber schon wieder.

ich weiß nicht warum es nicht klappt, aber alles was er macht ist das 
display löschen. also geh ich mal von aus, dass die initialisierung noch 
halbwegs geschaut funktioniert.

ich hab nun noch ein paar fragen:
1.) Muss ich die initialisierung auf 4 bit auch 3 mal durchlaufen wie 
die für das 8bit interface am anfang?

2.) kann es sein, dass er richtig initialisiert, und in der ausgabe 
routine ein fehler ist.

ich hab das ganze nur um die 4 bit erweitert, sprich dass ich die daten 
in oberen und unteren teil splitte und diese dann im anschluss tausche 
und hinter einander sende. wenn ich das richtig verstanden habe, sollte 
das lcd das dann am ende begreifen, dass ich erst die oberen und dann 
die unteren 4 bit sende. ist das so, oder muss das genau anders rum?

Autor: Marabel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Am besten besorgst du dir das Datenblatt für den Hitachi HD44780U.
Da steht exakt beschrieben, wie das Display mit 4 oder 8 bit 
initialisiert wird.
Der grundsätzliche Ablauf ist gleich, aber natürlich mit 
unterschiedlichen Inhalten, bzw. 4- oder 8-bit-Bus.

Bei 4-bit-Betrieb wird erst das higher nibble und dann das lower nibble 
gesendet, also so, wie du es beschrieben hast.

In meinem Datenblatt steht das in etwa so:
Nach Einschalten min. 15ms warten
senden: 0011
min. 4,1ms warten
senden: 0011
min. 100µs warten
senden: 0011
Dann kommt die Konfiguration mit testen des BF-Flags:
0010

0010
NF**

0000
1000

0000
0001

0000
01 I/D S

wobei N=display lines, F=character font, I/D=increment/decrement und 
S=shift
*=1 oder 0, ist völlig egal...

MfG - Marabel

Autor: Marco Schulze (sharkman)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo.

ich hab jetzt schon mehrere datenblätter durchforstet und das ganze auch 
entsprechend gestaltet. Ich glaub nicht das es in der bitfolge hängt 
sondern eher irgendwo in der übertragung oder ähnlichem.

ich hab mal die 4 bit version nochmal drangehängt. vielleicht kann ja 
nochmal jemand einen blick drauf werfen. ich werd da momentan nicht 
schlau draus. für das projekt, für das ich es brauche, wird es nun 
erstmal in der 8bit version verwendet. dafür reichts, weil ich noch 
genug andere pins frei hab :-)

denn schonmal vielen dank, dass ihr so viel geduld mit mir habt

Autor: Marabel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, mir fällt da auch erstmal nichts dran auf.
Sieht sogar fast genauso aus, wie mein erster Versuch - ich glaube, wir 
haben vom selben Author abgeschrieben ;-)

Hast du die nicht benötigten Datenleitungen noch angeschlossen?
Falls ja: Klemm die mal ab.
Falls nein: Hast du die richtigen Leitungen angeschlossen/abgeklemmt?

MfG - Marabel

Autor: Marco Schulze (sharkman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also abgeschrieben hab ich bei sprut :-D ich denk mal das ist das pic 
standartwerk für pic anfänger.

Ich hab das sowohl als auch probiert. ich hab die leitungen d0-d3 
abgeklemmt und d4-d7 drangelassen. ich hab das aber auch 
sicherheitshalber mal andersrum gemacht. hat aber auch  nichts gebracht. 
ich find einfach nicht den fehler.

ich hatte irgendwann auch damit mal so mystiröse ausgaben, die einfach 
nur sinnlos waren. irgendwas in der art oo<-oo oder so ähnlich. keine 
ahnung was da schief gelauften war.

ich bin ja nur froh, dass es eigentlich ganz gut ausschaut. also kann 
ich nicht soviel falsch gemacht haben

falls doch noch irgendwas auffällt bitte melden. denn hab ich vielleicht 
doch noch ne chance das ans laufen zu bekommen.

Antwort schreiben

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

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.