mikrocontroller.net

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


Autor: reflection (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: reflection (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg S. (Gast)
Datum:

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

Autor: Jörg S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P2SEL &= 0xE0;
Was soll das bewirken?

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

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

Autor: szimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der MSP430F1xx hat keine internen Pull-Ups. Ein externer ist zwingend 
erforderlich.

Autor: reflection (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: reflection (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: reflection (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christian R. (supachris)
Datum:

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

Autor: reflection (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.