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
der code wäre hilfreich erste vermutung: sicherst du in der timer isr deine register alle?
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.
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 ;-)
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
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
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 ??
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.