mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupts beim mega8515


Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:

Autor: Dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nen stack overflow vielleicht? (dacht ich grad dran)

dave

Autor: Interesierter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in solchen Fällen hilft bei mir nur das Simulieren in Studio.

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
den interessantesten Programmteil (RxRoutine) hast du schlauerweise
weggelassen....

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Benedikt (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.