www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 12F683 Wieviele Befehle packt ein Interrupt? (Assembler))


Autor: Wolf Retlaw (Firma: Monster AG) (ik-student)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich (Anfänger) bin beim Programmieren an einen Punkt gekommen, wo ich 
feststellen muss, dass meine Interrupt-Routine (TMR0 Interrupt) nicht 
mehr ordnungsgemäß funktioniert. Wenn ich einen gewissen stupiden 
Schritt (irgendwelche flags setzen um LED zum Leuchten zu bekommen) in 
einem Unterprogramm rauslasse funktioniert wieder alles. Vorab ich habe 
und muss alle Programmteile im Interrupt laufen lassen. Gibt es eine 
bestimmte Grenze wo in der Routine so viele Befehle drinnen sind, dass 
der Interrupt nicht mehr richtig funktionieren kann? So was ähnliches 
wie einen "worst-case" ?

Danke im Voraus
Gruß Wolf

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es würde helfen, wenn Du den Programmcode posten würdest. Idealerweise 
auf das Minimum abgespeckt, um das Problem aufzuzeigen, und in beiden 
Versionen (also die die nicht funktioniert und die mit dem 
Unterprogramm, die funktioniert).

Hast Du das Ganze in Hardware getestet und/oder mit dem Simulator?

Sind die Banks korrekt ausgewählt?

Ist die Interrupt-Routine so lang, dass sie noch immer läuft wenn der 
nächste TMR0 Interrupt kommt?

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kannst du dir doch selber ausrechnen, bzw. abzählen. Die Timer 
werden doch mit dem selben Takt getaktet wie die Befehle abgearbeitet 
werden. Wenn also der Prescaler des Timer0 auf 1:1 steht, läuft der 
Timer0 nach genau 256 Befehlen über und erzeugt einen Interrupt. Bei 
Prescaler 2:1 entsprechend 512 Befehle usw. Wenn deine Interruptroutine 
mehr wie 256 (512, ...) Befehle abarbeiten muss dann trifft ein neuer 
Interupt ein, bevor der alte beendet wurde.

Du solltest die ISR so kurz wie möglich machen und den Rest in der 
Hauptroutine. Im Simulator siehst du übrigens wunderbar wie viele 
Befehle zwischen zwei Haltepunkten abgearbeitet werden.

Sven

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und dann noch die Zeit für Interruptaufruf, reti und evtl. Sicherungen 
diverser Register. Kenne aber den PIC nicht, um zu wissen, wieviel Takte 
das konkret kostet.
Eine ISR sollte jedenfalls nicht in die Nähe von 100% Prozessorzeit 
kommen :-)
Auch möglich sind evtl. stackprobleme.

Autor: Wolf Retlaw (Firma: Monster AG) (ik-student)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort!

@Severino R. wenn der TMR0 Interrupt kommt schalte ich ihn wieder aus, 
also kann kein anderer Interrupt in die Quere kommen, banks etc. sind in 
der Initialisierung alle richtig ausgewählt.

Aber das mit dem Simulator klingt interessant, aber da habe ich noch 
nicht so die große Ahnung, ich habe schon versucht damit zu arbeiten 
aber irgendwie habe ich es noch nicht geschafft mit Interrupts zu 
simulieren, da muss doch irgendwie der Interrupt simuliert ausgeführt 
werden, kann man das irgendwo einstellen ? ich arbeite momentan mit dem 
MPLAB IDE v8.10.

Einfacher wäre es richtig debuggen zu können aber leider geht das wohl 
mit diesem PIC nicht, nur simulieren !?


Gruß

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wolf Retlaw wrote:
> banks etc. sind in der Initialisierung alle richtig ausgewählt.

Und später beim Ansprechen von Registern?

> Aber das mit dem Simulator klingt interessant, aber da habe ich noch
> nicht so die große Ahnung, ich habe schon versucht damit zu arbeiten
> aber irgendwie habe ich es noch nicht geschafft mit Interrupts zu
> simulieren, da muss doch irgendwie der Interrupt simuliert ausgeführt
> werden, kann man das irgendwo einstellen ? ich arbeite momentan mit dem
> MPLAB IDE v8.10.

Setze einen Breakpoint am Anfang Deiner ISR, und Du wirst sehen, dass 
das Programm dort stoppt!!!

> Einfacher wäre es richtig debuggen zu können aber leider geht das wohl
> mit diesem PIC nicht, nur simulieren !?

Wenn das Problem beim Simulator nicht auftritt, wird Debuggen mit dem 
ICD2 (das meintest Du doch, oder?) erst interessant. Wenn das Problem 
beim Simulator auch auftritt, solltest Du mit dessen Hilfe den Fehler 
suchen. Im Simulator läuft der Timer synchron zu den Einzelschritten; 
beim ICD2 läuft der Timer halt weiter, wenn das Programm angehalten 
wird.

Es gibt einen speziellen PIC12F683, der PIC12F683-ICD. Der hat 
zusätzliche Pins, um mit den ICD2-Signalen die knappen Pins nicht zu 
blockieren.
Der PIC12F683-ICD ist montiert auf einem kleinen Print "Header-Print" 
von Microchip erhältlich: Artikel AC162058. Auf dem Header-Print 
befindet sich auch der RJ-12 Anschluss, und der Print hat auf der 
Unterseite Stifte im DIL8-Layout, um ihn an Stelle des PIC12F683 in die 
Schaltung zu stecken.

Autor: Wolf Retlaw (Firma: Monster AG) (ik-student)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Severino R. wow danke dir, und Ja ich habe ICD2, wusste gar nicht dass 
es einen speziellen PIC gibt! der wird aber bestimmt einiges kosten g

