Forum: Mikrocontroller und Digitale Elektronik Probleme mit Display AV1624


von Lukas W. (lukaswe)


Lesenswert?

Hallo Leute!

Habe widermal ein problem!

Ich habe mir ein AV1624 Display zugelegt!
Mit der Hilfe des Tutorial habe ich mir eine Code geschrieben.

Jedoch das Display zeigt nur eine Zeile an und diese ist komplett 
ausgefüllt!

Dies ist mein code:


;DATUM
;xx
;Version x.x


;######################
;includierte Files
;######################

.include "M16def.inc"

;######################
;Variablen festlegen
;######################

.def TEMP2=R16
.def TEMP1=R17
.def TEMP3=R18
.def temp=R19
;.def x=R20

;#######################
;Interuptadressen
;#######################

  rjmp   Init      ; External Reset
  rjmp   unusedISR    ; External Interupt Request 0
  rjmp   unusedISR    ; External Interupt Request 1
  rjmp  unusedISR    ; Timer/Counter2 Compare Match
  rjmp  unusedISR    ; Timer/Counter2 Oberflow
  rjmp   unusedISR     ; Timer/Counter1 Capture Event
  rjmp   unusedISR     ; Timer/Counter1 Compare Match A
  rjmp   unusedISR     ; Timer/Counter1 Compare Match B
  rjmp   unusedISR     ; Timer/Counter1 Overflow
  rjmp   unusedISR     ; Timer/Counter0 Overflow
  rjmp   unusedISR     ; Serial Transfer Complete
  rjmp   unusedISR    ; USART, Rx Complete
  rjmp   unusedISR     ; USART Data Registry Empty
  rjmp   unusedISR     ; USART, Tx Complete
  rjmp   unusedISR     ; ADC Complete
  rjmp   unusedISR     ; EEPROM Ready
  rjmp  unusedISR    ; Analog Comperator
  rjmp  unusedISR    ; 2-wire Serial Interface
  rjmp  unusedISR    ; External Interrupt Request 2
  rjmp  unusedISR    ; Timer/Counter0 Compare Match
  rjmp   unusedISR     ; Store Programm Memory Ready

;#######################

init:

;#######################
;Ports Initialisieren
;#######################

ldi TEMP, 0xff    ;1 Ausgänge, 0 Eingänge
out DDRA, TEMP
ldi TEMP, 0xff    ;1 Ausgänge, 0 Eingänge
out DDRB, TEMP
ldi TEMP, 0xff    ;1 Ausgänge, 0 Eingänge
out DDRC, TEMP
;ldi TEMP, 0b000000000    ;1 Ausgänge, 0 Eingänge
;out DDRD, TEMP
;ldi TEMP, 0b000000000    ;1 Ausgänge, 0 Eingänge
;out DDRE, TEMP



;#########################
;Interrupt Vector - GICR
;#########################


ldi    TEMP,0b00000001
out    GICR,TEMP

ldi    TEMP,0b00000000

out    GICR,TEMP

;#########################
;SFIOR            Datenblatt S. 55ff
;#########################


ldi    TEMP,0b00000000

out    SFIOR,TEMP

;#########################
;External Interrupts - MCUCR - MCUCSR -GICR  Datenblatt S. 66ff
;#########################


ldi    TEMP,0b00000000    ;Interrupt Sense Control von INT0

andi    TEMP,0b00001111
in    R17,MCUCR
or    TEMP,R17
out    MCUCR,TEMP

ldi    TEMP,0b00000000

out    MCUCSR,TEMP

ldi    TEMP,0b00000000

andi    TEMP,0b11100000
in    R17,GICR
or    TEMP,R17
out    GICR,TEMP

;#########################
;Timer/Counter0 - TCCR0
;#########################

ldi    TEMP,0b00000000

out    TCCR0,TEMP

ldi    TEMP,0x00       ;Output Compare Register
out    OCR0,TEMP

ldi    TEMP,0b00000000

out    TIMSK,TEMP


;##########################
;Timer/Counter1 - TCCR1A - TCCR1B    Datenblatt S. 87ff
;##########################


ldi    TEMP,0b00000000

;
out    TCCR1A,TEMP
ldi    TEMP,0b00000000


andi  TEMP,0b11011111
out    TCCR1B,TEMP

ldi    TEMP,0x00      ;|
out    OCR1AH,TEMP      ;|Output Compare Register A
                 ;|
ldi    TEMP,0x00      ;|
out    OCR1AL,TEMP      ;|

ldi    TEMP,0x00      ;|
out    OCR1BH,TEMP      ;|Output Compare Register B
                 ;|
ldi    TEMP,0x00      ;|
out    OCR1BL,TEMP      ;|

ldi    TEMP,0b00000000

andi    TEMP,0b00111100
in    R17,TIMSK
or    TEMP,R17
out    TIMSK,TEMP

;#######################
;STACKPOINTER
;#######################

