Forum: Mikrocontroller und Digitale Elektronik Glyn EVBM16C/62P Board - Probleme mit UART receive Interrupt


von Oli (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich habe Schwirigkeiten mit der Programmierung des UART0 receive
Interrupts.

Ich möchte die UART0 schnittstelle meines Glyn Boards
(EVBM16C/62P)abfragen.
Treffen Daten am UART0 ein, sollte der Interrupt anschlagen und die
Daten in den Buffer (U0RB) schreiben.

- Ich habe in main den Interrupt aktiviert mit "_fset( _I )"

- in sect30 habe ich eingetragen:
;---------------------------------------------------------------
; variable vector section
;---------------------------------------------------------------

.lword  dummy_int    ; uart0 transmit(for user)(vector 17)

  .glb  _UART0_RX
  .lword  _UART0_RX    ; uart0 receive(for user)(vector 18)
;  .lword  dummy_int    ; uart0 receive(for user)(vector 18)


aber
irgendwas mit meinem Code stimmt nicht und ich möchte Euch mal um Rat
fragen. Vielleicht sieht einer von Euch den Fehler.

Wenn jemand schon eine funktionierdende Routine für dieses Problem hat,
wäre ich natürlich auch sehr interessiert daran.

Jetzt schon vielen Dank für Eure Inputs

Gruss Oli

von Jens (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Uli,

so ganz kann ich Deiner Quelle nicht folgen: Die
Interruptserviceroutine muesste für meinen Geschmack UART0_RX heissen,
die Unterstriche werden vom Compiler hinzugefügt.

Und warum deklarierst Du die Funktion innerhalb einer anderen? Sie
sollte eigentlich einzeln stehen. Aber vielleicht ist hier nur mein
C-Wissen zu dünn...

Die Prio 7 ist für den Monitor reserviert, versuche lieber 6 oder
weniger (der serielle Interrupt bei 9600Bd ist ja nun nicht ganz so
hektisch...).

So ganz passen Quelle und Anforderung auch nicht zusammen, da Du den
empfangenen Wert in eine lokale Variable schreibst. Ich würde
vorschlagen, Du überarbeitest das Programm noch etwas - oder Deine
Beschreibung. Das RX-Byte steht übrigens im u0rbl.

Die sect30-Sache sieht gut aus.

Zur Info hänge ich Dir mal meine Sende-Empfangs-Routine an, die mit
Fifos für beide Richtungen arbeitet - aber auch noch nicht perfekt ist,
weil sie sich bei vollen Fifos gelegentlich verschluckt oder verklemmt.
Aber die Registerprogrammierung sollte ok sein.

Gruß
Jens

von Oli (Gast)


Angehängte Dateien:

Lesenswert?

Erstmal danke für die Erklärungen bezüglich der Interruptroutine

Ich hab jetzt mal die Priorität auf 6 zurückgesetzt.
Die Funktion habe ich nun nicht mehr in einer anderen deklariert. Die
Idee war ich rufe über main die Interruptroutine auf und verarbeite
diese dort. müsste doch auch gehen, oder?

Nun ja. mit den Interrupts habe ich immer noch so meine Probleme.
Ich denke mir fehlen die nötigen Grundlagen.
Kann mir jemand von Euch da mal auf die Sprünge helfen.
Bei mir kommt immer der Fehler "Interrupt ignored"

Ich hab mir mal die Dokus bei Glyn angesehen da steht:

#pragma INTERRUPT function name
void function name(void);

sorry dass ich so rudimentär frage. aber wie genau ist das zu
verstehen?
Ich muss dem Interrupt doch angeben bei welchem Erreignis er reagieren
muss, ist das das 1. function name? also z.B UART0_RX

Dann muss ich dem Interrupt doch mitteilen, welche routine er
abarbeiten soll, ist das das 2. function name?

Ich hätte da schon einen Beispiel Code bereit, wie genau müsste ich den
auf den M16C62P denn anpassen?

Grüsse Oli

von Jens M. (jensbert)


Lesenswert?

Oli,

zunächst mal eine kurze Antwort:
Der #pragma-Befehl dient dazu, dem Compiler mitzuteilen, dass die
Funktion name, die dann weiter unten deklariert ist, eine
Interrupt-Funktion ist. Er verändert dann den Code passend (Verwendung
des Interrupt-Stacks, richtiger Rücksprung-Befehl usw.)

Der Eintrag in die Sect30-Datei legt den Funktionsnamen fest, also die
Adresse, die bei einem Interrupt angesprungen wird. Unerwartet ist
vielleicht der Unterstrich, den Du davor setzen musst. Ich erkläre mir
das so, dass der Compiler ein Label (hier der Funktionsname) mit dem
Unterstrich versieht, bevor er es 'nach aussen', also ausserhalb des
eigentlichen Files, veröffentlicht.

Auf jeden Fall lohnt das Studium des Compiler-Manuals - am besten immer
mal wieder, mit zunehmender Erfahrung versteht man immer mehr.
Lieber zwischendurch etwas weglassen, was noch zu abgefahren
daherkommt.

Dein Beispielcode sieht doch schon sehr gut aus, er scheint eine
7-Segment-Anzeige anzusteuern, wenn das empfangene Zeichen zwischen 0
und 9 liegt. Was möchtest Du da groß anpassen? Sieht sehr nach M16C/62
aus, P oder nicht, sollte für Uart0 keinen Unterschied machen.

Lediglich
  asm( "\tFSET  I");  /* Enable interrupt */
scheint mir zu fehlen.

Und ob die while-Schleife im Main wirklich auf uart0 sendet, weiss ich
nicht ganz sicher, ich habe das schon vor Jahren durch meine eigene
Routine ersetzt...

Gruß
Jens

von Oli (Gast)


Lesenswert?

Hallo zusammen, Hallo Jens

Vielen Dank für die Infos betreffend Interrupt
Jetzt sind mir einige Dinge bereits wieder ein wenig klarer geworden.

Also ich habe mal versucht Deine Inputs in mein Projekt aufzunehmen.
Auch habe ich noch den Interrupt aktiviert mit _fset(_I);
Ich verwende den Tasking Compiler, darum sieht wahrscheinlich der
Interrupt Aktivierungsbefehl ein wenig anders aus.

Nach meiner Meinung müsste alles verhanden sein, aber ich habe immer
noch den Fehler "ignored Interrupt"

Dürfte ich Dir Jens (mikrocontrollerdl4aas.de) mal meinen Code
persönlich zumailen.
Du scheinst das Ganze recht gut zu verstehen und ich wäre froh um einen
weiteren Input von Dir.
Allerdings setzte ich meinen Code nicht so gerne öffentlich ins Netz.

schreib doch mal, was Du so darüber denkst

Gruss Oliver

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
Noch kein Account? Hier anmelden.