Powertip PG12864A - Problem mit Chipselect

Gast #1783320
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
Gast #1785404
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...
Gast #1785477
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...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren