Forum: Mikrocontroller und Digitale Elektronik Problem: Page-Wechsel bei LCD DG-12232 klappt nicht


von Eingehirner (Gast)


Lesenswert?

Hallo,

ich versuche gerade, eine "Clear Display"-Routine für das DG12232 von 
Pollin zu schreiben, einen sattsam bekannten, nicht ganz einfachen 
Vertreter der LCDs... eigentlich klappt auch alles ganz gut:
- beide Displayhälften lassen sich ein- und ausschalten
- ich kann eine Page problemlos hin und her beschreiben und löschen
- ich kann EINE Page auswählen (beliebig 0-3) und dort was machen

Das Problem tritt auf, wenn ich versuche, ALLE Pages hintereinander über 
eine Schleife anzusprechen und jeweils zu löschen (PORTC0-4: 
Steuerbefehle, PORTA0-7: Daten):
1
; Definitionen:
2
     ; Steuer-Pins:
3
     ; PC0: A0 (0: Command, 1: Data)
4
     ; PC1: CS2 (0: right display active)
5
     ; PC2: CS1 (0: left display active)
6
     ; PC3: /RD (0: read display data/status)
7
     ; PC4: /WR (0: write display data/command)
8
.equ A0=0
9
.equ CS2=1
10
.equ CS1=2
11
.equ READ=3
12
.equ WRITE=4
13
.equ LCD_COMMAND_PORTC = (0<<A0 | 1<<CS1 | 1<<CS2 | 1<<READ | 0<<WRITE)
14
.equ LCD_DATA_PORTC = (1<<A0 | 1<<CS1 | 1<<CS2 | 1<<READ | 0<<WRITE)
15
16
; Befehle aus Datenblatt
17
     ; PA0..7: DB7..0, lcd_data byte for writing/lcd_command
18
.equ LCD_ON_PORTA=             0b10101111
19
.equ LCD_OFF_PORTA=            0b10101110
20
.equ LCD_STARTLINE_PORTA=      0b11000000 ; use with "OR line#" (0..31)
21
.equ LCD_SETPAGE_PORTA=        0b10111000 ; use with "OR page#" (0..3)
22
.equ LCD_SETCOLUMN_PORTA=      0b00000000 ; use with "OR column#" (0..79)
23
.equ LCD_SELECTADC_PORTA=      0b10100000 ; use with "OR ccw_output" (0/1)
24
.equ LCD_READMODIFYWRITE_PORTA=0b11100000 ; for updating small parts of LCD
25
.equ LCD_END_PORTA=            0b11101110 ; end the read-modify-write mode
26
.equ LCD_RESET_PORTA=          0b11100010 ; reset display
27
28
[...]
29
  ; Display an
30
  ldi lcd_command, LCD_COMMAND_PORTC
31
  out PORTC, lcd_command ; LCD ist im "command"-Modus...
32
  ldi lcd_data, LCD_ON_PORTA
33
  out PORTA, lcd_data ; ...und bekommt das Kommando "an"
34
  cbi PORTC, CS1
35
  sbi PORTC, CS1
36
  cbi PORTC, CS2
37
  sbi PORTC, CS2 ; jetzt sind beide Displayhälften an
38
39
  ; Reset
40
  ldi lcd_command, LCD_RESET_PORTA
41
  out PORTA, lcd_command
42
  cbi PORTC, CS1
43
  sbi PORTC, CS1
44
45
; clear display
46
  rcall clear_display_LCD
47
48
;------------------------
49
clear_display_LCD:
50
  push lcd_command
51
  push lcd_page
52
53
  ldi lcd_command, LCD_STARTLINE_PORTA
54
  ori lcd_command, 0 ; start line  is 0
55
  rcall send_lcd_command_to_both_LCD ; diese Routine ist getestet und funktioniert
56
        ldi lcd_command, LCD_SETPAGE_PORTA
57
  ori lcd_command, 0 ; go to page 0 (a page is one set of eight lines)
58
  rcall send_lcd_command_to_both_LCD
59
  ldi lcd_command, LCD_SETCOLUMN_PORTA
60
  ori lcd_command, 0 ; go to column 0 (now we should be at the top left pixel/byte)
61
  rcall send_lcd_command_to_both_LCD
62
63
  ldi lcd_page, 0
