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
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.