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.