Habe übrigens meinen Fehler gefunden, zuviele Calls haben ein Problem im 
Stack ausgeführt schäm

Aber der Thread hat trotzdem einige neue Informationen locken können :-)

Gruß Wolf

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit einem ICD2 kannst du auch direkt im PIC debuggen. A

ber der Simulator ist für solche kleineren Probleme ganz gut. Du gehst 
halt einfach Schritt für Schritt durch. Wenn der Timer einen Interupt 
auslößt, springt das Programm automatisch auf Adresse 4 und arbeitet 
dann weiter. Wenn du nicht 256 mal klicken willst, kannst du auch das 
Timer0 Register einfach mit z.Bsp 255 beschreiben und dann weiter 
klicken. Probier einfach ein bisschen rum. Gerade als Anfänger kann man 
da wunderschön die meisten Sachen simmulieren. Du hast jedes Register im 
Blick und kannst eigene Werte eingeben. Mit dem Stimulus Controller 
kannst du auch externe Ereignisse simulieren z.Bsp. das an RB0 eine 
L/H-Flanke auftritt oder das Über die Serielle ein bestimmtes Bitmuster 
eingelesen wird. Alles noch ganz ohne Hardware.

Also wenn ich das richtig interpretiere benötigt der PIC nach dem 
Interuptereignis 5 Befehlszyclen bis er den Befehl auf Adresse 4 
abgearbeitet hat, genauso dann wieder bei einem RETFIE. Dann kommen 
natürlich noch bis zu 10 Befehlen wo man die Register rettet und das 
Interupt-Ereignis abfragt (die 16F PICs kennen nur eine Interuptadresse, 
deshalb muss man als erstes feststellen welcher Interupt aufgetreten 
ist). Am Ende wieder das selbe. Da können schon mal 20-30 Befehle drauf 
gehen, bevor du in deiner Routine bist.

Ein Interupt kommt dir innerhalb der ISR normalerweise sowiso nicht in 
die Quere, da der PIC das GIE-Flag deaktiviert sobald er in die ISR 
springt. Damit sind alle Interupts abgeschaltet, solange die ISR läuft. 
Allerdings können trozdem Ereignisse auftreten, welche das entsprechende 
Bit wieder enabeln. Sobald die ISR verlassen wird und es trat 
zwischendurch ein Ereignis auf springt der PIC sofort wieder in ISR und 
arbeitet den Interupt ab. Also angenommen deine ISR benötig 1000 
Befehle, dann würde der Timer0 mit Prescaler 1:1 in dieser Zeit 3x das 
T0IF setzen. Damit gehen dir die Interupts verloren und dein Programm 
arbeitet nicht korrekt.

Stell dein Prog doch mal hier ein, dann können wir mal drüber schauen. 
Eventuell gest du die Sache ja falsch an.

Gruß
Sven

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wolf Retlaw wrote:
> @Severino R. wow danke dir, wusste gar nicht dass es einen speziellen
> PIC gibt! der wird aber bestimmt einiges kosten *g*

Wenn das Ding hilft, Zeit zu sparen... Kostenlos gibt es das Teil nicht, 
aber es ist ja ein Entwicklungswerkzeug, das man dann nicht in der 
fertigen Schaltung belässt, sondern wieder benutzen kann.

Bei Farnell EUR 18.00

> Habe übrigens meinen Fehler gefunden, zuviele Calls haben ein Problem im
> Stack ausgeführt schäm

Wow! mehr als sieben CALLs in einer ISR!!!

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So schön wie das ist mit den Unterprogrammen, aber bei einer Stacktiefe 
von 8 muss man schon aufpassen und es nicht übertreiben mit den Calls. 
Ein Call benötigt auch zwei Befehlszyklen und das Return dann auch 
wieder. Für ein Unterprogramm mit 2-3 Befehlen also unnötig. Dann doch 
lieber wieder copy and paste...

Sven

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven Stefan wrote:
> Dann doch lieber wieder copy and paste...

Oder ein MACRO.

Autor: Wolf Retlaw (Firma: Monster AG) (ik-student)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Macro?

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, du definierst ein paar Zeilen Code als Macro und rufst dann im 
Programm an der Stelle das Macro auf, wo du den definierten Programmcode 
einfügen willst. Ist eigentlich nur ein optischer Trick um den Quellcode 
übersichtlicher zu gestalten. Der Compiler fügt beim Übersetzen genau 
den Quellcode an der Stelle ein wo du das Macro aufrufst. Du sparst 
damit also keinen Speicherplatz.

Bsp:
;Macro definieren
Bank0  macro
  bcf STATUS,RP0  ;Bank 0
  bcf STATUS,RP1
  endm

;Macro aufrufen
         Bank0

An der Stelle wo du das Macro aufrufst werden vom Compiler beim 
übersetzen die beiden Befehlszeilen eingefügt. Im Quellcode steht aber 
nur Bank0 als Befehl.

Sven

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Wolf:
Falls Du MACROs nicht kennst: Du kannst auch "Argumente" verwenden, also 
eine Art Parameter, welche jedoch (anders als bei z.B. Funktionsaufrufen 
in Hochsprachen) zur Assemblierzeit (und nicht erst zur Laufzeit) 
ersetzt werden.
Deshalb müssen die Argumente Konstanten sein.

Näheres im Manual von MPASM sowie z.B.:
http://www.fernando-heitor.de/component/option,com...

Autor: Wolf Retlaw (Firma: Monster AG) (ik-student)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok,

vielen Dank an euch! Heute habe ich wieder einiges gelernt :-)

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.