Forum: Mikrocontroller und Digitale Elektronik LCD am ATmega8


von Alexander (Gast)


Lesenswert?

Hallo Leute,
ich hab einen ATmega8 und an den wollte ich ein 2*16 Display
anschließen.
1 Vss GND
2 Vcc 5V
3 Vee GND oder Poti (siehe oben)
4 RS PD4 am AVR
5 RW GND
6 E PD5 am AVR
7 DB0 GND
8 DB1 GND
9 DB2 GND
10 DB3 GND
11 DB4 PD0 am AVR
12 DB5 PD1 am AVR
13 DB6 PD2 am AVR
14 DB7 PD3 am AVR

Aber irgendetwas funzt net richtig, die erste Zeile ist immer schwarz
die zweite ist ganz normal. Das ist aber auch so wenn ich das Display
nicht ansteuere. Habt Ihr vielleicht eine Idee was ich da machen
könnte?

Danke

XEUS

von Sascha (Gast)


Lesenswert?

Dann ist das Display nicht oder nicht richtig initalisiert.
Mfg Sascha

von Dominik (Gast)


Lesenswert?

Schreib mal den Code hierrein, vielleicht kann dir ja dann geholfen
werden.

Dominik

von Alex (Gast)


Lesenswert?

Oder bemüh einfach die Forensuche, benutze Peter Pfleurys Bibliothek,
... Das Thema wurde hier schon x-mal abgehandelt.

von Alexander (Gast)


Lesenswert?

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                 LCD-Routinen                ;;
;;                 ============                ;;
;;              (c)andreas-s@web.de            ;;
;;                                             ;;
;; 4bit-Interface                              ;;
;; DB4-DB7:       PD0-PD3                      ;;
;; RS:            PD4                          ;;
;; E:             PD5                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



 ;sendet ein Datenbyte an das LCD
lcd_data:
           mov temp2, temp1             ;"Sicherungskopie" für
                                        ;die Übertragung des 2.Nibbles
           swap temp1                   ;Vertauschen
           andi temp1, 0b00001111       ;oberes Nibble auf Null setzen
           sbr temp1, 1<<4              ;entspricht 0b00010000
           out PORTD, temp1             ;ausgeben
           rcall lcd_enable             ;Enable-Routine aufrufen
                                        ;2. Nibble, kein swap da es
schon
                                        ;an der richtigen stelle ist
           andi temp2, 0b00001111       ;obere Hälfte auf Null setzen
           sbr temp2, 1<<4              ;entspricht 0b00010000
           out PORTD, temp2             ;ausgeben
           rcall lcd_enable             ;Enable-Routine aufrufen
           rcall delay50us              ;Delay-Routine aufrufen
           ret                          ;zurück zum Hauptprogramm

 ;sendet einen Befehl an das LCD
lcd_command:                            ;wie lcd_data, nur ohne RS zu
setzen
           mov temp2, temp1
           swap temp1
           andi temp1, 0b00001111
           out PORTD, temp1
           rcall lcd_enable
           andi temp2, 0b00001111
           out PORTD, temp2
           rcall lcd_enable
           rcall delay50us
           ret

 ;erzeugt den Enable-Puls
lcd_enable:
           sbi PORTD, 5                 ;Enable high
           nop                          ;3 Taktzyklen warten
           nop
           nop
           cbi PORTD, 5                 ;Enable wieder low
           ret                          ;Und wieder zurück


 ;Pause nach jeder Übertragung
delay50us:                              ;50us Pause
           ldi  temp1, $42
delay50us_:dec  temp1
           brne delay50us_
           ret                          ;wieder zurück

 ;Längere Pause für manche Befehle
delay5ms:                               ;5ms Pause
           ldi  temp1, $21
WGLOOP0:   ldi  temp2, $C9
WGLOOP1:   dec  temp2
           brne WGLOOP1
           dec  temp1
           brne WGLOOP0
           ret                          ;wieder zurück

 ;Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
