Hallo, ich habe ein merkwürdiges Problem: Der uC macht immer wenn ich Daten per UART in das externe RAM lade einen Reset, dadurch dass ein Interrupt verursacht wird und so unkontrolliert in mein Programm läuft. Allerdings nicht sofort, sondern meistens so nach einigen kB Daten, manchmal früher und manchmal auch garnicht. Das Problem habe ich durch ein reti direkt vor dem eigentlichen Programm umgangen, aber das ist nur eine Hilfslösung. Und da ich eigentlich nur den UART und vielleicht den Timer0 Interrupt verwende, sehe ich eigentlich keine weitere Interruptquelle die den Interrupt verursachen könnten. Die RX Routine besteht eigentlich nur daraus, Daten einzulesen und ins SRAM zu schreiben. .org 0000 rjmp reset .org OVF0addr ;Timer 0 reti .org URXCaddr ; Interruptvektor für UART-Empfang rjmp RXRoutine .org 32 reti Reset: ldi r16, low(RAMEND) out SPL, r16 ; setup stack pointer ldi r16, high(RAMEND) out SPH, r16 ; setup stack pointer ldi temp, 2 TCCR0, temp clr temp out TCNT0, temp ldi temp, 2 ;out TIMSK, temp ldi temp, 25 ;38.4kBit bei 16MHz out UBRR, temp sbi UCsRb, RXCIE ; Interrupt bei Empfang sbi UCsRb, RXEN ; RX (Empfang) aktivieren ldi temp, 128 out mcucr, temp Main:
Probiers doch mal so: .cseg rjmp main reti reti reti rjmp TimerIRQ ;IRQ on Timer Compare Match A reti reti reti reti reti reti reti reti reti reti reti reti Da, wo ein IRQ gebraucht wird, statt dem reti ein rjmp rein und wo nicht, ein reti. Entsprechend der IRQ-Nummer von 0 an zählen. Ansonsten ist von Haus aus der Analog Comparator an. Zwar noch nicht mit IRQ gesetzt aber wenn nicht benötigt kann man den mit "sbi acsr,acd" abschalten. Gruß Andi
mach einfach mal für jeden int einen handler und dort schickst du dann ma per uart oder so rüber welcher int aufmuckt. vielleicht findest du so das problem
den interessantesten Programmteil (RxRoutine) hast du schlauerweise weggelassen....
Hier die RX Routine, aber da wird eigentlich nur das externe RAM beschrieben. Das ganze ist ein LCD Controller für ein Dualscan 640x480 LCDs (mit 2x 4bit Daten), daher die Aufspaltung der 8 bit in zwei Bytes, da jedes Byte im Speicher 4 bit für die obere und 4bit für die untere Displayhälfte enthält. Bisher läuft das ganze recht gut. Bei 16MHz erreiche ich 60Hz Displayfrequenz und kann nebenher noch Daten per UART laden. Für Grafikanwendungen wo häufig das komplette Bild aktualisiert werden muss ist das natürlich zu langsam, aber für ein Textdisplay kann man so einen Low Cost LCD Controller durchaus einsetzen. Ansonsten finde ich 3,5s für ein ein komplettes Bild an sich OK. Wenn das ganze zufriedenstellend läuft stelle ich den Code in die Codesammlung. RXRoutine: in temp, udr sbi portd, XSCL sbrc Spalte, 7 rjmp untereHalfte obereHalfte: ld temp2, X and temp2, LN ;obere Datenhälfte behalten mov temp3, temp and temp3, HN ;erste Hälfte behalten or temp2, temp3 st X+,temp2 ld temp2, X and temp2, LN ;obere Datenhälfte behalten swap temp and temp, HN ;erste Hälfte behalten or temp2, temp st X+,temp2 cpi XAdresseLow, 160 brne normal clr XAdresseLow inc Zeile cpi Zeile, 244 brne normal ldi Zeile, 4 sbr Spalte, 128 cbi portd, XSCL reti untereHalfte: swap temp ld temp2, X and temp2, HN ;untere Datenhälfte behalten mov temp3, temp and temp3, LN ;erste Hälfte behalten or temp2, temp3 st X+,temp2 ld temp2, X and temp2, HN ;untere Datenhälfte behalten swap temp and temp, LN ;erste Hälfte behalten or temp2, temp st X+,temp2 cpi XAdresseLow, 160 brne normal clr XAdresseLow inc Zeile normal: cbi portd, XSCL reti
Ich habe jetzt die Software etwas verändert und das Resetproblem behoben. Allerdings hängt sich der Controller in der UART Interrupt Routine andauernd auf, aber ich finde den Fehler nicht. Frage ich das Receive Flag ab und starte dann per Software die RX Routine läuft alles einwandfrei. Aktiviere ich dagegen den Interrupt, hängt sich der Controller auf wenn viele Daten empfangen werden. Da aber die Warteschleife etwa 20us dauert in der der Controller Zeit für den Interrupt hat, dürfte das kaum stören, mit der RX Routine ausgelöst per Software funktioniert es ja auch... Und selbst wenn er mal etwas länger brauchen sollte, dann darf er sich nicht aufhängen.
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.