Forum: Mikrocontroller und Digitale Elektronik MSP430 Joystick an Port2, Interrupt will nicht.


von reflection (Gast)


Lesenswert?

Salu zusammen

Ich habe hier gerade wieder mal ein Prob mit dem MSP. Habe einen 
Minijoystick (wie er in Mobiltelefonen verbaut ist) an Port2 des 
MSP430F149 gehängt. Der Common des Joysticks liegt auf Masse, und die 
jeweiligen Kontakte am Port2.


             __________
            |
      /     |
  |--/   ---|P2.0
  |
 ---


Nun habe ich hier mal den Code. Vielleicht sieht ja jemand einen Fehler 
oder kann sagen das er OK ist. Weiss nicht wo ich noch suchen soll. Er 
springt einfach gar nie in den Interrupt rein.

   #include <msp430x14x.h>

   int push_state = 0;
   int menu_step = 0;

   interrupt (PORT2_VECTOR) P2_ISR(void)
    {
       DebounceDelay();

       if(P2IFG & 0x01)  // hat P2.0 den Interrupt ausgelöst?
       {
         push_state = 0;
         P2IFG &= ~0x01;  // Interrupt-Flag löschen
       }
       else if(P2IFG & 0x02)// hat P2.1 den Interrupt ausgelöst?
       {
           if(menu_step < 5)
           {
             menu_step += 1;
           }
           else
           {
             menu_step = 1;
           }
           P2IFG &= ~0x02;  // Interrupt-Flag löschen
       }
       else if(P2IFG & 0x04)// hat P2.2 den Interrupt ausgelöst?
       {
           if(menu_step > 1)
           {
           menu_step -= 1;
           }
           else
           {
           menu_step = 5;
           }
           P2IFG &= ~0x04;  // Interrupt-Flag löschen
         }
       else if(P2IFG & 0x08)// hat P2.3 den Interrupt ausgelöst?
       {
         //push_state = 3;
        P2IFG &= ~0x08;  // Interrupt-Flag löschen
       }
       else if(P2IFG & 0x10)// hat P2.4 den Interrupt ausgelöst?
       {
         //push_state = 4;
        P2IFG &= ~0x10;  // Interrupt-Flag löschen
       }
       else                // Falls mehrere Interrupts gleichzeitig 
auftreten
       {
         //push_state = 100;
         P2IFG &= 0x00;
       }
    }

   int main(void)
{
   P2SEL &= 0xE0;  // P2.0 - 2.4 als I/O konfigurieren
   P2DIR &= 0xE0;  // P2.0 - 2.4 als Input definieren / Joystick
   P2IES &= 0x1F;  // P2.0 - 2.4 neg. edge löst Interrupt aus
   //P2IES &= 0xE0;// P2.0 - 2.4 pos. edge löst Interrupt aus
   P2IE &= 0x1F;  // P2.0 - 2.4 kann Interrupt auslösen

}

void DebounceDelay(void)
{
  volatile unsigned int i;
  for(i = 50000; i > 0; i--);
}

Danke schonmal im Voraus fürs drüberschauen

Gruss und ein schönes Wochenende

reflection

von reflection (Gast)


Lesenswert?

Achja, signal.h ist natürlich includiert :o)

In der Initialisierung des UART habe ich dann noch das _EINT drin, die 
Interrupts sollten doch also laufen, oder muss ich das für Port2 noch 
irgendwie speziell angeben?

Gruss reflection

von Jörg S. (Gast)


Lesenswert?

Du legst den Pin also auf GND, aber gibt es denn auch einen Pull-Up?

von Jörg S. (Gast)


Lesenswert?

1
P2SEL &= 0xE0;
Was soll das bewirken?

Ich glaube du willst eher sowas:
1
P2SEL |= 0xE0;

Oder noch besser (für initialisierung):
1
P2SEL = 0xE0;

von szimmi (Gast)


Lesenswert?

Hiho,
also ich denke auch es hängt mit dem fehlenden Pull-Up zusammen. Schau 
Dir doch einmal im Debugger den Zustand von P2.0 an (gleich nach dem 
reset, ohne die Portinitialisierungen). Da muss das Bit 0 wackeln, wenn 
Du schließt bzw. öffnest.

von Christian R. (supachris)


Lesenswert?

Der MSP430F1xx hat keine internen Pull-Ups. Ein externer ist zwingend 
erforderlich.

von reflection (Gast)


Lesenswert?

Ouuuups, sorry das ich euch wegen so was belästige, hätte ich auch 
selber draufkommen können ditsch Dachte der hätte interne Pullups. Wie 
gross wählt ihr die? 47k oder soll ich grösser gehen?

Greets

von Jörg S. (Gast)


Lesenswert?

> Dachte der hätte interne Pullups.
Gibt es erst in der F2xx Serie

> 47k oder soll ich grösser gehen?
47k is OK. Es sei denn du hast eine ultra low Power Anwendung, dann 
vielleicht eher 100k.

von reflection (Gast)


Lesenswert?

Salu zusammen

Das mit dem Interrupt funktioniert nun. Das mit dem Menu geht auch so 
einigermassen :o)

Ich habe noch folgendes Prob. In der ISR verändere ich ja menu_step und 
push_state. Nun frage ich in der while(1) diese ab (Mittels 
switch/Case).
Das klappt auch und er zeigt mir das entsprechende Menu an. Wenn ich die 
Werte einmal aufs Display geschrieben habe bleiben sie stehen bis ich 
sie überschreibe oder aber ein clear_LCD mache. Das Prob ist, dass er 
manchmal die „alte“ Anzeige nicht komplett löscht, da ich kein clear_LCD 
in der While(1) machen kann (benötigt zu lange und fängt an zu 
flackern.) Habe nun das clear gemacht gleich wenn ich in die ISR 
reinspringe. Wenn ich reinspringe will ich ja ein anderes Menu anzeigen 
und lösche darum schon mal alles. Wenn ich das so löse klappt es von 
10mal ca. 8-9mal, 1-2Mal hat er das Prob das er das Display nicht 
löscht. Habe mir nun überlegt woher es kommt und bin auf folgendes 
gestossen:
Ich bin z.B. gerade in der Ausgabe auf das Display wenn der ISR kommt. 
Nun wird das Display gelöscht, der menu_step erhöht und er springt 
wieder aus der ISR raus ins Hauptprogramm. Da ich aber dort genau in der 
Ausgabe hänge schreibt er natürlich noch einmal die alten Werte aufs 
Display und wertet erst in einem erneuten Durchlauf den menu_step aus. 
Somit sind dann noch die alten Daten auf dem Display und werden vor 
Anzeige der neuen Werte nicht mehr gelöscht. Wenn die neuen Werte nun 
kürzer sind als die alten stehen halt noch Zeichen da die dort 
eigetnlich nicht hingehören. Hat vielleicht jemadn eine Lösung für das 
Problem? Wie gesagt, ich kann nicht bei jedem Durchlauf die Anzeige 
löschen, da das Display dafür wohl einfach zu langsam ist.

Wäre über ein paar Anregungen dankbar

Gruss reflection

von reflection (Gast)


Lesenswert?

Ich habe nun einfach _DINT gemacht während der Ausgabe auf dem Display 
und danach wieder _EINT. Somit bin ich sicher das der Interrupt nicht 
genau dann kommt wenn ich das Menu aufs LCD schreibe. Ist dieser Weg der 
richtige? Irgendwie weiss ich nicht ob ich das so machen soll oder ob es 
eine elegantere Lösung gibt.

Gruss reflection

von Christian R. (supachris)


Lesenswert?

Frag doch die Tasten in einem Timer-Interupt z.b. alle 20ms ab.

von reflection (Gast)


Lesenswert?

Ok, das könnte ich machen, muss ich mich mal mit Timern beschäftigen. 
Habe mir vor einiger Zeit mal das orangene Buch zum MSP430 gekauft. Ist 
echt gut das Ding, kann ich also nur empfehlen. Werde mich mal schlau 
machen wie ich das anstellen kann, gibt sicher ne Beschreibung welcher 
Mode geeignet ist.

Gruss reflection

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.