Forum: Mikrocontroller und Digitale Elektronik LCD Hängt immer Datenmüll an


von Sören T. (stimmy)


Lesenswert?

Hallo,
ich hatte mir vor ein paar Wochen 2 von diesen 8x2 Displays(C0802-04) 
von Pollin gekauft und habe sie gestern einmal angeschlossen.

Wenn das Display initialisiert und gecleart ist sind beide total leer.
Sobald ich ein Zeichen ausgebe hängt er wieder diese Zeichen an.

Bild: Ausgabe <SPACE>1 war gedacht und was bei raus gekommen ist, ist ja 
zu sehen.

Es war mir erst auf den beiden Kleinen von Pollin aufgefallen und 
deswegen habe ich mein 20x4 Display parallel dazu angeschlossen.

Hat jemand eine Idee was das soll?

MfG

von Floh (Gast)


Lesenswert?

Sören Timm schrieb:
> ist ja zu sehen.
äh nein.

von Hc Z. (mizch)


Lesenswert?

Weder Code noch Bild.  Und die Kristallkugeln sind in diesen Tagen voll 
von Schneegestöber.

von Sören T. (stimmy)


Angehängte Dateien:

Lesenswert?

Das BIld

von Sören T. (stimmy)


Lesenswert?

Ich habe die Standard LCD-Routines.asm von dieser Seite genommen und an 
den AVR angepasst.

von Hc Z. (mizch)


Lesenswert?

Die Routinen funktionieren ja wohl sonst, die LCDs auch.  Bleibt nicht 
viel über.

Kein Code.  Keine Kekse.

von Thomas H. (flaretom)


Lesenswert?

Ich weiß jetzt nicht konkret, wie bei der LCD-Routines.asm die String 
Terminierung aussehen muss.
Es sieht aber so aus, als ob du die \0 am Ende vergessen oder die 
Stringlänge falsch übergeben hast.
Stell doch mal den Aufruf der LCD Routine rein.

von Spess53 (Gast)


Lesenswert?

Hi

>Ich habe die Standard LCD-Routines.asm von dieser Seite genommen und an
>den AVR angepasst.

Da scheint etwas dabei schief gegangen zu sein. Also zeig mal deinen 
aktuellen Code.

MfG Spess

von Sören T. (stimmy)


Lesenswert?

1
.include "m8def.inc"
2
3
 
4
5
.def temp1 = r16
6
7
8
9
 
10
11
Stack: 
12
13
           ldi temp1, LOW(RAMEND)
14
15
           out SPL, temp1
16
17
       ldi temp1, HIGH(RAMEND)
18
19
           out SPH, temp1
20
21
22
23
Display1: 
24
25
           rcall lcd_init
26
27
           rcall lcd_clear
28
29
 
30
31
           ldi ZL, LOW(text*2)
32
33
           ldi ZH, HIGH(text*2)
34
35
 
36
37
           rcall lcd_flash_string
38
39
40
41
loop:
42
43
           rjmp loop
44
45
 
46
47
text:
48
49
          .db " 1"
50
51
52
53
54
55
 
56
57
.include "lcd-routines.asm"
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
3
;;                 LCD-Routinen                ;;
4
5
;;                 ============                ;;
6
7
;;              (c)andreas-s@web.de            ;;
8
9
;;                                             ;;
10
11
;; 4bit-Interface                              ;;
12
13
;; DB4-DB7:       PD0-PD3                      ;;
14
15
;; RS:            PD4                          ;;
16
17
;; E:             PD5                          ;;
18
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20
21
 
22
23
.def temp2 = r22
24
25
.def temp3 = r23
26
27
 
28
29
.equ LCD_PORT = PORTC
30
31
.equ LCD_DDR  = DDRC
32
33
.equ PIN_RS   = 4
34
35
.equ PIN_E    = 5
36
37
38
39
.ifndef XTAL
40
41
.equ XTAL = 1000000
42
43
.endif
44
45
46
47
 ;sendet ein Datenbyte an das LCD
