Forum: Mikrocontroller und Digitale Elektronik Unterprogramme in Interrupt-Routine


von Philipp (Gast)


Lesenswert?

Hallo
ich möchte Unterprogramme in eine Timer Interrupt-Routine einbauen, doch 
es funktioniert nicht. Es bleibt vermutlich im ersten Unterprogramm 
stecken und das Interrupt kommt nicht.
Beides getrennt von einander funktioniert. Also wenn ich die 
Unterprogramme im void main() teste funktioniert es und wenn ich den 
Interrupt alleine teste funktioniert er auch.

1
#include <33FJ256MC710A.h>
2
#include <stdio.h>
3
#include <stdlib.h>
4
5
#fuses XT,PR_PLL,NOWDT
6
#use delay (crystal=8M, clock=80M)
7
#INT_TIMER2
8
9
int eins(int a)
10
{
11
    int b=3,v=2;
12
    a=b+v;
13
    return(a);
14
}
15
16
int zwei(int d)
17
{
18
    int e=4,a,f;
19
    f=eins(a);
20
    d=e+f;
21
    return(d);
22
}
23
24
void TIMER2interrupt()
25
{
26
    int d,c=0;
27
        c=zwei(d);
28
        if(c==9)
29
        {
30
            output_high(PIN_E5);
31
        }
32
        else
33
            output_low(PIN_E5);
34
   clear_interrupt(INT_TIMER2);
35
}
36
37
void main()
38
{
39
    setup_timer2(TMR_DISABLED);
40
    setup_timer2(TMR_INTERNAL | TMR_DIV_BY_1,4000);
41
42
    enable_interrupts(INT_TIMER2);
43
    enable_interrupts(INTR_GLOBAL);
44
    clear_interrupt(INT_TIMER2);
45
46
    while(1)
47
    {
48
    }
49
}
Ich hoffe mir kann jemand helfen

mfg

: Bearbeitet durch User
von Philipp (Gast)


Lesenswert?

PS:
Ich verwende den dsPIC33FJ256MC710A, das dsPICDEM MCLV, einen CCS 
Compiler

von Karl H. (kbuchegg)


Lesenswert?

grundsätzlich:

sag nicht "es funktioniert nicht".
Sag "ich erwarte das und das. Aber statt dessen passiert dieses und 
jenes"


dann
1
int zwei(int d)
2
{
3
    int e=4,a,f;
4
    f=eins(a);
5
    d=e+f;
6
    return(d);
7
}
welchen Wert hat hier a, wenn du die FUnktion eins aufrufst?

Wenn du eine lokale Variable nicht ausdrücklich initialisierst, kannst 
du dich auf keinen Wert verlassen. Es ist zufällig, welchen Wert a hier 
hat.

von Karl H. (kbuchegg)


Lesenswert?

Selbiges hier
1
void TIMER2interrupt()
2
{
3
    int d,c=0;
4
        c=zwei(d);

welchen Wert hat d?
der ist völlig undefiniert. zufällig.

Gut, so wie zwei geschrieben ist, spielt das keine Rolle. Es ist 
trotzdem schlechtes Programmieren, wenn man die Internals von zwei 
kennen muss, um zu wissen, ob es an dieser Stelle egal ist oder nicht. 
Hier wird der Inhalt einer Variablen an eine Funktion übergeben und über 
diesen Inhalt wissen wir nur eines: der ist zufällig.

von NurEinGast (Gast)


Lesenswert?

Deine Funktionen sind - sorry - ziemlicher Unsinn.
Die übergeben Parmeter werden nie verwendet.

Wenn ich's im Kopf richtig überschlagen habe, kommt aus "zwei(d)" immer 
9 heraus.
Wobei der Parameter "d" für zwei(d) nicht intialisuert wird. Ist aber 
egal, weil er in den Funktione sowieso nicht benutzt wird.

Dieses Konstrukt ist vollkommen unklar.

von Karl H. (kbuchegg)


Lesenswert?

Irgendwie fehlt mir in deinem Code das Gegenstück zu
1
    setup_timer2(TMR_DISABLED);

du gibst zwar im Nachhinein Interrupts frei. Das ist alles schön und 
gut.
ABer wird dadurch auch der Timer enabled? Arbeitet der?

von Philipp (Gast)


Lesenswert?

Es soll die LED am Pin E5 leuchten.

Den Wert der Variable a soll er aus dem ersten Unterprogramm übernehmen

von Philipp (Gast)


Lesenswert?

@ NurEinGast:
Ich weiß das es keine großartiges Programm ist, es geht mir darum einen 
Wert von einem Unterprogramm in ein zweites zu übergeben und dann in 
einer Interrupt-Routine eine Aktion durchzuführen. Wenn ich das geschaft 
habe werde ich es natürlich noch Sinnvoll ausbauen.

Ja eigentlich sollte immer 9 heraus kommen aber trotzdem leuchtet die 
LED nicht.

@ Karl Hein:
Wenn ich bei anderen Programmen ohne Unterprogramme die 
Timer-Interrupt-Routine verwende funktioniert sie einwandfrei.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Philipp schrieb:
> Den Wert der Variable a soll er aus dem ersten Unterprogramm übernehmen

Wer ist "er"?

Und hast Du Dir überhaupt schon mal angesehen, wie in C die 
Parameterübergabe und -Rückgabe mit Funktionen (so nennt man das, was 
Du als "Unterprogramm" bezeichnest) funktioniert?

Was sagt denn Dein C-Buch dazu?


Mit Interrupts jedenfalls hat Dein Problem überhaupt nichts zu tun.

von profi (Gast)


Lesenswert?

schreib mal das "#INT_TIMER2" über die Funktion für den Timer IRQ

also:
1
#INT_TIMER2
2
void TIMER2interrupt()

von Amateur (Gast)


Lesenswert?

Da "C", außer bei einfachsten Befehlen, sowieso Funktionen einbindet, 
warum nicht?

Normalerweise kannst Du innerhalb von Unterbrechungen machen was Du 
willst.

Wichtig ist nur, dass Du garantiert fertig wirst, mit etwas Reserve, 
bevor ein erneuter Aufruf erfolgt.
Schön wäre es auch, wenn noch etwas Zeit, für die Hauptroutine und 
eventuelle andere Unterbrechungen, übrig bleibt.

Alles in allem ein zeitliches Problem. Es besteht ja auch kein 
Unterschied zwischen einem linearen Programmablauf und einem mit 
Unterprogrammen.
Natürlich kosten der Aufruf (call), ein eventuelles Registersichern 
(push), die Restauration von Registern (pop) und der Rücksprung ihre 
Zeit (ret).
Bei längeren Routinen ist das prozentual Vertretbar. Für kürzere 
Sequenzen bietet sich die Anweisung Inline an.
Ob damit mehr als das call und ret gespart werden ist eine andere Sache.

von nein? (Gast)


Lesenswert?

Man sollte keine solchen Spielchen machen. Was sollen Unterprogramme in 
einem interrupt? Vergiss solches Zeug. Eine schlechte Idee.

von Philipp (Gast)


Lesenswert?

"Er" ist die zweite Funktion

Ein Beispiel ist darin:

int example(int a, int b)
{
 return a+b;
}

.
.
.

void main()
{
int a=9;
int b=15;
int c=example(a,b)
}

von Philipp (Gast)


Lesenswert?

Danke Profi, dass war das Problem...

Danke an alle

von Karl H. (kbuchegg)


Lesenswert?

?
Sagtest du nicht, du hättest Interrupts alleine getestet?

von Philipp (Gast)


Lesenswert?

Ja hab ich und weil ich beide Funktionen gelöscht habe war auch das 
#INT_TIMER2 genau vor der Interrupt-Routine

von Profi (Gast)


Lesenswert?

kein Problem
Rechnung folgt....... ;-)

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.