Forum: Mikrocontroller und Digitale Elektronik Powertip PG12864A - Problem mit Chipselect


von Christian (Gast)


Lesenswert?

Hallo,

ich habe ein Powertip PG12864A Display mit 128x64 Pixeln an mein Pollin 
Evaluationsboard angeschlossen. Das Display wird über einen ATmega 8 
angesteuert.
Mein Problem ist nun, dass ich auf der linken Displayhälfte(CS1 = high) 
normal schreiben kann, wenn ich jedoch auf der rechten Displayhälfte 
schreiben will(CS2 = high), wird ebenfalls auf der linken Seite 
geschrieben, allerdings nicht genau die selben Pixelmuster sondern 
irgendwas komisches. Als Test hab ich z.b. ein Byte 10101010 übertragen, 
welches auf der rechten Hälfte so angezeigt wird, auf der linken jedoch 
00111111.
Wenn ich aber beide Chips anspreche, also CS1 und CS2 high, 
funktionieren beide Hälften wie gewollt.

Im Programm habe ich schon CS1 und CS2 vertauscht, daran kann es 
normalerweise nicht liegen, und auch irgendwelche Zusatzfunktionen an 
den Ports C und D, welche ich abschalten müsste, habe ich nicht 
gefunden.

Hier mein Code, am Anfang stehen auch direkt die Pinzuordnungen zum 
Display.
1
.include "m8def.inc"
2
3
.def temp = r16
4
.def param = r17
5
.def counter = r18
6
.def counter2 = r19
7
.def addreg = r20
8
9
.equ LCD_DP = PORTD    ;LCD Data Port
10
.equ LCD_DPD = DDRD    ;LCD Data Port Direction
11
12
.equ LCD_CP = PORTC    ;LCD Control Port
13
.equ LCD_CPD = DDRC    ;LCD Control Port Direction
14
15
.equ LCD_RS = PORTC0  ;LCD Register Select Pin
16
.equ LCD_RW = PORTC2  ;LCD Read/Write Pin
17
.equ LCD_EN = PORTC1  ;LCD Enable Pin
18
.equ LCD_CS1 = PORTC3  ;LCD Chip Select 1 Pin
19
.equ LCD_CS2 = PORTC4  ;LCD Chip Select 2 Pin
20
.equ LCD_RE = PORTC5  ;LCD Reset Pin
21
22
23
24
.org 0x000
25
  rjmp reset
26
27
28
29
reset:
30
31
    ldi temp, HIGH(RAMEND)
32
    out SPH, temp
33
    ldi temp, LOW(RAMEND)
34
    out SPL, temp
35
36
    ldi temp, 0xFF
37
    out LCD_DPD, temp    ;LCD Data Port als Ausgang setzen
38
39
    ldi temp, 0x00
40
    out LCD_DP, temp
41
42
    ldi temp, 0xFF
43
    out LCD_CPD, temp    ;LCD Control Port als Ausgang setzen
44
45
    ldi addreg, 1
46
47
    ldi temp, (1<<LCD_RE)
48
    out LCD_DP, temp
49
50
    ldi param, 0xFF      ;0x10 = 460 µs*4 / 0xFF = 34ms*4
51
    rcall wait_ms
52
53
    rcall LCD_clear
54
    rcall LCD_init
55
56
    ldi counter, 0
57
    
58
59
60
loop:
61
    ldi temp, 0b01010101
62
    out LCD_DP, temp
63
    rcall LCD_data_both
64
    add counter, addreg
65
    cpi counter, 65
66
    brsh nop_loop
67
68
    rjmp loop
69
70
nop_loop:
71
    rjmp nop_loop
72
73
74
wait_ms:
75
    push temp
76
    mov temp, param
77
    push param
78
    cpi temp, 0
79
    breq wait_ms_end
80
81
    subi temp, 1
82
    mov param, temp
83
    rcall wait_ms
84
85
    wait_ms_loop:
86
    subi temp, 1
87
    cpi temp, 0
88
    brne wait_ms_loop
89
90
    wait_ms_end:
91
    pop param
92
    pop temp
93
    ret
94
95
LCD_init:
96
    push temp
97
98
    ldi temp, 0b00111111
99
    out LCD_DP, temp
100
    rcall LCD_command
101
102
    ldi param, 0
103
    rcall LCD_set_x
104
105
    ldi param, 2
106
    rcall LCD_set_page
107
108
    ldi param, 0
109
    rcall LCD_set_start
110
111
    pop temp
112
    ret
113
114
LCD_set_x:
115
    push temp
116
    mov temp, param
117
118
    ori temp, 0b01000000
119
    out LCD_DP, temp
120
    rcall LCD_command
121
122
    pop temp
123
    ret
124
125
LCD_set_page:
126
    push temp
127
    mov temp, param
128
129
    ori temp, 0b10111000
130
    out LCD_DP, temp
131
    rcall LCD_command
132
133
    pop temp
134
    ret
135
136
LCD_set_start:
137
    push temp
138
    mov temp, param