48
49
lcd_data:
50
51
           push  temp2
52
53
           push  temp3
54
55
           mov   temp2, temp1            ; "Sicherungskopie" für
56
57
                                         ; die Übertragung des 2.Nibbles
58
59
           swap  temp1                   ; Vertauschen
60
61
           andi  temp1, 0b00001111       ; oberes Nibble auf Null setzen
62
63
           sbr   temp1, 1<<PIN_RS        ; entspricht 0b00010000
64
65
           in    temp3, LCD_PORT
66
67
           andi  temp3, 0x80
68
69
           or    temp1, temp3
70
71
           out   LCD_PORT, temp1         ; ausgeben
72
73
           rcall lcd_enable              ; Enable-Routine aufrufen
74
75
                                         ; 2. Nibble, kein swap da es schon
76
77
                                         ; an der richtigen stelle ist
78
79
           andi  temp2, 0b00001111       ; obere Hälfte auf Null setzen 
80
81
           sbr   temp2, 1<<PIN_RS        ; entspricht 0b00010000
82
83
           or    temp2, temp3
84
85
           out   LCD_PORT, temp2         ; ausgeben
86
87
           rcall lcd_enable              ; Enable-Routine aufrufen
88
89
           rcall delay50us               ; Delay-Routine aufrufen
90
91
92
93
           pop   temp3
94
95
           pop   temp2
96
97
           ret                           ; zurück zum Hauptprogramm
98
99
 
100
101
 ; sendet einen Befehl an das LCD
102
103
lcd_command:                            ; wie lcd_data, nur ohne RS zu setzen
104
105
           push  temp2
106
107
           push  temp3
108
109
110
111
           mov   temp2, temp1
112
113
           swap  temp1
114
115
           andi  temp1, 0b00001111
116
117
           in    temp3, LCD_PORT
118
119
           andi  temp3, 0x80
120
121
           or    temp1, temp3
122
123
           out   LCD_PORT, temp1
124
125
           rcall lcd_enable
126
127
           andi  temp2, 0b00001111
128
129
           or    temp2, temp3
130
131
           out   LCD_PORT, temp2
132
133
           rcall lcd_enable
134
135
           rcall delay50us
136
137
 
138
139
           pop   temp3
140
141
           pop   temp2
142
143
           ret
144
145
 
146
147
 ; erzeugt den Enable-Puls
148
149
lcd_enable:
150
151
           sbi LCD_PORT, PIN_E          ; Enable high
152
153
           nop                          ; 3 Taktzyklen warten
154
155
           nop
156
157
           nop
158
159
           cbi LCD_PORT, PIN_E          ; Enable wieder low
160
161
           ret                          ; Und wieder zurück                     
162
163
 
164
165
 ; Pause nach jeder Übertragung
166
167
delay50us:                              ; 50us Pause
168
169
           ldi  temp1, ( XTAL * 50 / 3 ) / 1000000
170
171
delay50us_:
172
173
           dec  temp1
174
175
           brne delay50us_
176
177
           ret                          ; wieder zurück
178
179
 
180
181
 ; Längere Pause für manche Befehle
182
183
delay5ms:                               ; 5ms Pause
184
185
           ldi  temp1, ( XTAL * 5 / 607 ) / 1000
186
187
WGLOOP0:   ldi  temp2, $C9
188
189
WGLOOP1:   dec  temp2
190
191
           brne WGLOOP1
192
193
           dec  temp1
194
195
           brne WGLOOP0
196
197
           ret                          ; wieder zurück
198
199
 
200
201
 ; Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
202
203
lcd_init:
204
205
           push  temp1
206
207
           in    temp1, LCD_DDR
208
209
           ori   temp1, (1<<PIN_E) | (1<<PIN_RS) | 0x0F
210
211
           out   LCD_DDR, temp1
212
213
214
215
           ldi   temp3,6
216
217
powerupwait:
218
219
           rcall delay5ms
220
221
           dec   temp3
222
223
           brne  powerupwait
224
225
           ldi   temp1,    0b00000011   ; muss 3mal hintereinander gesendet
