Forum: Mikrocontroller und Digitale Elektronik LCD-Probleme am Atmega128


von Doc. Shorty (Gast)


Lesenswert?

Habe Probleme beim Ansteuern eines LCD-Displays und keine Lösung dafür
......

Folgende Gegebenheiten :
- Atmega128 auf Tinyboard (übrigens mein erster ;-) )
- 16 MHz Takt + 32 kHz Quarz
- 64*128 Grafik Display

Ich möchte auf dem Display ein paar Werte anzeigen und habe dazu im
EEPROM folgendes hinterlegt:
- Textpositionen auf dem Display
- Grafiken der einzelnen Zeichen und Ziffern
- Langtexte

Bisher habe ich von extern nur das Display (Portb für Steuerbefehle +
Porte für Daten) sowie drei Tasten (Portc 0-2) angeschlossen.
Die Ausgabe hat auch wunderbar funktioniert, bis ich zum erzeugen einer
Uhr den Timer0 in Betrieb genommen habe. Seit dem habe ich sporadisch
auftretende Displaystörungen.
D.h. es erscheinen plötzlich (mittlerweile nicht einmal mehr
unerwartet) Daten aus dem EEPROM auf dem Display die dort nicht
hingehören.
Nun habe ich schon die Steuerbefehle auf Porta gewechselt da an b wohl
auch noch Timerausgänge mit dranne sind, welche das ganze beeinflussen
können - jedoch ohne Erfolg.
Der Timer kommt alle 10 ms und vor und nach jeder Displayansteuerung
habe ich schon Verzögerungen eingebaut (ca.50 Takte).
Der Hersteller des Displays gibt im großen und ganzen ca. 10 ns für die
Kommunikation an.Also kann es wohl an der Geschwindigkeit auch nicht
liegen.
Die Daten auf dem Display gehen auch immer über eine ganze Zeile, dh.
irgendwie passiert da was kontrolliert....... nur leider nicht von mir
!

Hat irgendwer eine Idee ????

Währe sehr dankbar.

Shorty

von Tobi (Gast)


Lesenswert?

der code wäre hilfreich
erste vermutung: sicherst du in der timer isr deine register alle?

von A.K. (Gast)


Lesenswert?

Werden in einer Interrupt-Routine Pins gesteuert? Wenn ja, müssen alle
alle Read-Modify-Write Operationen auf diesen Ports gegen Interrupts
abgesichert werden. SBI/CBI sind von Haus aus wasserdicht, erzeugt der
Compiler aber
   in/load
   operate
   out/store
und es kommt ein Interrupt dazwischen der diesen Port bearbeitet, dann
hast Du Pech gehabt.

von Doc. Shorty (Gast)


Lesenswert?

Hallo,

Alle Register die ich in der Routine benutze werden gesichert ...

In der Routine werden keine I/O's gesteuert.

Ich habe zuerst den Zähler für meine Uhr im Speicher abgelegt und mir
vorgestellt, das wenn ich die Anzeige der Uhrzeit starte ich beim
Zugriff über die Register (X,Y,Z) mir irgendetwas durcheinander bringe
wenn der Interrupt einsetzt, aber auch nachdem ich in der Routine nur
noch mit r6-r9 arbeite ändert sich nix.

Habe ich evtl. bei der Initialisierung was falsch gemacht ?

Timer1Init:
  ldi  r16,0x02
  out  TCCR0,r16
  ldi  r16,215
  out  TCNT0,r16
  ldi  r16,0b00001000
  out  ASSR,r16
  ldi  r16,0x01
  out  TIMSK,r16
  ldi  r16,0b10001000
  out  sfior,r16
  sei
  ret

Habe mir dir Werte ausschließlich aus den ATMEL-Beschreibungen
zurechtgebastelt.

Die IRQ-Routine für den Timer habe ich auf 0040 Platziert (jmp
Timer1).

Timer1:
  push  r16
  push  r17
  mov    r16,Var1   ;Variable für zehntl-Sec. (r6)
  inc    r16
  mov    Var1,r16
  cpi    r16,100
  brlt  Timer1End
  ldi    r16,0
  mov    Var1,r16
        .......
        hier kommen dann noch Var2-4 für Sec,Min,Std.
        .......
Timer1End:
  ldi  r16,221
  out  TCNT0,r16
  pop  r17
  pop  r16
  reti

Die Einstellung des Interrupts kann eigentlich gar nicht richtig sein,
da ich keine genaue Uhrzeit bekomme ....

Aber, jeder Anfang ist schwer ;-)

von Andi (Gast)


Lesenswert?

Und wie siehts aus mit

 push r16
 in r16,SREG
 push r16
 push r17
 .....
 .....
 pop r17
 pop r16
 out SREG,r16
 pop r16

Du hast einfach vergessen, das Statusregister (WICHTIG) zu sichern.

Geht auch kürzer, wenn man sich für das Statusregister eines der
Register reserviert:

.def StReg=r3

 in StReg,SREG
 ...
 out SREG,StReg

Gruß
Andi

von Andi (Gast)


Lesenswert?

Ach ja, gerade mit einem Mega128 würde ich das NICHT über Register
machen sondern soweit möglich die Variablen im SRAM speichern.
Man nimmt ja nicht einfach so einen Mega128 (nicht für kleine Dinge)
und irgend wann, bei einem größeren Projekt, ärgerst Du dich dann, das
Du für eine Funktion die viele Register benötigt (32Bit-Operationen und
Pointer) kein Register mehr frei hast und dauernd am pushen und poppen
bist.

Gruß
Andi

von Doc. Shorty (Gast)


Lesenswert?

Das mit den Registern hab ich auch erst im nachhinein gemacht, als ich
keinen Ausweg mehr wusste ...
Hatte vorher auch über das Ram gespeichert.
Aber wie gesagt, dachte mir halt, das ich beim abrufen der Daten aus
dem Ram und dann auftretenden IRQ (welches die Daten ja denne auch
direkt ins Ram schreibt) Prob kriege.Erst daraufhin habe ich auf die
Register zurückgegriffen um sicher zu gehen .....

tüüttelüt .... nach sichern des SREG läuft es nun seit 10 min.

Kannst du mir sagen, was mit dem Register während dem IR passiert ?
warum ist das Ding mit sichern und wieder herstellen so wichtig ??

von Andi (Gast)


Lesenswert?

Im Statusregister 'SREG' sind die Ergebnisse nach CPI, ADD, SUB in
Binärform (C=Carry, Z=Zero, N=Negative, V=Overflow, H=Halfcarry,
T=Transport-Flag) gespeichert.
Wenn in Deinem Main z. B. ein Zähler mit 'dec Counter' runtergezählt
wird und darauf ein 'brne loop' kommt wird vom zufällig kommendem
Interrupt das Z-Flag durch ein weiteres CPI verändert und das
Main-Programm trifft nach dem Interrupt eine falsche Entscheidung.
Da es nur ein Statusregister gibt muß das im Interrupt gesichert werden
um das Main-Programm nicht zu irritieren.
Ne bessere Erklärung ist mir jetzt leider nicht eingefallen, klingt
vielleicht ein bißchen wirr :-)

Gruß
Andi

von Doc. Shorty (Gast)


Lesenswert?

nee..

ist schon völlig ausreichend.
Jetzt gibt das ganze auch wieder Sinn..... (mehr oder weniger)

Danke.

Kann ich nun also den ganze Code wieder umschreiben (wech von den
Registern).
Die Anzeige sieht nun "fast" gut aus. Bemerke immer noch einige
Unregelmäßigkeiten (leider) die ich jedoch bei weiteren Anzeigen mit
überbügeln kann.

Bedanke mich .....


Shorty

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.