www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Hardware-Interrupt R8C/13


Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab ein kleines Problem an den ich nicht weiterkomme.

Ich habe für mein µC R8C/13 ein Programm geschrieben das ein 
X_Timer-Interrupt und ein UART0_RX-Interrupt verwendet.

Der X_Timer hat ein Prioritätslevel von 1.
Der UART0_RX hat ein Prioritätslevel von 6.
txic  = 0x02;    //Timer interrupt priority level = 2
s0ric   = 0x06;    //UART0 interrupt priority level = 6

Das heißt das der UART0_RX-Interrupt "bevorzugt" wird. Ich habe nun das 
Problem, dass ich den UART0_RX-Interrupt zwischenzeitlich auf ein 
anderes Level ändern muss.
s0ric   = 0x01;    //UART0 interrupt priority level = 1

Wenn ich den interrupt jetzt wieder auf Level 6 zurück ändern will, 
funktioniert das ganze aber nicht.
s0ric   = 0x06;    //UART0 interrupt priority level = 6


Hat jemand eine Idee ???

Gruß

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du vor der Zuweisung des neuen IPL das IR Bit getestet, ob noch ein 
IRQ ansteht (requested ist)? Wenn das der Fall wäre, würde die Zuweisung 
nicht funktionieren. (Hardwaremanual 19.2.6)

Mit dem Holzhammer könntest du diesen IRQ disablen, das IR Bit löschen 
und dann die Zuweisung machen und dann den IRQ wieder enablen.

Damit keine Zeichen verloren gehen, könnte man auch anders arbeiten: In 
der UART Interruptroutine ein globales Flag aus dem Userprogramm 
abfragen, ob die IPL Maske geändert werden soll und entsprechend 
reagieren. Zu diesem Zeitpunkt sollte die UART ja mit hoher 
Wahrscheinlichkeit leer sein bzw. das IR Bit auf 0 stehen.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

Stefan B. schrieb:
> (Hardwaremanual 19.2.6)

Das hatte ich übersehen, ich werde das damit mal probieren.

Danke für den Tipp


Gruß
Peter

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich mach das genauso, wie es im Handbuch steht, nur es funktioniert 
nicht. Was mache ich falsch ?

Gruss

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir keiner weiterhelfen ?

Gruss

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann dir nicht weiterhelfen, weil du keinen Quellcode zeigst.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

hier der Code:
asm("FCLR I");    //Interrupt ausschalten
s0ric   = 0x00;   //Interrupt disable
ir_s0ric = 0;
asm("nop");    
asm("nop");
asm("FSET I");    //Interrupt einschalten

      
Warten_ms(3000);  //Dauer bis zum wegdrücken
Senden(Befehl[2]);  //wegdrücken
Warten_ms(3000);  //warten    
Senden(Befehl[1]);  //anrufen
Warten_ms(15000);  //Dauer des Anrufs
Senden(Befehl[0]);  //auflegen
      
asm("FCLR I");    //Interrupt ausschalten
s0ric   = 0x06;   //Interrupt Level 6
ir_s0ric = 0;
asm("nop");    
asm("nop");
asm("FSET I");    //Interrupt einschalten

Wenn ich Ihn einmal ausschalte, lässt er leider nicht wider einschalten, 
ich hoffe Du kannst helfen.

Gruss

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja was soll ich sagen. Unter debugbarem Code verstehe ich was anderes.

Der Codefetzen eingebettet in ein provisorisches main() konnte 
fehlerfrei simuliert werden. s0ric konnte auf 0 bzw. 6 gesetzt werden. 
ir_s0ric konnte gelöscht werden.

Interruptinitialisierung und Interruptroutinen fehlen ja, daher war 
diese Simulation schnell erledigt :-)

Hast du irgendwo im Programm IPL im FLG Register geändert? Es darf nicht 
6 oder 7 sein!

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

sorry. Ich schicke Dir am besten den kompletten Code sobald ich zuhause 
bin. Du hast recht wenn Du sagst, dass man mit so ein paar Codefetzen 
nichts anfangen kann.

Gruss

Autor: P. F. (pfuhsy)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Also, hier de komplette Code.

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also das alles hat folgenden Hintergrund, vielleicht hast Du ja einen 
besseren Lösungsansatz.

Zur Hardwareverschaltung:
Ich hab den R8C/13 über UART an das Bluetoothmodul BTM-222 verbunden. 
Der BTM-222 ist über Bluetooth an ein Handy verbunden.

Zur Idee und Programmierung:
Ich habe im Code 2 Interrupts. Ein Time-Interrupt mit Level 2 und den 
besagten UART0-Interrupt mit Level 6.
Der Time-Interrupt soll nichts anderes machen als alle 20ms (50 Hz) eine 
Variable mit +1 zu Inkrementieren. Damit will ich Zeiten haben, die das 
Programm "abbummeln" kann, der Code soll also z.B. 5000 ms warten bis er 
den nächsten Schritt ausführt.
Der UART0-Interrupt soll dafür gut sein, dass er eine Funktion ausführt 
(Empfangene Daten im Array ablegen), sobald er Daten von den verbundenen 
Handy bekommt. Da ich nicht immer weiß wann die Daten kommen, hab ich 
mir gedacht dies einfach mit einem Interrupt zu machen. Dieser ist 
natürlich "höher gestellt" als der Time-Interrupt, damit mir Daten die 
während des Time-Interrupts gesendet werden, nicht verloren gehen. Nun 
hatte ich aber, in der Funktion Ueberwachung, folgendes Problem. In der 
If-Schleife "Testanruf", habe ich eine Abfrage, nach dem Inhalt im Array 
des UART0-Interrupts, und Warteschleifen. Das blöde ist jetzt, das das 
Program an der Stelle nicht weitergeht und hängen bleibt. Ich hab 
einfach mal den UART0-interrupt ausgeschaltet und es hat ohne Probleme 
funktioniert. Ich kann jetzt nicht genau nachvollziehen warum sich das 
so verhält, da sich im Array (empfangene Daten) nichts befindet, es 
funktioniert aber so.

Daher kommt die Idee den "störenden" Interrupt kurzzeitig abzuschalten. 
hast Du vielleicht eine andere Idee wie man das Problem lösen könnte.

Gruss

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit dem letztens geposteten Codestück konnte ich dein Problem (UART RX 
wird nach dem Ändern seines IPLs nicht mehr angesprungen) reproduzieren 
aber noch nicht lösen. Das Problem interessiert mich und ich schaue 
heute abend weiter danach. Gestern hat das HEW Einrichten und Projekt 
aufsetzen die meiste Zeit verschlungen.

Jeder Interrupt hat sein eigenes Interrupt Request Flag, d.h. selbst bei 
gleichem Interrupt Prioritätslevel gehen keine Interrupts verloren 
wenn keine zwei Interrupts für den gleichen Vektor eintreffen. Wenn A 
und B Interrupts bekommen und wenn A vorrangig zu B ist, wird B nach dem 
RETI von A aufgerufen. Aber zwei Interrupts für B können eintreffen, 
wenn ein (mehrere) vorrangige(r) Interrupt A zu lange abgearbeitet wird.

Bei einem default vorrangigen Timer X alle 20ms der bloß einen Zähler 
erhöht gegen eine default nachrangige UART RX mit 19200 BAUD, sehe ich 
da keine Gefahr. Das könnte man mal berechnen oder testen.

Dein Code hat auch noch ein Problem mit dem nicht-interruptfesten 
Zugriff/Reset des Index i des RX-Datenpuffers wenn der RX-Puffer 
entleert wird.

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, vielen dank für die Infos. Ich hab schon mehrere Probleme des Codes 
gelöst und damit immerwieder neue Probleme ans Tageslicht gebracht. Ich 
hba gemerkt, dass man dafür einen langen Atem braucht.

Stefan B. schrieb:
> Das Problem interessiert mich und ich schaue
> heute abend weiter danach.

Vielen Dank, ich bin mal gespannt. Ich versuche auch noch ein parr 
Sachen vielleicht finde ich ja noch was.

Stefan B. schrieb:
> wenn ein (mehrere) vorrangige(r) Interrupt A zu lange abgearbeitet wird.

Was heißt den "zu lange" ?

Stefan B. schrieb:
> Bei einem default vorrangigen Timer X alle 20ms der bloß einen Zähler
> erhöht gegen eine default nachrangige UART RX mit 19200 BAUD, sehe ich
> da keine Gefahr. Das könnte man mal berechnen oder testen.

Wie berechnet man den sowas ?



Hast du vielleicht noch eine Idee warum im Eingangpuffer manchmal ein 
paar empfange Daten verloren gehen. Wenn ich z.B. "atd0123456" sende, 
bekomme ich manchmal nur"atd01" wieder, beim nächsten senden dann "atd" 
und vielleicht beim 3. mal bekomme ich komplett auch das wieder was ich 
sende. Deswegen habe ich dort eine Schleife eingebaut, die das Senden 
sollange wiederholt, bis ich ein "OK" sehe. Damit umgehe ich das Problem 
aber nur, vorhanden ist es trotzdem.

Gruss

Autor: gk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter F. schrieb:
> Wie berechnet man den sowas ?