226
227
           out   LCD_PORT, temp1        ; werden zur Initialisierung
228
229
           rcall lcd_enable             ; 1
230
231
           rcall delay5ms
232
233
           rcall lcd_enable             ; 2
234
235
           rcall delay5ms
236
237
           rcall lcd_enable             ; und 3!
238
239
           rcall delay5ms
240
241
           ldi   temp1,    0b00000010   ; 4bit-Modus einstellen
242
243
           out   LCD_PORT, temp1
244
245
           rcall lcd_enable
246
247
           rcall delay5ms
248
249
           ldi   temp1,    0b00101000   ; 4 Bot, 2 Zeilen
250
251
           rcall lcd_command
252
253
           ldi   temp1,    0b00001100   ; Display on, Cursor off
254
255
           rcall lcd_command
256
257
           ldi   temp1,    0b00000100   ; endlich fertig
258
259
           rcall lcd_command
260
261
262
263
           pop   temp1
264
265
           ret
266
267
 
268
269
 ; Sendet den Befehl zur Löschung des Displays
270
271
lcd_clear:
272
273
           push  temp1
274
275
           ldi   temp1,    0b00000001   ; Display löschen
276
277
           rcall lcd_command
278
279
           rcall delay5ms
280
281
           pop   temp1
282
283
           ret
284
285
286
287
 ; Cursor Home
288
289
lcd_home:
290
291
           push  temp1
292
293
           ldi   temp1,    0b00000010   ; Cursor Home
294
295
           rcall lcd_command
296
297
           rcall delay5ms
298
299
           pop   temp1
300
301
           ret
302
303
304
305
 ; Einen konstanten Text aus dem Flash Speicher
306
307
 ; ausgeben. Der Text wird mit einer 0 beendet
308
309
lcd_flash_string:
310
311
           push  temp1
312
313
314
315
lcd_flash_string_1:
316
317
           lpm   temp1, Z+
318
319
           cpi   temp1, 0
320
321
           breq  lcd_flash_string_2
322
323
           rcall  lcd_data
324
325
           rjmp  lcd_flash_string_1
326
327
328
329
lcd_flash_string_2:
330
331
           pop   temp1
332
333
           ret
334
335
336
337
 ; Eine Zahl aus dem Register temp1 dezimal ausgeben
338
339
lcd_number:
340
341
           push  temp1
342
343
           push  temp2
344
345
           push  temp3
346
347
348
349
           mov   temp2, temp1
350
351
                                  ; abzählen wieviele Hunderter
352
353
                                          ; in der Zahl enthalten sind
354
355
           ldi   temp1, '0'
356
357
lcd_number_1:
358
359
           subi  temp2, 100
360
361
           brcs  lcd_number_2
362
363
           inc   temp1
364
365
           rjmp  lcd_number_1
366
367
                                          ;
368
369
                                          ; die Hunderterstelle ausgeben
370
371
lcd_number_2:
372
373
           rcall lcd_data
374
375
           subi  temp2, -100              ; 100 wieder dazuzählen, da die
376
377
                                          ; vorherhgehende Schleife 100 zuviel
378
379
                                          ; abgezogen hat
380
381
382
383
                                          ; abzählen wieviele Zehner in
384
385
                                          ; der Zahl enthalten sind
386
387
           ldi   temp1, '0'
388
389
lcd_number_3:
390
391
           subi  temp2, 10
392
393
           brcs  lcd_number_4
394
395
           inc   temp1
396
397
           rjmp  lcd_number_3
398
399
400
401
                                          ; die Zehnerstelle ausgeben
402
403
lcd_number_4:
404
405
           rcall lcd_data
406
407
           subi  temp2, -10               ; 10 wieder dazuzählen, da die
408
409
                                          ; vorhergehende Schleife 10 zuviel
410
411
                                          ; abgezogen hat
412
413
414
415
                                          ; die übrig gebliebenen Einer
416
417
                                          ; noch ausgeben
418
419
           ldi   temp1, '0'
