PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD will nicht :(



noNeed 4 aNick
14.01.2005, 16:49
Hi zusammen,
Ich hab gerad meinen LCD-Screen angeschloßen und wollte mit Peter Fleurys LCD-Libary das ganze mal testen.

Der Code is der folgende:


#include <inttypes.h>
#include <avr/io.h>
#include <LCD/lcd.h>
#include <LCD/lcd.c>

#define Pin1 0
#define Pin2 1
#define Pin3 2
#define Pin4 3
#define Pin5 4
#define Pin6 5
#define Pin7 6
#define Pin8 7

#define XTAL 8000000

#define LCD_PORT PORTC

#define LCD_DATA0_PORT LCD_PORT
#define LCD_DATA1_PORT LCD_PORT
#define LCD_DATA2_PORT LCD_PORT
#define LCD_DATA3_PORT LCD_PORT

#define LCD_RS_PORT LCD_PORT
#define LCD_RW_PORT LCD_PORT
#define LCD_E_PORT LCD_PORT

#define LCD_DATA0_PIN Pin1
#define LCD_DATA1_PIN Pin2
#define LCD_DATA2_PIN Pin3
#define LCD_DATA3_PIN Pin4

#define LCD_RS_PIN Pin5
#define LCD_E_PIN Pin6
#define LCD_RW_PIN Pin7


int main (void)
{
DDRB = 0x00;
PORTB = ~( (1 << Pin1) | (1 << Pin2) );

lcd_init(LCD_DISP_ON);
lcd_puts("Hello World :-)");

while (1) {}
}

Nur es passiert nix :(
Daher hab ich mal alle Befehle, sowie die includes für die Libary ausgeklammert, denn dann müssten zumindest die an PortB angeschloßenen LEDs leuchten.
Dem ist jedoch nicht so...

Aber davor kommen doch gar keine Befehle ?! Der kann doch nicht bei den #define-Befehlen abstürzen?!

Alternativ hab ich nen kleines Programm für LED-Ansteuerung auf den µC geladen und da leuchteten die LED's...
Also falsche Verkablung oder so könnte zwar daran Schuld sein, dass das LCD nicht arbeitet, aber dann müssten zumindest die LEDs leuchten...

Was tun?

ThxInAdv
Alex

Pascal
14.01.2005, 17:25
um welchen AVR handelt es sich denn?

noNeed 4 aNick
14.01.2005, 17:30
Ein ATmega16 mit 8 Mhz...

Pascal
14.01.2005, 17:45
hast du das JTAG deaktiviert?
das gibts ab dem ATMEGA16, liegt am Port C und ist standartmäßig aktiviert
wenn man nun was daran anschließt, kann man machen, was man will, der Port macht, was er will...
also entweder schließt du das an einen anderen Port an oder deaktivierst das JTAG-Interface(per Software(steht im Datenblatt, wie) oder per Fusebits)

noNeed 4 aNick
14.01.2005, 17:54
Hmm, also bei JTAGEN war tatsächlich ein Häckchen...dieses hab ich jetzt entfernt...
Aber geändert hat sich nichts :(

bluebrother
14.01.2005, 21:19
geht es wenn du einen anderen Port nimmst? Würde PortB vorschlagen.
Hast du mal die Frequenz überprüft? Passiert denn überhaupt was auf den Ports?

noNeed 4 aNick
15.01.2005, 15:56
Was meinst du mit Frequenz?
Und was sollte ich denn wo messen können?

noNeed 4 aNick
15.01.2005, 18:27
Hi zusammen,
da ich nix traue, was ich nicht selber geschrieben habe, hab ich versucht, mithilfe der LCD-Schilderung von www.mc-project.de selber das LCD anzuwerfen:


#include <inttypes.h>
#include <avr/io.h>

#define Pin1 0
#define Pin2 1
#define Pin3 2
#define Pin4 3
#define Pin5 4
#define Pin6 5
#define Pin7 6
#define Pin8 7

#define DataPin1 Pin1
#define DataPin2 Pin2
#define DataPin3 Pin3
#define DataPin4 Pin4

#define PinRS Pin5
#define PinE Pin6
#define PinRW Pin7


void delay(int ms)
{
int i,j;
for (i = 0; i < ms; i++)
for(j = 0; j < 8000; j++)
asm volatile ("nop");
}

void toggle_e(void)
{
PORTC |= (1 << PinE);
asm volatile ("rjmp 1f\n 1:");
PORTC &= ~(1 << PinE);
}


void waitWhileBusy(void)
{
DDRC |= ~(1 << DataPin4);
PORTC |= ( (1 << PinRW) | (1 << PinE) );

while ( ( PINC & (1 << DataPin4) ) )
asm volatile ("nop");

DDRC &= (1 << DataPin4);
PORTC &= ~( (1 << PinRW) | (1 << PinE) );
}

int main (void)
{
DDRB = 0xFF;
PORTB = ~( (1 << Pin1) );

DDRC = 0xFF;
PORTC = 0x00;

delay(17);

PORTC = (1 << DataPin2) | (1 << DataPin1);
toggle_e();
delay(5);
toggle_e();
delay(1);
toggle_e();

delay(2);
PORTC = (1 << DataPin1);
toggle_e();

PORTC = (1 << DataPin2);
toggle_e();
PORTC = (1 << DataPin4);
toggle_e();

delay(5);
PORTB = ~( (1 << Pin1) | (1 << Pin2) );
PORTC= 0x00;

PORTC = 0x00;
toggle_e();
PORTC = (1 << DataPin4);
toggle_e();

delay(5);
PORTC= 0x00;

PORTC = 0x00;
toggle_e();
PORTC = ( (1 << DataPin4) | (1 << DataPin3) );
toggle_e();


delay(5);
PORTC= (1 << PinRS);

PORTC |= ( (1 << DataPin4) | (1 << DataPin3) );
toggle_e();
PORTC |= ( (1 << DataPin4) | (1 << DataPin3) );
toggle_e();

PORTB = ~(1 << Pin2);


while (1) {}
}

Klappt auch ohne Probleme, nur beim letzen Übermitteln setze ich RS auf hi, damit der das als Schriftzeichen interpretieren soll.
Aber das Display bleibt leer :(

Die LEDs arbeiten aber sauber...
Was mich verwundert ist, dass das Programm hängenbleibt, sobald ich die Prozedur waitWhileBusy aufrufe, daher hab ich jetzt alles mit delays gelöst...
Vllt stimmt was mit dem RW Kabel nicht oder so - das würde zumindest erklären, warum die Libary immer hängen blieb....

Aber richtig zufriedenstelllend is dieses Zwischenergebnis nun auch nicht...
Any Vorschläge?

Bye
Alex

pebisoft
18.01.2005, 13:56
dieses hasse ich an c: eine verfluchte, komplizierte, verdammte, zum haare raufen, herzinfarktproduzierende, ärgerniserregende sch..ße.
nicht mal ein stinknormales display bekommt ein anfänger damit zu laufen. es ist zum kotzen. soviele titel gibt es schon und alle haben das perfekte ansprechen eines display noch nicht geschafft. sind die alle zu blöde, nein, es liegt an c. für mich gibt es kein ärger mehr, ich habe ein haus, ein pferd und natürlich "bascom", einfach und fast problemlos.
mfg pebisoft

noNeed 4 aNick
18.01.2005, 14:58
Meiner Meinung nach is C genial.

Ich kann mir nicht vorstellen, dass jmd, der mit basic mit 2-3 Befehlen nen funzendes LCD zusammenbastelt auch nur die geringste Ahnung davon hat, wie die Kommunikation zwischen dem Display und dem µC funktioniert.

Das is genauso wie die Leute die die mit VisualBasic coden... Das is doch keine richtige Sprache mehr.

Meine Meinung ist, dass Basic für die Leute gut is, die keine Zeit haben, sich mit sowas zu beschäftigen, oder grundsätzlich kein gutes Verständnis für Informatik haben...

Übrigens ist nicht die Kommunikation mit C schwierig, sondern grundsätzlich die Kommunikation - Wenn du mit bascom die passenden Pins an und ausschaltest und dadurch auch die HexCodes überträgst, is das auch nicht wirklich einfacher als mit C.

Ich persönlich hab's nun schon geschafft Zeichen auszugeben und zwar nachdem ich 2 mal den kompletten Code verworfen habe
Resultierend kann ich sagen, dass ich dadurch einen riesigen Lerneffekt erfahren habe und ich würd sicher auch noch schöne Output Prozeduren hinkriegen, wenn ich nicht meinen µC geschrottet hätte ;)

Welche Sprache man wählt liegt doch nur an den Interessengebieten - wer sich lieber mit mechanischen Feinarbeiten am Bot rumschlägt und die Sprache vernachlässigt, für den is Bascom sicher das Richtige...

btw, verwende auch wenn du wütend bist vllt ein paar Linefeeds und groß/KLEINschreibung - macht die Texte doch ein wenig lesbarer...

My 2 Cents

bluebrother
18.01.2005, 15:14
@noNeed 4 aNick:
Danke für diese Zeilen :-)

bluebrother (... findet Basic für AVRs auch ziemlich daneben -- und für hardewarenahes Programmieren ungeeignet)

Felix G
18.01.2005, 15:50
Also ich finde C auch besser als Basic.

Und ich habe eine LCD-Bibliothek für den KS0073(nahezu 100% HD44780 kompatibel) geschrieben.
Sie ist noch lange nicht fertig, und leider kann ich daran momentan nichts mehr machen (keine Zeit)

Aber sie sollte schon jetzt in der Lage sein ein Display (mit KS0073) anzusteuern,
und zwar völlig unabhängig davon wie es angeschlossen ist.

Es geht sowohl 4- als auch 8-Bit und es ist völlig egal wie die Steuerleitungen angeschlossen sind.
(den 4-Bit Modus habe ich allerdings noch nicht testen können)
Bei den Datenleitungen gibt es nur die Einschränkung, daß es mindestens 4 aufeinanderfolgende Pins eines Ports sein müssen.
(es ist aber egal ob das die Pins 0-3 sind oder z.B. 2-5)


Von der Funktionalität ist auch alles wesentliche schon drin.
man kann dem Display Befehle schicken, Daten auslesen (also Adresse & Busy-Flag), einzelne Zeichen oder auch ganze Strings ausgeben.
Dabei wird auch "\n" erkannt, und das Display springt in die nächste Zeile.
Es existieren auch zwei Funktionen SetPos und GetPos um den Cursor an eine bestimmte Position zu setzen bzw. die Cursorposition auszulesen.

Wenn man möchte kann man das ganze in Kombination mit fprintf() verwenden, und so formatierten Text ausgeben.

Beispiel:

float atemp;

fprintf(lcdout, "Aussentemperatur: %f°C", atemp);


Ich stelle die Bibliothek jetzt mal hier rein, obwohl sie noch nicht fertig ist



Ich würde mich sehr über konstruktive Kritik freuen...
also wenn ihr Verbesserungsvorschläge habt, immer her damit :)

bhm
18.01.2005, 17:17
ahhh, endlich! ein kleiner Flamewar :evil:
Also, ein großer Freund von C bin ich auch nicht. Ich wundere mich immer wieder wieviele Fehler man (ich) in ein paar Zeilen machen kann.
Allerdings kostet der gcc nix (ausser vielleicht Zeit) und erzeugt wirklich sehr kompakten Code. Ausserdem _ist_ µC-Programmierung sehr hardwarenah und die einzige Alternative wäre meiner Meinung nach Assembler, und es gibt nur eins was über ist als C, Assembler (naja vielleicht noch Cobol ..).
Bascom ist sehr mächtig, hat aber meiner Meinung nach den Nachteil, dass ich nicht wirklich weis, was ich tue und wenn's dann doch nicht sofort geht (in C der Normalfall) habe ich aber auch wenig Möglichkeit zu sehen, wo es schief geht. Ich kann naürlich auch die Register direkt programmieren, aber dann ist der Vorteil von Bascom dahin.

just my 0.02€
... bernd

pebisoft
18.01.2005, 20:54
hallo, gestern um 12.30 uhr hat schon einer nach dem rat gefagt. bitte helft ihn doch einmal so, das sein display funktioniert. ihr könnt den armen doch nicht so einfach hängen lassen. in bascom hätte ich ihn nicht in stich gelassen. seid so nett.
mfg pebisoft

Felix G
18.01.2005, 21:12
meinst du etwa diesen thread (https://www.roboternetz.de/phpBB2/viewtopic.php?t=6042)?

Dann verstehe ich ehrlichgesagt nicht was du willst http://unrealed.myexp.de/forum/style_emoticons/default/hmpf.gif
bluebrother hat ihm ja gestern schon geholfen.

Thorsten
18.01.2005, 21:34
@pepisoft
Ich versteh dich irgendwie nicht, erst schimpfst du über c ohne auf die
Frage bezug zu nehmen, dann bettelst du um hilfe für ihn.
Hätest du gernichts gesagt wärs genause gelaufen.
Nichts gegen dich, aber irgendwie trägst du auch nichts zur
Problemlösung bei.

flamer_war(end)


@noNeed 4 aNick
Ich jenn mich mit Peter Fleurys Librarie nicht aus, aber wenn du willst
kann ich dir ne einfache (Test)Lcd bibliothek schicken, mit der du
zumindest das LCD testen kannst. Ich hab bisher ne komplette lcd
bibliothek selber geschrieben, nicht weil ich es besser kann sondern um
dir Grundlagen zu lernen (Also kein perfekter Code, aber mein :-)

Ich helfe gern,
also nur melden.

noNeed 4 aNick
18.01.2005, 23:08
Danke nett von dir, aber auch mich reizt es mehr, dass ganze auf eigene Faust zu programmieren - besonders weil ich es doch auch schon geschafft hab, was auf dem LCD auszugeben...
Wenn auch nicht ganz das, was ich vorhatte :)

Wahrscheinlich irgendwelche Pins vertauscht oder so...

Thorsten
18.01.2005, 23:15
Ja, dass selber lernen hat mich auch gereizt. Und wenn jetzt schon was angezeigt wird
kann es nur besser werde ( Kenn ich aus eigener Erfahrung *g*)
Auf jeden Fall noch viel Spaß und Erfolg

noNeed 4 aNick
22.01.2005, 15:30
*hochschieb*
Ich fänds jetzt blöd, nen neuen Thread zu eröffnen, weil's mehr oder weniger immernoch ums selbe Thema geht.

Mittlerweile läuft mein LCD einwandfrei jedoch nur auf einer Zeile...
Wenn der Strom eingeschaltet ist und das LCD noch nich initialisiert ist, ist auch nur die obere Zeile schwarz, die untere bleibt leer (Weiß nicht, ob man dem jetzt irgend eine Bedeutung zuschreiben kann).

Nun weiß ich nicht, ob der im LCD eingebaute Controller automatisch nach Zeilenende die Zeile wechselt, aber ich denke mal nicht, denn als ich es mal mit nem langen String versucht habe, blieb der hintere Rest weg.

In anderen Lib's hab ich immer wieder getPos / setPos Funktionen gesehn, weiß aber nicht genau, wie die realisiert werden, denn ich hab in meinem Datenblatt keinen Befehl für die Positionierung gefunden (Bis auf den Cursor nach links/rechts bewegen; aber das bringt mir ja nix, wenn ich ne neue Zeile haben will...)

Also wat nu?

Felix G
22.01.2005, 16:29
In meiner Lib kann man eigentlich ganz gut sehen wie das funktioniert...


Um den Cursor an eine bestimmte Position zu setzen gibt es, zumindest beim KS0073,
den Befehl "Set-DDRAM-Address" mit dem Instruction-Code 0x80+Addresse.
Die unteren 7-Bits enthalten dabei also die Addresse an die der Cursor gesetzt werden soll.



Das Lesen der Position funktioniert praktisch genauso, und ist im Prinzip ein "Abfallprodukt" wenn man das Busy-Flag überprüft.
Denn das Busy-Flag ist ja das 8. Bit, und in den unteren 7 Bit steht die Addresse an der sich der Cursor momentan befindet.
Die kriegt man also quasi gratis dazu.

noNeed 4 aNick
23.01.2005, 13:12
Hmm, aber wie komm ich nun in die 2te Zeile?
Nehm ich dann als Position 17? (Mein Display is 16x2 groß).

Und wie krieg ich das beim lesen hin, alle 8 Bits zu lesen, ich hab nur 4 Datenleitungen - ich denk mal 2 Lesevorgänge oder so?!

Felix G
23.01.2005, 13:39
Du musst dir mal das Datenblatt von dem LCD Controller anschauen der in deinem Display sitzt, da steht das alles drin.

Bei meinem 4x20 LCD z.B. haben die Zeilen die Addressen 0x00, 0x20, 0x40 und 0x60.

Da das aber hexadezimale Zahlen sind bedeutet das, daß der "Abstand" nicht 20 sondern 32 ist, also 12 mehr als nötig.
(das muss aber nicht immer so sein)

Aber wie gesagt, im Datenblatt stehen die Addressen.



Und ja, beim 4-Bit Modus muss man je zweimal lesen bzw. schreiben.

Möchte man z.B. irgendwas ans Display senden, dann setzt man zuerst RS (falls nötig) und gibt die erste Hälfte (die oberen 4 Bit) der Daten an den Bus.
Damit das Display die Daten übernimmt muss man Enable kurz setzen und gleich wieder löschen. (also L-H-L)
Dann kommen die unteren 4 Bit, und wieder ein Impuls auf Enable.


Beim Lesen geht das ganz ähnlich:
Zuerst setzt man R/W dann setzt man Enable.
Das Display gibt jetzt die oberen 4-Bit auf den Bus, die man dann sinnvollerweise einlesen sollte.
Danach löscht man Enable wieder.
Die zweite Hälfte kriegt man genauso... also EN=H -> Daten einlesen -> EN=L