mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DOG-M mit ATmega8 in Assembler ansteuern


Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Ich möchte ein 2-zeiliges DOG-M Display in Assembler ansteuern. Ich 
lasse es im 4 Bit Modus an Port D laufen. Leider geschiet auf dem 
Display garnichts. Das Datenblatt zum Display ist hier: 
http://www.lcd-module.de/deu/pdf/doma/dog-m.pdf und hier ist mein Code:
Wär nett wenn jemand wüsste was ich falsch gemacht hab!!

;+----------------------------------------------------------------------
;| Title           : Ansteuerung für einen DOGM-Textdisplay
;+----------------------------------------------------------------------
;| Funktion        : gibt ;-) auf dem Display aus
;| Schaltung       : DOGM 2x16 an portb im 4 bit Modus (wie LCD-Add-On)
;+----------------------------------------------------------------------
;| Prozessor       : ATmega8
;| Takt            : 3,6864 MHz
;| Sprache         : Assembler
;| Datum           : heute
;| Version         : 1.0
;| Autor           : Tobias Frintz
;+----------------------------------------------------------------------
.include  "AVR.H"
;----------------------------------------------------------------------- 
-
;Reset and Interrupt vector             ;VNr.  Beschreibung
  rjmp  main  ;1   POWER ON RESET
  reti    ;2   Int0-Interrupt
  reti    ;3   Int1-Interrupt
  reti    ;4   TC2 Compare Match
  reti    ;5   TC2 Overflow
  reti    ;6   TC1 Capture
  reti    ;7   TC1 Compare Match A
  reti    ;8   TC1 Compare Match B
  reti    ;9   TC1 Overflow
  reti    ;10  TC0 Overflow
  reti    ;11  SPI, STC Serial Transfer Complete
  reti    ;12  UART Rx Complete
  reti    ;13  UART Data Register Empty
  reti    ;14  UART Tx Complete
  reti    ;15  ADC Conversion Complete
  reti    ;16  EEPROM Ready
  reti    ;17  Analog Comparator
  reti    ;18  TWI (I²C) Serial Interface
  reti    ;19  Store Program Memory Ready
;----------------------------------------------------------------------- 
-
;Start, Power ON, Reset
main:  ldi  r16,lo8(RAMEND)
  out  SPL,r16
  ldi  r16,hi8(RAMEND)
  out  SPH,r16
  rcall  LCD_init
  rcall  LCD_clear
;----------------------------------------------------------------------- 
-
mainloop:  wdr
  rcall  wait5ms
  ldi  r16,'H'
  rcall  LCD_data
  ldi  r16,'y'
  rcall  LCD_data
  ldi  r16,'!'
  rcall  LCD_data
  rcall  LCD_home
  rjmp  mainloop
;----------------------------------------------------------------------- 
-
LCD_data:  ldi  r18,0b00000100
  rjmp  LCD_out
;----------------------------------------------------------------------- 
-
LCD_cmd:  ldi  r18,0b00000000
LCD_out:  mov  r17,r16
  swap  r17
  andi  r16,0b11110000
  or  r16,r18
  andi  r17,0b11110000
  or  r17,r18
  out  PORTD,r16
  rcall  LCD_enable
  rcall  wait5ms
  ret
;----------------------------------------------------------------------- 
-
LCD_enable:  sbi  PORTD,3  ;Enable high
  nop    ;kurtz warten
  nop
  nop
  cbi  PORTD,3  ;Enable low
  ret
;----------------------------------------------------------------------- 
-
LCD_clear:  ldi  r16,0b00000001  ;Display löschen
  rcall  LCD_cmd
  rcall  wait5ms
  ret
;----------------------------------------------------------------------- 
-
LCD_home:  ldi  r16,0b00000010
  rcall  LCD_cmd
  rcall  wait5ms
  ret
;----------------------------------------------------------------------- 
-
LCD_off:  ldi  r16,0b00001000
  rcall  LCD_cmd
  rcall  wait5ms
  ret
;----------------------------------------------------------------------- 
-
LCD_on:  ldi  r16,0b00001110
  rcall  wait5ms
  ret
;----------------------------------------------------------------------- 
-
LCD_line1:  ldi  r16,0b10000000  ;DRAM auf 0x00
  rcall  LCD_cmd
  rcall  wait5ms
  ret
;----------------------------------------------------------------------- 
-
LCD_line2:  ldi  r16,0b11000000  ;DRAM auf 0x40
  rcall  LCD_cmd
  rcall  wait5ms
  ret
;----------------------------------------------------------------------- 
-
wait5ms:  push  r24  ;r24 retten
  push  r25  ;r25 retten
  ldi  r25,50  ;für 1ms = 10
loop1:  ldi  r24,123
loop2:  dec  r24
  brne  loop2  ;Solange nicht NULL
  dec  r25  ;Zähler 2 -1
  brne  loop1  ;Solange nicht NULL
  dec  r16  ;Zähler1 -1
  brne  loop1  ;Solange nicht NULL
  pop  r25  ;r25 wiederherstellen
  pop  r24  ;r24 wiederherstellen
  ret    ;Rücksprung
;----------------------------------------------------------------------- 
-

LCD_init:  sbi  DDRD,1
  sbi  DDRD,2
  sbi  DDRD,3
  sbi  DDRD,4
  sbi  DDRD,5
  sbi  DDRD,6
  sbi  DDRD,7
  cbi  PORTD,2
  ; warten bis Powerup
  ldi  r18,10