lcd_init:
           ldi  temp3,50
powerupwait:
           rcall  delay5ms
           dec  temp3
           brne  powerupwait
           ldi temp1, 0b00000011        ;muss 3mal hintereinander
gesendet
           out PORTD, temp1             ;werden zur Initialisierung
           rcall lcd_enable             ;1
           rcall delay5ms
           rcall lcd_enable             ;2
           rcall delay5ms
           rcall lcd_enable             ;und 3!
           rcall delay5ms
           ldi temp1, 0b00000010        ;4bit-Modus einstellen
           out PORTD, temp1
           rcall lcd_enable
           rcall delay5ms
           ldi temp1, 0b00101000        ;noch was einstellen...
           rcall lcd_command
           ldi temp1, 0b00001100        ;...nochwas...
           rcall lcd_command
           ldi temp1, 0b00000100        ;endlich fertig
           rcall lcd_command
           ret

 ;Sendet den Befehl zur Löschung des Displays
lcd_clear:
           ldi temp1, 0b00000001   ;Display löschen
           rcall lcd_command
           rcall delay5ms
           ret

Bekomm immer nur in der ersten Zeile einen schwarzen Balken

gruß xeus

von andy (Gast)


Lesenswert?

Hallo.
Ich hab auch ein LCD an einen mega8 angeschlossen,genau so wie
du,klappt
einwandfrei.Wie hast du VEE angeschlossen,GND oder Poti?
Mit einem Poti ist auf jedenfall besser.Laut deinem programm schickst
du nur befehle zum LCD.Schick doch mal was zum LCD,zb.
das beliebte "Hallo Welt.".
mfg
Andy

von Alexander (Gast)


Lesenswert?

Hab es über ein Poti angeschlossen.
Ich glaub das es eigentlich funktionieren müsste. Aber ich hab noch
nicht so den Durchblick was, und wie ich das mit dem initialisieren
machen muss. Gibts da vielleicht ein fertiges script, dass ich nur
rauflade und das LCD zeigt mir irgendeinen Text an. So könnte ich
rausfinden ob es an mir oder an der Hardware liegt.

gruß

xeus

von andy (Gast)


Lesenswert?

hallo.
Schau mal hier im Tutorial unter lcd nach.Da hast du ja sicher auch
dein programm her.Darunter steht unter anwendung auch ein kleines
programm,was glaub ich den text test zum lcd schickt.Nimm dieses
programm,lösch die letzte zeile (include sowieso) und häng dein
programm einfach dran.
dann sollte es klappen.
gruss
Andy

von Daniel (Gast)


Lesenswert?

Hallo Alexander,

bei mir lag RW nicht an GND und ich hatte genau das selbe Fehlerbild.
Oberer Zeile schwarz, untere klar. Die untere hat auch nicht auf die
Kontrastspannung reagiert.

Daniel

von Alexander (Gast)


Lesenswert?

Also das prog ist ja das aus dem tutorial.
Aber wenn ich das prog zusammen mit der routine durch den assambler
schicke und es dann auf dem ATmega8 sende tut sich nichts, bis auf die
erste Zeile die immer schwarz ist.Und der Kontrasst funzt auch nur bei
der oberen. Ich hab pin1 , pin5, pin7, pin8, pin9 und pin10 an GND
angeschlossen. Hatt einer von euch vielleicht ein kleines prog, mit dem
ich einfache Funktionen meines ATmega8 testen könnte.
Mein Experimentierboard ist so aufgebaut:
Am Port B sind 5 LEDs angeschlossen (parallel dazu das Display, störren
die LEDs???)
am Port d 5 Taster
Wär echt voll cool wenn einer von euch ein kleines Prog zum
Funktionstest für die Schaltung hätte.

mfg
Xeus

von andy (Gast)


Angehängte Dateien:

Lesenswert?

Hallo.
Zum testen sollte das reichen.
Die leds an portb sollten im sekundentakt blinken bei 4mhz takt.
hoffentlich klappt das ja bei dir.
gruss
Andy

von andy (Gast)


Lesenswert?

Nochmal ich.Wieso ist dein lcd parallel zu den leds an portb
angeschlossen.Laut tutorial gehört es an portd.
gruss
Andy

von Alexander (Gast)


Lesenswert?

Ups da hab ich mich wohl vertan.
Die LEDs sind am PortB, die Taster am PortD dazu parallel das Display.
Übrigens das Prog funzt echt einwandfrei.Bleibt nur noch das Problem
mit dem Display.

von Stefan Kneller (Gast)


Lesenswert?

Hallo Alexander,

die Initialisierung des LCD ist fehlerhaft.
Ich hatte das gleiche Problem, weil ich die Betriebsarten 2-zeilig UND
4-Bit Bus gleichzeitig mit einem Kommando einstellen wollte.

Nachdem ich zuerst den 4bit-Modus und dann 2-zeilig gesendet habe gings
einwandfrei.

Ich habe gerade den Code gerade nicht hier, kann aber vielleicht heute
abend mal Auszüge posten.

Lade dir unbedingt das Datenblatt zu deinem Display runter und schau
dir an, welche Kommandos unterstützt werden.

Gruss
Stefan Kneller

von Stefan Kneller (Gast)


Lesenswert?

So, hier ist mein Beispielcode:

beachte, dass du nach Anlegen der Versorgungsspannung mindestens 10ms
bis zur Initialisierung des Display warten musst.
Das ist hier nicht extra implementiert.

lcd_init:
  ldi  temp,0b00000011  ;muss 3mal hintereinander gesendet
  out  PORTD,temp  ;werden zur Initialisierung
  rcall  lcd_enable  ;1
  rcall  delay5ms
  rcall  lcd_enable  ;2
  rcall  delay5ms
  rcall  lcd_enable  ;3
  rcall  delay5ms

  ldi  temp,0b00100000  ;set Function (zuerst mal 4 bit Interface
aktivieren)

  rcall  lcd_command  ;sonst komme ich nämlich nicht an Bit 3 ran (für
Modus 2-zeilig)

  rcall  delay5ms

  ldi  temp,0b00101000  ;set Function (2 zeilig, Font 5x7)
  rcall  lcd_command
  rcall  delay5ms

  ldi  temp,0b00001100  ;Display on/off Control (Display on, Cursor off,
Blinking off)

  rcall  lcd_command
  rcall  delay5ms

  ldi  temp,0b00000100  ;set Entry Mode (Cursor Direction right, Display
shift off)

  rcall  lcd_command
  rcall  delay5ms

  ret      ;fertig

Berichte mal, wenns geklappt hat.

Gruss
Stefan K.

von Alexander (Gast)


Lesenswert?

Vielen Dank Steffan für deine Hilfe, aber ich weiß ets grad net wirklich
was ich damit machen muss, soll ich das Script irgendwo einbauen?Wenn
ich es in AVR Studio kopiere und Starten will kommen nur Fehler.
Könntest du mir vielleicht weiterhelfen, steh grad aufm Schlauch.

Gruß

Xeus

von Alexander (Gast)


Lesenswert?

Also hab dein script wie folgt eingebaut:

lcd_init:
  ldi  temp1,0b00000011  ;muss 3mal hintereinander gesendet
  out  PORTD,temp1  ;werden zur Initialisierung
  rcall  lcd_enable  ;1
  rcall  delay5ms
  rcall  lcd_enable  ;2
  rcall  delay5ms
  rcall  lcd_enable  ;3
  rcall  delay5ms

  ldi  temp1,0b00100000  ;set Function (zuerst mal 4 bit Interface
            ;aktivieren)

  rcall  lcd_command  ;sonst komme ich nämlich nicht an Bit 3 ran (für
            ;Modus 2-zeilig)

  rcall  delay5ms

  ldi  temp1,0b00101000  ;set Function (2 zeilig, Font 5x7)
  rcall  lcd_command
  rcall  delay5ms

  ldi  temp1,0b00001100  ;Display on/off Control (Display on, Cursor
off,
            ;Blinking off)

  rcall  lcd_command
  rcall  delay5ms

  ldi  temp1,0b00000100  ;set Entry Mode (Cursor Direction right,
Display
            ;shift off)

  rcall  lcd_command
  rcall  delay5ms

  ret      ;fertig

 ;sendet ein Datenbyte an das LCD
lcd_data:
           mov temp2, temp1             ;"Sicherungskopie" für
                                        ;die Übertragung des 2.Nibbles
           swap temp1                   ;Vertauschen
           andi temp1, 0b00001111       ;oberes Nibble auf Null setzen
           sbr temp1, 1<<4              ;entspricht 0b00010000
           out PORTD, temp1             ;ausgeben
           rcall lcd_enable             ;Enable-Routine aufrufen
                                        ;2. Nibble, kein swap da es
;schon
                                        ;an der richtigen stelle ist
           andi temp2, 0b00001111       ;obere Hälfte auf Null setzen
           sbr temp2, 1<<4              ;entspricht 0b00010000
           out PORTD, temp2             ;ausgeben
           rcall lcd_enable             ;Enable-Routine aufrufen
           rcall delay50us              ;Delay-Routine aufrufen
           ret                          ;zurück zum Hauptprogramm

 ;sendet einen Befehl an das LCD
lcd_command:                            ;wie lcd_data, nur ohne RS zu
;setzen
           mov temp2, temp1
           swap temp1
           andi temp1, 0b00001111
           out PORTD, temp1
           rcall lcd_enable
           andi temp2, 0b00001111
           out PORTD, temp2
           rcall lcd_enable
           rcall delay50us
           ret

 ;erzeugt den Enable-Puls
lcd_enable:
           sbi PORTD, 5                 ;Enable high
           nop                          ;3 Taktzyklen warten
           nop
           nop
           cbi PORTD, 5                 ;Enable wieder low
           ret                          ;Und wieder zurück



 ;Pause nach jeder Übertragung
delay50us:                              ;50us Pause
           ldi  temp1, $42
delay50us_:dec  temp1
           brne delay50us_
           ret                          ;wieder zurück

 ;Längere Pause für manche Befehle
delay5ms:                               ;5ms Pause
           ldi  temp1, $21
WGLOOP0:   ldi  temp2, $C9
WGLOOP1:   dec  temp2
           brne WGLOOP1
           dec  temp1
           brne WGLOOP0
           ret                          ;wieder zurück



 ;Sendet den Befehl zur Löschung des Displays
lcd_clear:
           ldi temp1, 0b00000001   ;Display löschen
           rcall lcd_command
           rcall delay5ms
           ret


------------------------------------------------------------------
Diese Routine hab ich dann eingebaut und das ganze compiliert
------------------------------------------------------------------

.include "m8def.inc"
.include "LCDinit.asm"            ;LCD-Routinen
.def temp1 = r16
.def temp2 = r17
.def temp3 = r18


           ldi temp1, LOW(RAMEND)      ; LOW-Byte der obersten
RAM-Adresse
           out SPL, temp1
           ldi temp1, HIGH(RAMEND)     ; HIGH-Byte der obersten
RAM-Adresse
           out SPH, temp1

           ldi temp1, 0xFF    ;Port D = Ausgang
           out DDRD, temp1

           rcall lcd_init     ;Display initialisieren
           rcall lcd_clear    ;Display löschen

           ldi temp1, 'T'     ;Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 'e'     ;Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 's'     ;Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 't'     ;Zeichen anzeigen
           rcall lcd_data

