Forum: Mikrocontroller und Digitale Elektronik MSP430F1611 Rev B: Programmier - Problem mit Interrupts


von Armin M. (orginalperser)


Lesenswert?

Hallo an Alle,

ich programmiere momentan einen MSP430F1611 mit dem Compiler "Code 
Composer Essentials (Eclipse)". Ich möchte mit Interrupts arbeiten, was 
auch schonmal geklappt hatte, aber momentan bekomme ich immer einen 
_reset_vector(), wenn ich das Programm starten will.

Ich habe versucht, den Fehler einzugrenzen und habe festgestellt, dass 
das Programm am Ende der Initialisation hängen bleibt bzw. den 
Reset-Vektor auslöst.

Ich gebe euch erst mal ein Ausschnitt meines Codes:
1
//*************** Main - Teil **************************
2
3
int main(void) { 
4
  
5
  init();  // general clock configure (s.Initialisation.c)
6
  
7
8
//now we have finished the configuration, initialisation and can go
9
//into the main loop which runs forever and takes from time to time
10
//control over our application to supply menu navigation, lcd output and so on
11
12
//Main-Loop for ever:
13
////////////////////////MAIN LOOP://///////////////////////
14
15
P2DIR |= 0x82;  
16
P2OUT &= ~(0x02+0x80);  // Zu- unf Abluft aus ( P2.1 und P2.7 sind Magnetventile )
17
18
while(1) {  //Main program loop....
19
20
...



Die Funktion
1
init()
 sieht folgendermaßen aus:

1
void init(void) {  
2
  
3
long j=0;  
4
    
5
_BIC_SR(GIE);     // general interrupt disable to avoid strange errors
6
  
7
init_clock();     // Initialisation of general clock system
8
  
9
init_statusled();  // Initialisation of status led (An P1.0 angeschlossen)
10
  
11
ADCinit();     // AD-Wandler initialisieren
12
13
//enable interrupt for pacemaker pulses
14
 P1DIR &=  0xBF;   // Set P1.6 to input direction (10111111)
15
 P1IFG  =  0x00;   // P1.0 IFG cleared &=0x3F
16
 P1IE  |=  0x40;   // interrupt enabled 01000000
17
 P1IES |=  0x40;   // Interrupt bei fallender Flanke
18
19
initrs232();       // Initialisation of the USART port
20
  
21
// initialisation of speedcontrol
22
  speedcontrol[0] = 10;
23
  speedcontrol[1] = 1;
24
  speedcontrol[2] = 10;
25
  speedcontrol[3] = 1;
26
  
27
init_mstimer();    // Initialisation des TimerA0  
28
29
// Bis hier läuft das Programm !!!
30
    
31
_BIS_SR(GIE);      // Enable Interrupts  <-- Nach diesem Befehl kommt der 
32
                   // _reset_vector()
33
  
34
//Show by LED flashing, that initialisation has finished
35
  P1OUT = 0x01;
36
  for(j=0; j<1000000; j++);
37
  P1OUT = 0x00;
38
  for(j=0; j<1000000; j++);
39
}

...bis zum Blinken kommt es garnicht erst. Jedoch habe ich den MSP nach
1
init_mstimer();
 mal blinken lassen und das hat er auch gemacht. Demnach gehe ich davon 
aus, dass es an "General Interrupt Enable" liegt.

Nun bin ich nicht grad ein Experte in diesen Dingen. Ich möchte einfach 
nur wissen, warum dieser _reset_vector() auftritt und was er überhaupt 
zu bedeuten hat. In der Hilfe zum CodeComposer steht nichts darüber 
drin.

Könnte es evtl. daran liegen, dass ich die Interrupts der einzelnen 
Komponenten falsch aktiviere (z.B. ADC, Timer, ...)

Hier ein Beispiel, wie ich das mache:
1
ADC12IFG = 0x0000;        // Flagregistier löschen
2
ADC12IE = 0x0001;    // Interrupt, wenn ADC-Wert im Speicher... 
3
4
// Benutze hier ADC12MEM0, deshalb ADC12IE = 0x0001 ...

Vielen Dank schonmal im Vorraus
Armin

von Michael (Gast)


Lesenswert?

Hallo,

ich denke, dass du den Watchdog nicht deaktiviert hast, kann das sein?!

von Armin M. (orginalperser)


Lesenswert?

Michael wrote:
> Hallo,
>
> ich denke, dass du den Watchdog nicht deaktiviert hast, kann das sein?!


Den Watchdog-Timer habe ich in der Funktion "init_clock()" deaktiviert:
1
void init_clock() {
2
//This function is used to initialise the system
3
4
    WDTCTL  = WDTPW | WDTHOLD;              // Disable watchdog timer
5
6
    // Initialize basic clock system
7
8
...

von Christian R. (supachris)


Lesenswert?

Schieb den Watchdog mal ganz Anfang der main(). Eventuell kommt der gar 
nicht bis in die Funktion, bevor der Hund zubeißt.

von Armin M. (orginalperser)


Lesenswert?

Nochmal Hallo,

wirklich kein Experte unter euch, der mal mit einem "_reset_vector()" zu 
kämpfen hatte?

Vielleicht ist noch die folgende Info nützlich für euch:
Der Compiler basiert auf Eclipse und ist um einige TI-spezifische 
Plug-In's erweitert worden, speziell für den MSP430.
So wie ich das verstanden habe, ist Eclipse eine OpenSource-Geschichte.

Wenn man ein Programm compiliert und startet, so werden - je nach dem - 
ein oder mehrere Threads auf dem Prozessor gestartet. Einer dieser 
Threads endet bzw. bricht mit dem _reset_vector() ab.

Über den Threads steht etwas von Cygwin GDE und noch ein spezieller 
Fehler. Den hab ich leider momentan nicht im Kopf, weil ich nicht auf 
der Arbeit bin. Kann ich euch erst frühestens Dienstag sagen... Auf 
jeden Fall irgendwas mit STR...

Kann es sein, dass dieser Fehler was mit Cygwin zu tun hat, d.h. eine 
Fehlerausgabe von Cygwin?

Wie ihr seht, habe ich nicht wirklich viel Ahnung von den Dingen und 
würde mich über jede Hilfe sehr freuen...

Schönes Wochenende noch,
Armin

von Armin M. (orginalperser)


Lesenswert?

Hi Chris,

das werd ich mal ausprobieren, wobei das Programm bis zum Befehl
1
init_mstimer();
 normal ausgeführt wird.
Ich habe das so herausgefunden, indem ich den MSP nach jeder Funktion 
einmal blinken lassen hab.
Nach o.g. Funktion hat er noch geblinkt, aber nach der Funktion
1
_BIS_SR(GIE);
 blinkt er nicht mehr und der _reset_vector() erscheint bei den Threads.

Ich werde es dennoch mal ausprobieren. Vielen Dank für den Tipp!!!

von Christian R. (supachris)


Lesenswert?

Hallo,

wenn der Reset-Vektor erscheint, ist ein nicht difinierter Interrupt 
aufgerufen worden. Bist du sicher, dass du die Interrupt-Service-Routine 
richtig deklariert hast? Wenn auf dem Interrupt-Vektor keien gültige 
Adresse steht, schmiert der Prozessor beim Eintreffen des Interrupts ab.
Hast du denn die signal.h includiert?

von Armin M. (orginalperser)


Lesenswert?

Hi Chris,

die signal.h habe ich nicht includiert. Ich werde es mal ausprobieren.

Wie ich die ISR deklariert habe, kann ich dir leider nicht aus dem Kopf 
sagen. Wie gesagt, am Dienstag kann ich mehr dazu sagen. Ist gut 
möglich, dass ich dort einen Fehler gemacht habe, da ich nicht genau 
weiß, wie sowas gemacht wird.

Kann es sein, dass der Prozessor abschmiert, weil ich beim AD-Wandler 
unter ADC12CTL0 die Timer-Overflow-Flags nicht aktiviert habe, dieser 
aber trotzdem überläuft und somit dieser Fehler eintritt? Hab mal grad 
drüber nachgedacht. Das wäre doch ein nicht definierter Interrupt, oder?

Viele Grüße
Armin

von Christian R. (supachris)


Lesenswert?

Also wenn du mit dem GCC arbeitest, musst du die Signal.h reinmachen. 
Ich kann mir schon vorstellen, was passiert. Du hast den Code für IAR 
Compiler genommen, und die ISR -Deklaration nicht geändert. Der GCC 
kompiliert dann zwar fast alles, aber eben nicht die ISR, weil er die 
pragma Anweisung nicht versteht. Da kommt glaube nicht mal ein Fehler 
sondern nur eine Warnung. Der entsprechende Interrupt-Vektor ist dann 
leer, und der Prozzi sringt irgendwohin, eigenlich müsste er dann auf 
dem unexpected Vector landen, weiß aber nicht, wie gut das implementiert 
ist.

ISRs beim GCC: http://mspgcc.sourceforge.net/manual/x918.html

von Armin M. (orginalperser)


Lesenswert?

Hi Chris,

der Link, den du in deinem Beitrag angegeben hast, ist schon mal sehr 
nützlich! Vielen Dank nochmals!

Ich werde mich am Dienstag hinsetzten und alle deine Tipps mal 
ausprobieren. Werde dir das Ergebniss natürlich mitteilen.

Vielen Dank nochmals für deine Hilfe!
Melde mich dann am Dienstag wieder...

von Tilo S. (thesurfer)


Lesenswert?

Moin,

im ersten Post hast geschrieben, dass du mit dem CCE arbeitest, Chris 
arbeitet immer mit dem GCC und Eclipse. Der CCE hat zwar auch als GUI 
Eclipse benutzt aber den TI Compiler. Beim CCE ist es nicht notwendig 
die Signal.h zu includieren.

die Interruptroutinen werden beim CCE auch nicht wie in den 
Beispielcodes mit den #pragma definiert.

sondern z.B. wie folgt :

__interrupt void SD16ISR(void)
{
  if (SD16MEM0 < 0x7FFF)                 // SD16MEM0 > 0.3V?, clears IFG
    P1OUT &= ~0x20;
  else
    P1OUT |= 0x20;
}
SD16_ISR(SD16ISR)

von Christian R. (supachris)


Lesenswert?

Ahso, stimmt...ich hatte nur Eclipse gelesen und angenommen er hat GCC. 
Beim CCE ist das wieder anders.
Aber da müsste doch mal eine Warnung oder Fehlermeldung kommen? Naja, 
die list ja immer keiner.

von Armin M. (orginalperser)


Lesenswert?

Guten Abend,

da ich grad im Umzugsstress stecke, wird das morgen mit arbeiten nichts 
(so ein Mist ;-). Werde euch dann Mittwoch Meldung geben.

Wenn ich mir jedoch den Beitrag von Tilo anschaue, dann fällt es mir 
ungefähr wieder ein, wie ich die ISR deklariert & definiert hab, nämlich 
nahezu identisch:
1
__interrupt void ADC(void);
2
ADC12_ISR(ADC)
3
__interrupt void ADC(void){
4
5
// ... Routine
6
7
}

Der Code sollte in dieser Form korrekt sein.

Beim Compilieren gibt es übrigens keine Fehlermeldungen und auch keine 
Warnungen. Habe nämlich sehr genau auf die Console geachtet.

von Armin M. (orginalperser)


Lesenswert?

Hallo,

seit 12:30Uhr sitze ich nun an diesem Problem und habe es endlich 
geschafft, es zu lösen...

Kurz gesagt: An PortPin 1.6 ist ein Gerät angeschlossen, welches in 
regelmäßigen Abständen ein Signal ausgibt. Dieses Signal löst einen 
Interrupt aus und es wird eine "254" an den PC geschickt, der dann damit 
weiterarbeitet.

Jedesmal, wenn ich die 254 via U0TXBUF an den PC schickte, trat ein 
_reset_vector() auf. Seitdem ich im Register IE1 den Interrupt für 
UTXIE0 deaktiviert habe, funktioniert die Sache einwandfrei.

Komisch ist nur: Warum tritt dieser Fehler jetzt plötzlich auf? Warum 
nicht schon vorher, denn es hatte ja schonmal geklappt.

Und warum erscheint ein _reset_vector(), obwohl dieser Interrupt 
garnicht bearbeitet wird? Man muss doch nicht mit jedem Interruptflag 
arbeiten, oder sehe ich das Falsch?

Ich bin jedenfalls froh, dass es endlich bei mir klappt.

Wenn jemand von euch eine Erklärung hierfür hat, würde ich die gern 
wissen.

Ansonsten nochmals vielen Dank für eure Hilfe! Ihr habt mir echt 
weitergeholfen!

von Christian R. (supachris)


Lesenswert?

Ist der Interrupt aktiviert, aber keine ISR Sprungadresse auf dem 
Interrupt-Vektor, stürzt der µC ab, so einfach ist das.

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.