Berechne die minimale Zeit zwischen zwei Zeichen bei 19200. Deine 
Timerroutine muss entsprechend schnell abgearbeitet sein, damit kein 
Zeichen verloren geht.
gk

Autor: Stefan B. (stefan) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So könnte ich mit dem Programm leben. Das zeitweilige Ausschalten des 
UART0 RX beim Testanruf funktioniert jetzt IMHO. Eingaben über UART0 RX 
während des Anrufes und in den Wartezeiten werden ersatzlos verworfen. 
Nach dem Anruf wird der IRQ auch wieder eingeschaltet und weitere 
Testanrufe sind über Eingaben über UART0 RX möglich. Ich habe nirgends 
echt angerufen sondern mit einem Terminalprogramm simuliert.

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ui...da hast Du Dir ja richtig Mühe gegeben. Das werde ich natürlich 
austesten und Dir Rückmeldung geben. Danke für die Hilfe erstmal.

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ja schon eine weile her das ich mit dem r8c13 rumgespielt habe.
Aber warum machst du das in deiner Interruptroutine?

//Daten am Empfang (RX) abholen
while (!ri_u0c1);//Warten bis Empfangspuffer voll

Wenn der Interrupt aufgerufen wird dann solle es sichergestellt sein das 
du ein Byte aus von deiner Schnittstelle abholen kannst. Dein while ist 
also mindestens mal unnoetig. Und eine eventuelle Endlosschleife ist 
sowieso schlecht und im Interrupt ist sie doppelt schlecht.

Kann es vielleicht sein das der Interrupt bereits dein Bit zuruecksetzt 
und dein while auf das naechste Byte wartet?

Olaf

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter F. schrieb

> Ui...da hast Du Dir ja richtig Mühe gegeben. Das werde ich natürlich
> austesten und Dir Rückmeldung geben. Danke für die Hilfe erstmal.

Jo, ein paar Namen sind aussagekräftiger geworden und manche 
auskommentierte Abschnitte aus deinem Original sind rausgeflogen. nicht 
wundern bzw. aus dem Backup einpflegen, wenn es gebraucht wird.

Olaf schrieb

> //Daten am Empfang (RX) abholen
> while (!ri_u0c1);//Warten bis Empfangspuffer voll
>
> Wenn der Interrupt aufgerufen wird dann solle es sichergestellt sein das
> du ein Byte aus von deiner Schnittstelle abholen kannst. Dein while ist
> also mindestens mal unnoetig. Und eine eventuelle Endlosschleife ist
> sowieso schlecht und im Interrupt ist sie doppelt schlecht.

U.a. hatte ich mich über das Gleiche gewundert und auch in Olafs Sinn 
geändert.

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

also ich hab das ganze mall ausgetest leider funktioniert der testanruf 
nicht. Bzw. nach dem resetn funktioniert das ganze 1x dannach nicht 
mehr.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schade war ein Versuch. Aber bei so einem komplexen Projekt ist es 
wahrscheinlich, dass man nicht 100% der Bugs mit dem ersten und einzigen 
Schuß erledigt.

Ferndiagnostisch gesehen stehe ich mit 
Beitrag "Re: Hardware-Interrupt R8C/13" im unbeleuchteten 
Tunnel, Hände auf dem Rücken.

Vielleicht magst du ja die eingebauten Debug- und Simulationshinweise 
verwenden, um herauszufinden, ob der R8C das Problemkind ist oder das 
von mir nicht berücksichtigte BTM oder das von mir nicht berücksichtigte 
Telefon.

Die nächste Maßnahme von mir an deiner Stelle wäre einen UART/RS232 
Sniffer anzuklemmen und wenistens die Kommunikation zwischen R8C und BTM 
abzuhören und zu loggen.

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, Schade. Ein paar Sachen habe ich übernommen, da ich diese für 
ziemlich gut und übersichtlich finde.

Hast Du denn eine Idee warum beim Empfang, der vom BTM gesendeten 
Signale, hin und wieder mal etwas verschluckt wird ? Kann es mit den 
Time-Interrupt zusammen hängen, so nach dem Motto: Wenn der 
Time-Interrupt anspringt und wieder "zurückkommt" hat er in der Zeit ein 
Zeichen übersehen. Aber das darf doch eigentlich nicht sein oder, der 
Interrupt vom UART0 unterbricht doch eigentlich den Time-Interrupt.


Gruss

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> Vielleicht magst du ja die eingebauten Debug- und Simulationshinweise
> verwenden, um herauszufinden, ob der R8C das Problemkind ist oder das
> von mir nicht berücksichtigte BTM oder das von mir nicht berücksichtigte
> Telefon.

Das werde ich sowieso mal machen, kann aber ein bisschen dauern.

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.