powerup:  rcall  wait5ms
  dec  r18
  brne  powerup  ;min. 30 millisec
  ;sende init 1
  ldi  r16,0b00100000
  out  PORTD,r16
  rcall  LCD_enable
  rcall  wait5ms  ;Zeit zum umschalten lassen
  ldi  r16,0b00101001  ;Funktion Set
  rcall  LCD_cmd
  ldi  r16,0b00011100  ;Bias Set
  rcall  LCD_cmd
  ldi  r16,0b01010010  ;Power Control
  rcall  LCD_cmd
  ldi  r16,0b01101001  ;Follower Control
  rcall  LCD_cmd
  ldi  r16,0b01110100  ;Contrast Set
  rcall  LCD_cmd
  ldi  r16,0b00001111  ;Display on
  rcall  LCD_cmd
  ldi  r16,0b00000001  ;Clear Display
  rcall  LCD_cmd
  ldi  r16,0b00000110  ;Entry Mode Set
  rcall  LCD_cmd
  ret
;----------------------------------------------------------------------- 
-

Autor: Uwe Nagel (ulegan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein lcd_cmd solltest du nochmal überdenken. Irgendwie veroderst du da 
die oberen mit den unteren 4 Bit und gibst sie gemeinsam aus. Du 
müsstest im 4-Bit Modus die beiden Teile nacheinander ausgeben, jewils 
mit einem eigenen Enable-Impuls. Zuerst die obere, dann die untere 
Hälfte.
Ungefähr so:
LCD_data:  ldi  r18,0b00000100
  rjmp  LCD_out
;------------------------------------------------------------------------
LCD_cmd:  ldi  r18,0b00000000
LCD_out:  mov  r17,r16
  swap  r17
  andi  r16,0b11110000
  or  r16,r18
  out  PORTD,r16
  rcall  LCD_enable

  andi  r17,0b11110000
  or  r17,r18
  out  PORTD,r16
  rcall  LCD_enable
  rcall  wait5ms
  ret

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Danke für die Antwort. hast natürlich recht gehabt (war ein 
abschreibfehler) Das Problem ist nur der Display geht immer noch nicht. 
Ich glaube das in der lcd-init, powerup noch ein Fehler ist.

Tobi

PS: Ich habe die Displaybeleuchtung einmal vor lcd_init angeschalten (im 
main) und einmal dannach. Nur davor gehen die LEDs an, des heißt dass 
programm hängt sich in der init, powerup auf oder? !?

Autor: Uwe Nagel (ulegan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In wait5ms hat sich ein r16 eingeschlichen, das brauchts nicht. Ich habs 
nicht ausgerechnet, aber diese Routine dürfte mit r16 unerwartet lange 
dauern...
Eigentlich ist das auch die einzige Stelle, wo sich das Programm 
aufhängen kann. Sonst gibts ja keine Schleifen.
wait5ms:  push  r24  ;r24 retten
  push  r25  ;r25 retten
  ldi  r25,50  ;für 1ms = 10
loop1:  ldi  r24,123

loop2:  dec  r24
  brne  loop2  ;Solange nicht NULL   etwa (50*(123*3+4))/3686400s =5ms

  dec  r25  ;Zähler 2 -1
  brne  loop1  ;Solange nicht NULL
;  dec  r16  ;Zähler1 -1
;  brne  loop1  ;Solange nicht NULL
  pop  r25  ;r25 wiederherstellen
  pop  r24  ;r24 wiederherstellen
  ret    ;Rücksprung

Dann fehlt laut Datenblatt hier was:
  ldi  r16,0b01110100  ;Contrast Set
  rcall  LCD_cmd
;<--
  ldi  r16,0b00111000  ;Zurück zur Instruction table 0
  rcall  LCD_cmd
;-->
  ldi  r16,0b00001111  ;Display on
  rcall  LCD_cmd

Ich hab mich auch verschrieben, beim zweiten out muss es natürlich r17 
heissen.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich hab mich auch verschrieben, beim zweiten out muss es natürlich r17
>heissen.
hm. des versteh ich jetzt nicht
1. wo ist das zweite out?!?
2. und warum r17 ?!? das Register wird doch nur bei lcd_out benutzt

Autor: Visitor (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Tobi,

ich habe mich für die Initialisierung an dem Datenblattt des 
ST7036-Controllers orientiert (Bsp. S 42)

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>ldi  r16,0b00111000  ;Zurück zur Instruction table 0

Man tut ja Funktionsset 2 mal Senden:

-am Anfang zur einstellung von 4/8Bit, Table, Dotmatrix, Lines usw...
-Was ich nicht versteh beim zweitenmal sendet man es ja nur um zum Table 
1 zu kommen. Muss man dann die anderen vorhergesendeten Einstellungen 
nochmalsenden oder nicht?!?

So?      0b00101000
Oder so? 0b00100000

Autor: Uwe Nagel (ulegan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>2. und warum r17 ?!? das Register wird doch nur bei lcd_out benutzt

Ich meinte dieses hier:
LCD_data:  ldi  r18,0b00000100
  rjmp  LCD_out
;------------------------------------------------------------------------
LCD_cmd:  ldi  r18,0b00000000
LCD_out:  mov  r17,r16
  swap  r17
  andi  r16,0b11110000
  or  r16,r18
  out  PORTD,r16
  rcall  LCD_enable

  andi  r17,0b11110000
  or  r17,r18
  out  PORTD,r17    ; hier r17 nicht r16
  rcall  LCD_enable
  rcall  wait5ms
  ret

>ldi  r16,0b00111000  ;Zurück zur Instruction table 0

Das muss wohl nicht unbedingt sein.

Problematisch ist das Umschalten vom 8- in den 4-Bit Modus.
In http://www.lcd-module.de/eng/pdf/zubehoer/st7036.pdf
steht ein Beispiel für 8051

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.