Forum: Mikrocontroller und Digitale Elektronik msp430 irq problem


von michael m (Gast)


Lesenswert?

hi,

an meinem msp430x149 sind unter anderem 4 taster, von denen ich einen
verwenden möchte, um mittels interrupt in ein menüsystem zu kommen.
die taster befinden sich an port1 und werden low-aktiv eingesetzt,
indem sie die pins p1.4-p1.7, die über einen 4.7k widerstand an vcc
hängen, auf gnd ziehen...das funktioniert soweit auch alles einwandfrei
und ist schon eine weile im einsatz.

jetzt habe ich folgendes problem:
sobald beim initialisieren nach dem setzen des GIE bits auch das dem
menü-taster entsprechende bit bei P1IE gesetzt ist, verabschiedet sich
der controller sofort sang- und klanglos, wenn die schalter
angeschlossen sind, der wert von P1IES spielt dabei keine rolle. die
irq service routine wird auch nicht aufgerufen (soll sie ja zu dem
zeitpunkt auch noch nicht werden, es wurde ja noch kein taster
gedrückt). ich bin langsam echt ratlos. selbst 6 zeilen code bringen so
das teil zum abschmieren. habe ich was vergessen? soweit ich weiss
müsste das was ich getan habe reichen, und die schalter funktionieren
im "normalen leben" ja auch und werden mit der gleichen spannung wie
der µc betrieben...bei einem zweiten msp tritt das gleiche problem
auf...

in grösser verzweiflung
michael

von OldBug (Gast)


Lesenswert?

Hänge mal zumindest einen Teil Sourcecode an.
Dann wird Dir bestimmt jemand helfen können...sonst ists halt nur
raterei...

von michael m (Gast)


Lesenswert?

ich habe im folgenden mal die wesentlichen teile angehängt, die zum
abstürzen lassen vollkommen ausreichen...nicht aufgelistet ist die
routine zur initialisierung des lcds und die variablendeklaration, aber
die spielen eigentlich keine rolle...
das 4x20er lcd fährt mit 2 schwarzen zeilen hoch, nach der
initialisierung ist es klar... das passiert aber nicht, da er eben
vorher stoppt... debuggen zeigt, dass er nach P1IE setzen hängt - ohne
GIE oder P1IE läuft das programm einwandfrei, die isr sollte ja
eigentlich auch nicht besucht werden, da noch kein interrupt auftritt
bei der initialisierung.

// interrupt service routines

#pragma interrupt_handler port1_isr:PORT1_VECTOR
void port1_isr(void){
  if (P1IFG&0x20){    // check if flag set (p1.5)
    menu=1;
    P1IE&=~0x20;    // disable irqs (p1.5)
    P1IFG&=~0x20;    // reset flag (p1.5)
  }
}

// main program

int main(void){
  WDTCTL = WDTPW + WDTHOLD;  // watchdog off
  _BIS_SR(GIE);      // general interrupt enable

  P1DIR=0x02;      // srf04 echo pulse (p1.0, in), trigger pulse (p1.1,
out); 4 switches (p1.4-p1.7, in)
  P1SEL=0x00;      // gpio
  P1IE=0x20;      // enable irqs (p1.5)
  P1IES=0x20;      // irq on falling edge (p1.5)

  init_lcd();

  [...]

von Sebastian (Gast)


Lesenswert?

Du resettest INNERHALB der ISR das PIE-Bit. Das ist IMHO falsch. Welchen
Sinn soll das denn auch haben?

von OldBug (Gast)


Lesenswert?

Ohje, noch ne Variante:

>#pragma interrupt_handler port1_isr:PORT1_VECTOR
>void port1_isr(void){

Leider weis ich nicht, wie man diese #pragma-Zeile richtig aufbaut,
aber könnte es sein, daß Du Vektor und zugehörige Funktion
vertauschst?

Ich verweise immer auf die Makros aus der signal.h:

#include <signal.h>

interrupt[PORT1_VECTOR] void Port1_Interrupt (void)
{
    /* something */
}

für IAR, oder für gcc:

#include <signal.h>

interrupt(PORT1_VECTOR) void Port1_Interrupt (void)
{
    /* something */
}

von Sebastian (Gast)


Lesenswert?

Stimmt, die Notation ist mir auch neu.

@michael: Welchen Compiler benutzt du? Und welche IDE?

von michael m (Gast)


Lesenswert?

> Du resettest INNERHALB der ISR das PIE-Bit. Das ist IMHO falsch.
> Welchen Sinn soll das denn auch haben?
der geht danach ins menü und soll keine weitern irqs auslösen. ich gebs
ja zu, das könnte man auch an den anfang des menü codes hängen. die
einzelnen unterroutinen loopen alle mit while(!menu). ich werde das
noch ändern. bei fast leerer isr ist das problem aber nach wie vor das
gleiche.

> Leider weis ich nicht, wie man diese #pragma-Zeile richtig aufbaut,
> aber könnte es sein, daß Du Vektor und zugehörige Funktion
> vertauschst?
also die notation ist die gleiche wie in der c't, die mich (wie wohl
manchen auch) zum msp430 geführt hat, und ich hatte bei timer- oder
sonstigen isr's auch nie probleme sondern habe mich eben an diese
schreibweise gewöhnt - den compiler scheint es auch nicht weiter zu
stören. es handelt sich übrigens um den mspgcc, deshalb glaube ich
nicht, dass es ein compilerfehler ist...(semi-)grafische umgebungen
nutze ich keine...ich kann aber gerne mal eine andere routinen notation
verwenden. was mich wirklich stutzig macht ist eben die tatsache, dass
mit abgezogenen tastern keinerlei probleme auftreten...

danke euch schonmal für die antworten bisher :)

von OldBug (Gast)


Lesenswert?

Aha... Das hätte ich jetzt nicht erwartet... :)
Hast Du mal die von mir vorgeschlagene Notation probiert?
So stehts jedenfalls im Manual...

von OldBug (Gast)


Lesenswert?

_BIS_SR(GIE) ist auch nicht gerade schön, eint(); und dint(); sehen doch
viel netter aus, dann noch sachen wie:

>P1IE=0x20;      // enable irqs (p1.5)

in

P1IE = (1 << BIT5);      // enable irqs (p1.5)

ändern und schon kann man das auch lesen :-)

von OldBug (Gast)


Lesenswert?

Jetzt werf ich das auch noch durcheinander!

P1IE = BIT5;

Muss das heissen!
Wenn Du noch andere Pinne dazu nehmen möchtest:

P1IE = BIT0 | BIT2 | BIT5;

Aktiviert die Interrupts für P1.0, P1.3 und P1.5...

von Sebastian (Gast)


Lesenswert?

Najaaa, man muss es ja nicht übertreiben. Diese Notation

P1IE=0x20;

finde ich völlig ok (und benutze sie auch selber), denn so schwer ist
das hexadezimale System nun auch wieder nicht. ;-)

@michael: Welche Hardware hast du denn? Olimex? Ein Hardware-Defekt ist
ja auch immer mal denkbar ...

von OldBug (Gast)


Lesenswert?

Ich wollte ja nur den Hinweis geben, daß man das so besser lesen kann
;)
Es geht natürlich noch lesbarer, und es gibt auch immer jemand, ders
noch besser kann. DIese "magic numbers" sind aber schon sehr
"verpöhnt"...

 :-)

von michael m (Gast)


Lesenswert?

also ich weiss ja nicht was manche gegen hexadezimale schreibweise
haben, schliesslich adressiert man ja immer 8bit, da ist das doch
naheliegender :) und den gigantischen zahlenraum von 4 bit pro stelle
kann man glaub ich noch überblicken, ich bin da ganz sebastians meinung
:) bei den ports kann man das wohl auch bringen, für normale flags nehme
ich aber auf jeden fall die defines...

> @michael: Welche Hardware hast du denn? Olimex? Ein Hardware-Defekt
> ist ja auch immer mal denkbar ...
ja, ein olimex. ich habe aber (siehe allererstes posting) schon einen
anderen getestet, wäre froh wenns nur das wäre :/

ich probier morgen nochmal rum, der ganze kram steht im moment an der
uni :)

von michael m (Gast)


Lesenswert?

ich kam jetzt endlich mal zum testen...die variante mit signal.h hat
funktioniert, auch wenn bei
> interrupt(PORT1_VECTOR) void Port1_Interrupt (void)
> {
>    /* something */
> }
das eine void zuviel war :)

danke an alle die sich die mühe gemacht hatten. aus irgend welchen
gründen hatte der wohl die irq-routine nicht richtig erstellt. ebenso
unklar ist, warum er nach aktivieren der irqs sofort die routine
aufrufen will (das macht er jetzt immer noch, deshalb ist damals auch
alles abgeschmiert), ich denke das ist architekturbedingt :/
egal. es läuft :)

von OldBug (Gast)


Lesenswert?

Wo ist denn da ein "void" zu viel?

von OldBug (Gast)


Lesenswert?

Ahja, jetzt hab ichs auch gerochen ;-)
Das erste "void" ist zu viel, kommt wohl vom C&P...

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.