12F683 Wieviele Befehle packt ein Interrupt? (Assembler))

OP (Firma: Monster AG) #885004
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
#885020
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?
Persönliche Seite #885033
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
Gast #885043
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.
OP (Firma: Monster AG) #885074
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ß
#885114
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.
OP (Firma: Monster AG) #885127
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
Persönliche Seite #885136
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
#885137
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!!!
Persönliche Seite #885402
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:
1
;Macro definieren
2
Bank0  macro
3
  bcf STATUS,RP0  ;Bank 0
4
  bcf STATUS,RP1
5
  endm
6

7
;Macro aufrufen
8
         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
#885424
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_smf/Itemid,121/topic,1245.0/

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren