Forum: Mikrocontroller und Digitale Elektronik [MSP430] I2C Sendeinterrupt löst nach Timer Interrupt nicht aus


von Finn D. (fatgod)


Lesenswert?

Hallo,

ich schreibe grade für ein FH Projekt ein Programm, mit welchem ich mit 
meinem MSP430G2553 auf einen MPU6050 über I²C zugreife. Mein Transfer 
funktioniert soweit ich das beurteilen kann ganz gut. Ich kann Daten 
Empfangen, Register Manipulieren , Konfigurieren etc. NUR...

...wenn ich nun den Datenabruf aus meinem TIMER0_A0_VECTOR Interrupt 
starte, wird der USCIAB0TX_VECTOR völlig ignoriert und das Programm 
tickert munter weiter bis die UCTXSTP abgeprüft wird.

Gibt es da einen Grund warum der Timer Interrupt den Sendeinterrupt 
blockieren könnte? Ich habe schon versucht diesen Zurückzusetzen, 
auszuschalten etc.

Wäre cool wenn mir da jemand einen Tip geben könnte - es geht langsam 
auf die Klausuren zu ;)

Grüße
Finn

von mal sehen (Gast)


Lesenswert?

Finn Deschenk schrieb:
> Wäre cool wenn mir da jemand einen Tip geben könnte

Wäre cool, wenn du den laufenden und den verklemmten Code vollständig 
reinstellst.

von Finn D. (fatgod)


Lesenswert?

Den Code will ich zu diesem Zeitpunkt nicht hochladen, da er noch 
ziemliches Flickwerk ist.

Die Lösung war das rück- und erneute setzen der GIE:

// Port 1 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Port_1(void)
{
  __bic_SR_register(GIE);   // Das hier hats gebracht...

  P1OUT |= 0x01;
  TACCTL0 &= ~CCIE;     //keine Unterbrechung

  __bis_SR_register(GIE);   // ...und das war auch nötig

    XL = receiveGyro(MPU6050_RA_ACCEL_XOUT_L);
    XH = receiveGyro(MPU6050_RA_ACCEL_XOUT_H);
    XOUT = (XH<<8) | XL;

    P1OUT &= ~0x01;
    TACCTL0 |= CCIE;       //Timer Interrupt wieder setzen

}

von mal sehen (Gast)


Lesenswert?

Wie stellst du dir den Ablauf deines Programms vor? Aktuell scheint die 
Timer ISR eine blockierende Funktion aufzurufen:
Finn Deschenk schrieb:
> XL = receiveGyro(MPU6050_RA_ACCEL_XOUT_L);
>     XH = receiveGyro(MPU6050_RA_ACCEL_XOUT_H);
Die Daten sollen im Hintergrund per USCI ISR gelesen werden. Richtig 
soweit?

Das würde nur funktionieren, wenn ein USCI Interrupt die Timer ISR 
unterbrechen könnte. Also verschachtelte Interrupts. Dabei spielt die 
Interrupt-Priorität eine entscheidende Rolle, wenn der 
Interrupt-Controller verschachtelte Interrupts unterstützt. Der MSP430 
macht das nicht! Erst durch die erneute globale Interrupt-Freigabe wird 
die Timer ISR unterbrechbar, was aber für deine Aufgabenstellung nicht 
nötig ist. Und schon gar nicht mehrfach!

In der Timer ISR wird der Timer-Interrupt zwar disabled, aber der Timer 
läuft weiter, das Flag wird gesetzt und der Interrupt steht direkt nach 
dem Verlassen der Timer ISR wieder an. Das kann nicht dein Wunsch sein.

Finn Deschenk schrieb:
> Den Code will ich zu diesem Zeitpunkt nicht hochladen, da er noch
> ziemliches Flickwerk ist.
Das glaube ich dir gerne. :-(((

Du solltest in der Timer ISR die I2C Kommunikation nur anstoßen und die 
ISR wieder schnell verlassen. Das Ende der Kommunikation prüfst du in 
der USCI ISR oder in der main loop.

von Finn D. (fatgod)


Lesenswert?

Genau, die Daten werden dann in einer USCI ISR auf den Weg gebracht. Ich 
habe nach deinem Denkanstoß die Routine nochmal umgebaut, so dass ich 
jetzt in der Routine nurnoch die Freigabe erteile und den eigentlichen 
Transfer aus der main() starte. Funktioniert auch und ist sicherlich ein 
klein wenig sauberer.

Danke für deine ausführliche Antwort.

: Bearbeitet durch User
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.