loop:
           rjmp loop

--------------------------------------------------------------------
Das Prog hab ich aus dem Tut dieser Seite.
--------------------------------------------------------------------

Beides hab ich anschließend mit Pony hauf den mega8 geladen, den
Kontrast mit Hilfe eines 10kOhm Pottis eingestellt,
aber leider hab ich noch immer keine Veränderung, der Schwarze Palken
in der ersten Zeile i immernoch da und die zweite macht garnichts.


Hab parallel zu dem Disp (dass an pd0-pd3 angeschlossen ist)5
Taster(pull up pd0-pd4) angechlossen.Kann das der Grund für das
Nichtfunktionieren meines Disp sein?

gruß

Xeus

von Profi (Gast)


Lesenswert?

Wieviel Ohm haben denn die PullUps?
Werden die Leitungen richtig low, wenn sie als low-Ausgang geschaltet
sind?
Sind die Taster normal offen (NO) oder normal geschlossen (NC)?

von Alexander (Gast)


Angehängte Dateien:

Lesenswert?

habs gefunden.

funzt ohne treiber nur unter win9x

schau es dir mal an

gruß

xeus

von Alexander (Gast)


Lesenswert?

Ups das war wohl der falsche Thread!!!
sorry

von Alexander (Gast)


Lesenswert?

Upps das war wohl der falsche Thread!!!
sorry

von Alexander (Gast)


Lesenswert?

Hab die Taster weggenommen, aber es tut sich immer noch nichts

von andy (Gast)


Lesenswert?

Hallo.
Setz mal die Zeile:
.include "LCDinit.asm"            ;LCD-Routinen
ans ende des programms,nach der loop funktion.
Ich hab auch mal die include anweisungen am anfang gesetzt,und hatte
nur ärger.
Vielleicht hilft das ja.
gruss
andy

von Tobi (Gast)


Lesenswert?

wenn du die include an den anfang setzt wird die glaub ich mit
abgearbeitet, egal ob das nur unterprogramme sind. dehalb ans ende.
zu der zweiten zeile die nicht auf den kontrast reagiert... wie soll
sie auch. der kontrast ist die helligkeit der dargestelltenn(!)
zeichen. wenn keine zeichen in zeile 2 sind siehst du da auch keinen
kontrast

von Stefan Kneller (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Alexander,

im Anhang findest du den kompletten funktionierenden Code, damit dein
Display etwas zeigt. Zum Assemblieren brauchst du nur noch die Datei
m8def.inc bereitzustellen.
Sicherlich kannst du an einigen Stellen noch Code wegstreichen, die
Schnipsel stammen ursprünglich aus einer recht umfangreichen Software.

Gruss
Stefan K.

von Alexander (Gast)


Lesenswert?

Super Geil es Funzt!!!

Vielen Dank

Xeus

von Stefan Kneller (Gast)


Angehängte Dateien:

Lesenswert?

Tagchen Alexander,

ich dacht ich melde mich nochmal und gebe dir den Tip, es in deinem
Programm unbedingt mal mit dem LPM Befehl zu probieren. Du wirst sehr
schnell merken, wie komfortabel du dann Zeichenketten handeln kannst.

Vielleicht noch etwas: ich lagere meine Unterprogramme, Teile der
Hauptroutine, die LCD-Routinen und auch die Zeichenketten in externen
*.inc Dateien, die per include eingebunden werden, was die
Übersichtlichkeit im Hauptprogramm/der Hauptdatei*.asm wesentlich
erhöht.

Gruss

von Claudio (Gast)


Lesenswert?

Hab auch mal ne frage zu der TESTLCD2.ASM

Wie kann ich dort von PORTD auf PORTB umstellen?

hab alle DDRD durch DDRB und alle PORTD durch PORTB ersetzt aber es 
klappt nicht.


hat jemand ne idee dazu?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.