420
421
           add   temp1, temp2
422
423
           rcall lcd_data
424
425
426
427
           pop   temp3
428
429
           pop   temp2
430
431
           pop   temp1
432
433
           ret
434
435
436
437
; eine Zahl aus dem Register temp1 hexadezimal ausgeben
438
439
lcd_number_hex:
440
441
           push  temp1
442
443
444
445
           swap  temp1
446
447
           andi  temp1, $0F
448
449
           rcall lcd_number_hex_digit
450
451
452
453
           pop   temp1
454
455
           push  temp1
456
457
458
459
           andi  temp1, $0F
460
461
           rcall lcd_number_hex_digit
462
463
464
465
           pop   temp1
466
467
           ret
468
469
470
471
lcd_number_hex_digit:
472
473
           cpi   temp1, 10
474
475
           brlt  lcd_number_hex_digit_1
476
477
           subi  temp1, -( 'A' - '9' - 1 )
478
479
lcd_number_hex_digit_1:
480
481
           subi  temp1, -'0'
482
483
           rcall  lcd_data
484
485
           ret

von Thomas H. (flaretom)


Lesenswert?

Wie wäre es damit:
text:
          .db " 1"
          .db 0

von thisamplifierisloud (Gast)


Lesenswert?

Sind alle statischen Steuerleitungen ordentlich festgenagelt
und evtl. erforderliche Pullups-Widerstände bestückt ?

Hatte mal ein I2C-Display, das ein ähnliches Eigenleben hatte,
bis ich die \CS-Leitung auf GND genagelt habe.

Laut Datenblatt hätte man die auch offenlassen können...

von Spess53 (Gast)


Lesenswert?

Hi

>        .db " 1"

Und wo ist die Null

        .db " 1",0

MfG Spess

von Sören T. (stimmy)


Lesenswert?

Bringt diese ,0 den String zum erliegen?
Kann man einen Zeilenumbruch dadurch erreichen?

von Floh (Gast)


Lesenswert?

Sören Timm schrieb:
> Bringt diese ,0 den String zum erliegen?

0 ist das definierte Ende einer Zeichenkette.

> Kann man einen Zeilenumbruch dadurch erreichen?

nein.

von Thomas H. (flaretom)


Lesenswert?

Die Null beendet nur den String:

lcd_flash_string_1:
           lpm   temp1, Z+
           cpi   temp1, 0
           breq  lcd_flash_string_2  ; ende


Also kein Zeilenvorschub dadurch.

von Spess53 (Gast)


Lesenswert?

Hi

>Bringt diese ,0 den String zum erliegen?
1
lcd_flash_string_1:
2
           lpm   temp1, Z+
3
           cpi   temp1, 0
4
           ....

Beim Erreichen der '0' wird die Ausgabe beendet.

>Kann man einen Zeilenumbruch dadurch erreichen?

Nein.

MfG Spess

von Sören T. (stimmy)


Angehängte Dateien:

Lesenswert?

Jetzt gehts!

Danke!

von Wampus (Gast)


Lesenswert?

Hallo!

Was ist denn das für ein 20x4 Display? Die Zeichen sind wunderbar 
kontrastreich und deutlich lesbar. Das gefällt mir = will auch haben ;)

Gruß Wampus

von Sören T. (stimmy)


Lesenswert?

Das ist ein YM2004A.
Ich hatte es von einem Polen bei Ebay gekauft.
Musste mal unter dem Begriff "HD44780" bei Ebay suchen.

von Wampus (Gast)


Lesenswert?

Hallo und vielen Dank!

von Sören T. (stimmy)


Lesenswert?


von Falk B. (falk)


Lesenswert?

@  Sören Timm (stimmy)

>      DSCI1467.JPG
>      1.7 MB, 49 Downloads

>Jetzt gehts!

Ja, jetzt geht's mal wieder los. Hirn aus, Spass rein. Ohje!

Lies mal was über Bildformate! Und Netiquette, lange Quelltexte 
gehören in den Anhang!

MfG
Falk

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.