64
  rcall clear_lcd_display_page
65
  ldi lcd_page, 1
66
  rcall clear_lcd_display_page
67
  ldi lcd_page, 2
68
  rcall clear_lcd_display_page
69
  ldi lcd_page, 3
70
  rcall clear_lcd_display_page
71
72
  pop lcd_page
73
  pop lcd_command
74
;-------------------------
75
clear_lcd_display_page:
76
    ; clear display page
77
    push lcd_command
78
    push lcd_data
79
    ldi lcd_command, LCD_SETPAGE_PORTA
80
    or lcd_command, lcd_page
81
    rcall send_lcd_command_to_both_LCD_special
82
    push counter
83
    ldi counter, 0
84
clear_next_byte:
85
    ldi lcd_data, 0x00
86
    rcall send_lcd_data_to_both_LCD
87
    inc counter
88
    cpi counter, 61
89
    brne clear_next_byte
90
    pop counter
91
    pop lcd_data
92
    pop lcd_command
93
    ret

Was passiert, ist, daß EINE Page gelöscht wird und danach nichts mehr 
geschieht. Ich hab das Programm im Simulator getestet, alles wunderbar, 
beide Schleifen laufen so durch wie gedacht. Ich hab gestern drei 
Stunden an diesem Problem gesessen und vermute ein dickes Brett vorm 
Kopf... sieht jemand den Fehler?

Dasselbe passiert auch, wenn ich folgende Routine verwende (hier ohne 
die push/pop-Teile, die sind eigentlich nicht zwingend notwendig):
1
clear_display:
2
  ; Initialisierung: Start bei Page 0 (überflüssig, aber gründlich)
3
        ldi lcd_command, LCD_SETPAGE_PORTA
4
  ori lcd_command, 0 ; Page auf Start setzen
5
  out PORTA, lcd_command
6
  cbi PORTC, CS1
7
  sbi PORTC, CS1
8
9
        ; Schleife über alle Pages
10
  ldi tmp2, 0 ; Page counter, Schleife loop_tmp2 von 0 bis 3
11
12
loop_tmp2:
13
  rcall wait1s ; damit ich sehen kann, was auf dem Display passiert
14
  ; Kommando
15
  ldi lcd_command, 0<<A0 | 1<<CS1 | 1<<CS2 | 1<<READ | 0<<WRITE
16
  out PORTC, lcd_command ; jetzt ist das LCD im "Command"-Modus
17
  ldi lcd_data, LCD_SETPAGE_PORTA
18
  mov tmp3, tmp2 ; tmp2 sichern (nur zur Sicherheit, push/pop geht auch)
19
  or lcd_data, tmp3 ; Befehl "springe zu Page tmp2" erzeugen...
20
  out PORTA, lcd_data ; ...und ausgeben
21
  cbi PORTC, CS1
22
  sbi PORTC, CS1
23
24
  ldi tmp1, 0 ; Column counter, Schleife loop_tmp1 von 0 bis 60
25
26
  ; Schreiben
27
  ldi lcd_command, 1<<A0 | 1<<CS1 | 1<<CS2 | 1<<READ | 0<<WRITE
28
  out PORTC, lcd_command ; das LCD ist im "data"-Modus
29
  ldi lcd_data, 0x00 ; aktuelles Byte löschen
30
  out PORTA, lcd_data
31
loop_tmp1:
32
  cbi PORTC, CS1 ; Daten (=Löschen) für linkes Display aktivieren
33
  sbi PORTC, CS1 ; linkes Display wieder auf Warten
34
35
  rcall wait100ms
36
37
  inc tmp1 ; Column inkrementieren
38
  cpi tmp1,61 ; sind wir fertig mit tmp1?
39
  brne loop_tmp1
40
; Ende loop_tmp1
41
42
  inc tmp2 ; Page inkrementieren
43
  cpi tmp2, 3 ; sind wir fertig mit tmp2?
44
  brne loop_tmp2
45
; Ende loop_tmp2
46
  ret

von Eingehirner (Gast)


Lesenswert?

OK, gelöst... man sollte dran denken, daß nach einem Page-Wechsel im 
Display der Column-Counter immer noch auf 61 steht... und ihn 
entsprechend resetten. Jetzt geht alles freu

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.