Forum: Mikrocontroller und Digitale Elektronik Displaytech 162C Init fehlgeschlagen


von Bernhard Drescher (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Mikrocontroller-Community,
da ich jetzt schon seit sehr langer Zeit am verzweifeln bin auf Grund 
meines nicht funktionierenden LCD, wende ich mich nun hier an euch, auch 
wenn ich weiß dass es bereits haufenweise Threads gibt. Jedoch brachte 
keine der Lösungsansätze Erfolg bei mir, Erstmal zur Beschreibung:

Ich nutze ein STK 500 mit ATMega8L und habe an PORTD mein LCD vom Typ 
Displaytech 162C, welches einen KS0070B Controller besitzt. An PORTB 
habe ich die LED-reihen, um Rückmeldungen über den Programmverlauf zu 
machen (erwies sich aber als sinnlos, Erklärung folgt). Poti als 
Kontrast, PD0-3 als DB4-7, RS auf PD4, E auf PD5, wie im Tutorial hier.

Nun das Problem:
Ich will das Display als 4 Bit ansteuern und habe das Datenblatt des 
Displays mit der lcd-routine von hier verglichen und sie scheint 
identisch. Trotzdem funktioniert die initialisierung nicht. Das einzige 
was je erschienen ist waren die Balken in der 1. Zeile. Egal welche 
Lösungsvorschläge es im Internet gab, nichts wollte funktionieren, auch 
Fleurys Library hat nicht funktioniert. Bin hier echt am verzweifeln.

Was mich zudem verwirrt ist:
1
rcall life          
2
rcall lcd_init     ; Display initialisieren
3
rcall life
4
rcall lcd_clear    ; Display löschen
5
 
6
...
7
8
delay1s:                               ; 1s Pause (bei 4 MHz)
9
  ldi r16, 200
10
  loop2: 
11
  rcall delay5ms
12
  dec r16
13
  brne loop2
14
   
15
  ret    
16
17
life:
18
push r16
19
20
  ldi r16,0x00
21
  out PORTB, r16
22
23
  rcall delay1s
24
25
  ldi r16,0xFF
26
  out PORTB, r16
27
28
  rcall delay1s
29
30
  pop r16
31
  ret

Hier scheinen irgendwelche Fehler abzulaufen, denn die LEDs gehen erst 
gar nicht aus, warum? Sie leuchten dauerhaft durch, obwohl ich ja zum 
schluss 0xFF auf PORTB ausgebe was sie ja eigentlich ausschalten sollte. 
(LED6 und LED7 leuchten auch nicht, keine Ahnung warum)

Mfg Bernhard

von kjh (Gast)


Lesenswert?

DDRB auf 0xff gesetzt? Sehe ich in deinem Code nicht. Die LEDs vom 
STK500 sind low active und ohne DDRB zu setzen ...

von Bernhard Drescher (Gast)


Lesenswert?

ganz am anfang der beigefügten Datei:
1
  ldi temp1, 0xFF    ; Port D = Ausgang
2
        out DDRD, temp1
3
4
  ldi temp1, 0xFF    ; Port B = Ausgang
5
  out DDRB, temp1

von kjh (Gast)


Lesenswert?

Das PB6 und PB7 dauerhaft leuchten könnte ein Oszillator Problem sein, 
wenn du auf dem STK500 testest. Welche Oszillator-Einstellungen für das 
STK 500 hast du gewählt?

Evtl. läuft das ganze viel zu schnell oder zu langsam.

von kjh (Gast)


Lesenswert?

Wollte nur nochmal darauf hinweisen: Du musst am STK500 einstellen, 
welcher Oszillator benutzt wird. Es reicht nicht, einfach ein Fusebit zu 
setzen!

von Bernhard Drescher (Gast)


Lesenswert?

Ich habe den Internen RC Oszillator auf 4 Mhz + 4ms gewählt, auch auf 1 
Mhz (standard Einstellung) läuft nichts.

von kjh (Gast)


Lesenswert?

Hallo Bernhard,

hast du die Jumper auf dem STK 500 richtig gesetzt?

von kjh (Gast)


Lesenswert?


von Bernhard Drescher (Gast)


Lesenswert?

Ist noch wie im Auslieferungszustand, d.h XTAL ist gesetzt und OSCSEL 
auf On-Board Software Clock Signal
Einen externen Quarz habe ich moment leider nicht hier, weil ich den 
Paketboten gestern verpasst habe.

von Bernhard Drescher (Gast)


Lesenswert?

Hat keiner eine Ahnung? Habe mir ein anderes LCD bestellt. Vlt bringt 
dass ja Abhilfe, koennte ich eigentlich auf dem Breadboard zwischen 
PD0-3 je eine LED mit Widerstand setzen um zu pruefen ob Signale 
durchkommen? Oder wuerde eine LED zu viel Strom ziehen? Tut mir leid 
falls die Frage einfach ist,  bin noch Neuling im Elektronikbereich.

von Karl H. (kbuchegg)


Lesenswert?

Bernhard Drescher schrieb:

> Hier scheinen irgendwelche Fehler abzulaufen, denn die LEDs gehen erst
> gar nicht aus, warum?

Du musst dir in Assembler angewöhnen, auf die Register zu achten

Wenn du hier
1
delay1s:                               ; 1s Pause (bei 4 MHz)
2
  ldi r16, 200
3
  loop2: 
4
  rcall delay5ms
5
  dec r16
6
  brne loop2
7
   
8
  ret

die delay5ms aufrufst, dann darf delay5ms das Register r16 nicht 
verändern! Denn ansonsten decrementierst du irgendwas, was du nicht mehr 
unter Kontrolle hast.
Daher die Frage: macht die delay5ms irgendwas mit dem r16?
1
 ; Längere Pause für manche Befehle
2
delay5ms:                               ; 5ms Pause (bei 4 MHz)
3
           ldi  temp1, $21
4
WGLOOP0:   ldi  temp2, $C9
5
WGLOOP1:   dec  temp2
6
           brne WGLOOP1
7
           dec  temp1
8
           brne WGLOOP0
9
           ret                          ; wieder zurück

Da werden die Register temp1 und temp2 verändert:
1
.def temp1 = r16
2
.def temp2 = r17
3
.def temp3 = r18

Daher: Ja! delay5ms verändert das Register r16!
Und zwar so, dass es 0 ist, wenn delay5ms wieder zurückkommt nach 
delay1s! WEnn aber hier
1
  rcall delay5ms
nach dem Aufruf in r16 eine 0 steht, und zwar IMMER, dann wird dir 
gleich danach
1
  dec r16
2
  brne loop2
mit Sicherheit niemals 0 rauskommen, sondern immer 255. D.h. der brne 
wird IMMER springen. Du hast also in deiner Wartefunktion eine 
Endlosschleife gebaut.


Und damit kommt dein Programm hier
1
  ldi temp1, LOW(RAMEND)      ; LOW-Byte der obersten RAM-Adresse
2
    out SPL, temp1
3
    ldi temp1, HIGH(RAMEND)     ; HIGH-Byte der obersten RAM-Adresse
4
    out SPH, temp1
5
6
  ldi temp1, 0xFF    ; Port D = Ausgang
7
    out DDRD, temp1
8
9
  ldi temp1, 0xFF    ; Port B = Ausgang
10
  out DDRB, temp1
11
  
12
       rcall life
13
           
14
           rcall lcd_init     ; Display initialisieren
gar nicht über den ersten Aufruf von 'life' drüber und damit nie zu 
lcd_init.


Wenn du Code veränderst oder erweiterst UND du andere Funktionen 
aufrufst, dann musst du immer darauf achten, was diese aufgerufenen 
FUnktionen mit den Registern machen!
Das ist nun mal das Los der Assembler-Programmierer, sich um solchen 
Kleinkram kümmern zu müssen und es ist einer der Gründe, warum Assembler 
programmieren generell als schwieriger gilt, eben weil man sich auch 
noch um zig kleine Details kümmern muss und man sich ganz schnell 
unbemerkt ein Eigentor schiesst.

von Bernhard Drescher (Gast)


Lesenswert?

Vielen Dank für die schnelle Antwort. Ja, da hab ich wohl einiges 
übersehen. Ich will aber lieber in Assembler programmieren, da ich von C 
und C++ aus gestartet habe und anstatt Software momentan 
Hardware-Programmierung testen will, um mich für ein Studiumsfach 
entscheiden zu können.
Blinklicht funktioniert jetzt nach push / pop bei delay5ms. Vielen Dank 
nochmal, jetzt muss nur noch die Init-Routine fehlerfrei ablaufen 
können...

von Karl H. (kbuchegg)


Lesenswert?

Hinweis:
LCD Timing ist nur insofern kritisch, als du nicht zu kurz werden 
darfst. Aber länger darfst du werden so viel du willst.

Wenn in der Init die 0x03 angelegt sind, kannst du auch 10 Sekunden 
warten ehe du dann mal den E Pin langsam mal auf 1 ziehst, eine halbe 
Stunde wartest und den Pin wieder auf 0 fallen lässt. Und in der Zeit 
kann man mal direkt am LCD nachmessen, was da eigentlich ankommt.

von Bernhard Drescher (Gast)


Lesenswert?

ok, habe jetzt LEDs mit je 1k Vorwiderstand an die Pins parallel 
gehängt, die Sigale kommen durch und auch in der richtigen Reihenfolge, 
zwischen jedem Signal warte ich 1 Sekunde. Trotzdem bleibt es bei den 
schwarzen Blöcken in der ersten Zeile...
Neuen Quellcode reiche ich gleich nach

von Bernhard Drescher (Gast)


Angehängte Dateien:

Lesenswert?

Hier der Quellcode

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.