www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP 430 - Interrupt des Port 1 nutzen, aber wie?


Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin!

habe mir kuerzlich sampels des Microcontroller MSP430F437 zukommen
lassen. habe soweit auch alles aufgebaut und auf dem controller auch
ein einfaches programm laufen lassen.
nun wollte ich einen interrupt des port 1 nutzen. solbald dort eine
rising edge festgestellt wird sollen 2 pins des port 2 (die zu leucht
dioden fuehren) mittels interrupt handler auf high gesetzt werden.
mein code sieht wie folgt aus:

/*********************************************************************** 
******
*
     *
*                                    T E S T
     *
*
     *
************************************************************************ 
*****/


#include <msp430x43x.h>
#include <stdio.h>



void delay(void)
{
  int i;
  for(i=0; i<3000; i++);
}


int main(void)
{
  P2DIR |= 0xA2;   //Pin 7 + 5 + 1 of Port 2 = outputs;
  P2IE  |= 0x08;  //Interrupt for Pin 3 = enabled
  P2IES &= ~0x01;   //rising edge
  P2IFG &= 0x00;   //reset interrupt

  P2OUT &= 0x02;

  while (1)
  {
     delay();
  }

} //main-loop

// Port2 interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void key_pressed (void)

{
  P2OUT |= 0xA0;
  P2IFG &= 0x00;  //reset interrupt

}


Es passiert aber rein gar nichts! ist die initialisierung vielleicht
falsch?
fuer hilfe am besten mit code beispielen waere ich sehr dankbar!


johannes

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P2IES &= ~0x01;   //rising edge
  P2IFG &= 0x00;   //reset interrupt

  P2OUT &= 0x02;


Ich kenne den MSP nicht, aber in der Regel stehen Register nach dem
Reset auf 0x00, d.h. es ist witzlos etwas zu UNDieren.

0x00 UND irgendwas bleibt 0x00


Sauberer ist es aber, jede erste Registeroperation immer als Zuweisung
auszuführen, dann sind alle Bits definiert.


Peter

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter!

Du hast natuelrich recht! (habe den fehler komischer weise in dem prog
dass ich die ganze zeit auf dem MSP laufen lasse nich gemacht...)

vielen dank dafuer!


leider laeufts immer noch nicht. ich vermute dass ich den interruot
falsch initialisiert habe..


kann mir wer weiterhelfen?!


johann

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Johannes

Was ist denn das für eine Delay-Funktion? Der MSP430 hat Timer und
diverse Schlafmodi, womit man das eleganter lösen könnte. Natürlich,
für erste Schritte programmiert man schon mal sowas.
Hast du mal mit einem Debugger geprüft, ob alle Register richtig
gesetzt werden? Bei manchen Simulatoren/Debuggern kannst du Interrupts
auch von Hand auslösen. Vielleicht hilft dir das weiter.

FG

Tom2

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Johannes,

Das GIE Bit hast du nicht aktiviert oder siehe ich das falsch.

Gruß Jörn

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joern!

"Maskable interrupts are the lowest priority interrupts and can be
turned off individually with the various interrupt enable registers or
turned off as a group by setting the general interrupt enable bit (GIE)
in the status register (SR)."


Ich dachte, wenn ich das setze DISABLE ich die maskable Interrupts..
ich will sie ja nun aber aktivieren!

trotzdem: vielleicht sollte ich es mal ausprobieren, das zu setzen.
kannst du mir hierfuer beispiel code geben? ich weiss leider nicht wie
man das mit dem status reg macht!

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dürfte so ziemlich genau das sein, was du suchst ;)

Beispiel von TI HP:


#include <msp430x11x1.h>

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
  P1DIR |= 0x01;                        // Set P1.0 to output
direction
  P2IE |= 0x01;                         // P2.0 interrupt enabled
  P2IES |= 0x01;                        // P2.0 Hi/lo edge
  P2IFG &= ~0x01;                       // P2.0 IFG cleared

  _BIS_SR(LPM4_bits + GIE);             // Enter LPM4 w/interrupt
}

// Port 2 interrupt service routine
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
  P1OUT ^= 0x01;                        // P1.0 = toggle
  P2IFG &= ~0x01;                       // P2.0 IFG clearedf
}

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wahrscheinlich wird deine CPU immer durch den WD reset.

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auf "_BIS_SR(GIE);" bin ich auch schon gekommen, doch das led hat
immer geflackert. denke das ich das aber sauber und ordentlich
hinbekomme wenn ich den WDT disable ...

vielen dank!!

johannes

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Jörn hat schon recht, du musst die Interrupts erst mal global erlauben
(das geht mit de GIE-Bit, es heißt ja auch 'global interrupt
ENABLE'). Ist das auf 0, wird KEIN Interrupt ausgeführt.

In dem Befehl '_BIS_SR(LPM4_bits + GIE)' ist ebenfalls das Setzen
dieses Bits enthalten !

Und außerdem musst du, wie auch bereits erwähnt, den Watchdog
ausschalten, der hat mich bei der Entwicklung meiner Programme auch
schon einiges an Nerven gekostet, bis ich draufgekommen bin, dass der
alle paar Millisekunden einen Reset auslöst (ich war halt die Atmels
gewöhnt, wo er von Haus aus disabled ist) ...

Grüße, Mario

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hehe, kann gut nachvollziehen, was du meinst.
habe ueber den hitachi H8S programmieren gelernt. da muss man den auch
nicht extra disablen. was solls, nun weiss ich ja was los is :)


danke fuer eure hilfe!


johannes

Autor: tenner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tach,

wenn du einen interrupt an PORT 1 nutzen willst, solltest du auch den
interrupt für port 1 und nicht für port 2 konfigurieren.

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
  P2DIR = 0xA2;   //Pin 7 + 5 + 1 of Port 2 = outputs;
  P1IE  |= 0x08;  //Interrupt for Pin 3 = enabled
  P1IES &= ~0x01;   //rising edge
  P1IFG &= 0x00;   //reset interrupt

  P2OUT &= 0x02;

  eint();

  while (1)
  {
     delay();
  }

} //main-loop

// Port1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void key_pressed (void)

{
  P2OUT |= 0xA0;
  P1IFG &= 0x00;  //reset interrupt
}

code ist untesteted

Autor: Johannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ein argument! ;)
hab den mist mitlerweile schon zum laufen bekommen..
trotzdem danke !

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.