ldi TEMP, HIGH(RAMEND)
out SPH, TEMP
ldi TEMP, LOW(RAMEND)
out SPL, TEMP



;Display init

;Power on



;#######################
;MAIN
;#######################
          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







;#######################
;Unterprogramme
;#######################

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 RS=0
           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
 ;
 ; Bei höherem Takt (>= 8 MHz) kann es notwendig sein,
 ; vor dem Enable High 1-2 Wartetakte (nop) einzufügen.
 ; Siehe dazu Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
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        ; 4Bit  2 Zeilen  5x8
           rcall lcd_command
           ldi temp1, 0b00001100        ; Display ein  Cursor aus  
kein Blinken
           rcall lcd_command
           ldi temp1, 0b00000100        ; inkrement / kein Scrollen
           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

 ; Sendet den Befehl: Cursor Home
lcd_home:
           ldi temp1, 0b00000010   ; Cursor Home
           rcall lcd_command
           rcall delay5ms
           ret

;#######################
;Interrupts
;#######################


    ;eint_0:

    ;reti


    ;eint_1:

    ;reti


    ;eint_2:

    ;reti


    unusedISR:

    reti


Wäre super wenn mir jemand helfen kann!

Danke

mcrluni

von Lukas we (Gast)


Lesenswert?

Ok dann hilft mir halt keiner!

gg

lg

von holger (Gast)


Lesenswert?

>Ok dann hilft mir halt keiner!

Naja, ASM mögen halt nicht so viele.

Wie hast du dein Display denn angeschlossen ?
Sag jetzt bitte nicht: "Genau wie im Tutorial"
Schau noch mal ganz genau nach. Keine Pindreher drin ?
Kurzschlüsse,offene Leitungen ausgeschlossen ?

von Michael U. (amiga)


Lesenswert?

Hallo,

schlecht kommentiert, wo ist das Display angeschlossen?
Zur Fehlersuche zu lang, der hanze Timerkram ist für das Display doch 
erstmal unnötig, also raus damit, wir lesen das hier schließlich 
freiwillig in unserer Freizeit und da ist ewiges Suchen, um Wichtiges 
von Unwichtigen zu trennen, eher nervend.

So nach dem Vorwort:

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

Ich kann nur vermuten, daß an PD4 RS vom Display liegt,

ein
 .equ LCD_RS = PD4
und dann
 sbr temp1, 1<<LCD_RS
würde es merklich lesbarer machen.

Wenn ich richtig vermute:
Bei der Ausgabe des unteren Nibble wird RS dann nicht gesetzt!

Weiter habe ich noch nicht geschaut.

Gruß aus Berlin
Michael

von Michael U. (amiga)


Lesenswert?

Hallo,

sorry, ist natürlich so richtig, habe die Zeile einfach übersehen...
Daran kann es also nicht liegen.

init sieht eigentlich ok aus, RW hast Du fest auf GND gelegt?
Das Display hat wirklich einen HD44780 als Controller drauf, nicht einen 
(oft nur teilweise) kompatiblen?

Gruß aus Berlin
Michael

von Christoph L. (letti)


Lesenswert?

Hallo!

hab auch bei einem Display das gleiche Problem, nur hat es vorher schon 
längere Zeit funktioniert. Keine Ahnung warum es nicht mehr funzt... 
sollte jemand eine Lösung haben, bitte antworten!

mfg

von Michael U. (amiga)


Lesenswert?

Hallo,

gerade mal gegoogelt, wenn es das AV1624 von Ana Vision ist, sagt ein 
kurz-Datenblatt, daß ich gerade gefunden habe, Kontroller wäre ein 
KS0066 oder kompatibler?

Die Initialisierung des KS0066 stimmt nicht 100% mit dem HD44780 
überein.

Vielleicht hilft Dir das hier weiter:
Beitrag "KS0066U oder Ähnliche --- LCD Treiber"

Gruß aus Berlin
Michael

von Lukas W. (lukaswe)


Lesenswert?

Also erstmal danke
ok dann versuch ichs nochmal! gg

Code:
; 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        ; 4Bit  2 Zeilen  5x8
           rcall lcd_command
           ldi temp1, 0b00001100        ; Display ein  Cursor aus
                                        ;kein Blinken
           rcall lcd_command
           ldi temp1, 0b00000100        ; inkrement / kein Scrollen
           rcall lcd_command
           ret

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 RS=0
           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

R/W habe ich vergessen auf GND zu legen, jedoch ändert dies auch nichts.

Restliche belegung:

DB7 - pd3
db6 - pd2
db5 - pd1
db4 - pd0
rs  - pd4
e   - pd3

Danke für die vorherigen Einträge! Hoffe i könnt mir jetzt weiterhelfen!

von holger (Gast)


Lesenswert?

DB7 - pd3
e   - pd3

Vertippt oder falsch angeschlossen ?

von Lukas We (Gast)


Lesenswert?

Vertippt e-pd5

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.