139
140
    ori temp, 0b11000000
141
    out LCD_DP, temp
142
    rcall LCD_command
143
144
    pop temp
145
    ret
146
147
LCD_clear:
148
    push temp
149
    push counter
150
    push counter2
151
152
    ldi counter, 0
153
    ldi counter2, 0
154
    ldi param, 0
155
    rcall LCD_set_x
156
    rcall LCD_set_page
157
    rcall LCD_set_start
158
159
    LCD_clear_loop:
160
      add counter, addreg
161
      ldi temp, 0b11111111
162
      out LCD_DP, temp
163
      rcall LCD_data_both
164
      cpi counter, 64
165
      brlo LCD_clear_loop
166
    
167
    add counter2, addreg
168
    mov param, counter2
169
    rcall LCD_set_page
170
    ldi counter, 0
171
    cpi counter2, 8
172
    brlo LCD_clear_loop
173
174
    pop counter2
175
    pop counter
176
    pop temp
177
    ret
178
179
LCD_command:
180
    push temp
181
    push param
182
183
    ldi temp, (1<<LCD_RE) | (1<<LCD_EN) | (1<<LCD_CS1) | (1<<LCD_CS2)
184
    out LCD_CP, temp
185
    ldi param, 0x05
186
    rcall wait_ms
187
    ldi temp, (1<<LCD_RE)
188
    out LCD_CP, temp
189
190
    pop param
191
    pop temp
192
    ret
193
194
LCD_data_one:
195
    push param    
196
197
    ldi param, (1<<LCD_CS1)
198
    rcall LCD_data
199
200
    pop param
201
    ret
202
203
LCD_data_two:
204
    push param    
205
206
    ldi param, (1<<LCD_CS2)
207
    rcall LCD_data
208
209
    pop param
210
    ret
211
212
LCD_data_both:
213
    push param    
214
215
    ldi param, (1<<LCD_CS1) | (1<<LCD_CS2)
216
    rcall LCD_data
217
218
    pop param
219
    ret
220
221
LCD_data:
222
    push temp
223
224
    mov temp, param
225
    ori temp, (1<<LCD_RE) | (1<<LCD_EN) | (1<<LCD_RS)
226
    out LCD_CP, temp
227
    push param
228
    ldi param, 0x05
229
    rcall wait_ms
230
    ldi temp, (1<<LCD_RE)
231
    out LCD_CP, temp
232
233
    pop param
234
    pop temp
235
    ret

von Christian (Gast)


Lesenswert?

Keiner eine Lösung? Oder irritiert der Code? Der Code ist glaube ich 
garnicht so wichtig, daran dürfte es eigentlich nicht liegen.

von Christian (Gast)


Lesenswert?

Ok ich habe das Problem nun ein wenig eingegrenzt:

Folgenden Code habe ich in der Schleife:
1
lpm temp, Z+
2
    
3
    ;ldi param, 3
4
    ;rcall LCD_set_page
5
    mov param, counter
6
    rcall LCD_set_x
7
    out LCD_DP, temp
8
    rcall LCD_data_two
9
10
11
    
12
    add counter, addreg
13
    cpi counter, 54
14
    brsh nop_loop

Dies funktioniert nicht, auf der rechten Seite werden die gewünschten 
Daten geschrieben (Buchstaben, tut aber nichts zur Sache) und links(also 
linke Hälfte) werden komische Zeichen ausgegeben. Dabei ist mir 
aufgefallen, dass jeweils der Befehl, der vorher durch den Aufruf "rcall 
LCD_set_x" übertragen wurde, angezeigt wird, also als ob man das falsche 
Register gewählt hat. Dummerweise werden die Register in der 
Befehlsroutine nichtmal angerührt, und ich bin mir ziemlich sicher dass 
das Register korrekt ist.
Allerdings werden bei einem Befehl immer beide Chips angesprochen, 
während die Schreiboperation danach nur den zweiten anspricht. Testweise 
habe ich beim Befehl auch mal nur den zweiten Chip angesprochen, dann 
wird es korrekt angezeigt. Allerdings sollte es auch so gehen, dass 
beide Chips den Befehl mitkriegen.

Hauptproblem ist im Moment also, dass auf irgendeine komische Art und 
Weise die Befehlsdaten im falschen Register landen...

von spess53 (Gast)


Lesenswert?

Hi

Vielleicht solltest du mal das Timing überarbeiten. RS,RW und CS sollten 
gesetzt werden, bevor E auf H  und nachdem E wieder auf L gesetzt wird.

MfG Spess

von Christian (Gast)


Lesenswert?

Naja habs jetzt eh gelöst, indem ich einfach ein globales Chipselect 
Register gemacht habe, dass dann immer in den aufrufen für Befehl bzw. 
Daten benutzt wird. Das muss man dann halt vor dem jeweiligen Aufruf 
setzen, aber dadurch spart man sich quasi die ganzen Prozeduren für Chip 
1 und Chip 2 und hat eine allgemeine.

Das Timing werde ich trotzdem überarbeiten, ist sicherer...

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.