Datum: 02.05.2008 18:56
Hallo,
ich frage per MSP430F2013 I2C-Bausteine ab. Dazu nehme ich die USI.
Abgeleitet habe ich die Functionen von msp430x20x3_usi_08.c. Es läuft
alles bestens.
Jetzt können jedoch durch irgendwelche Störungen hänger auftauchen. Die
interessante Stelle habe ich hier.
//I2C ausführen lassen
USICTL1 |= USIIFG; // Set flag and start communication
LPM0; // CPU off, await USI interrupt
_NOP(); // Used for IAR
Danach wird die Interruptroutine aufgerufen.
/******************************************************
// USI interrupt service routine
******************************************************/
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX (void)
{
switch(__even_in_range(I2C_State,10))
{
.....
}
}
Frage: Mit LPM0 wird wohl auf den Interupt gewartet. Wird nach
Ausführung des USI interrupts wieder ein Rücksprung zu LPM0 durchgeführt
und _NOP() ausgeführt?
Würde das denn Funktionieren?
WDTCTL = WDT_ARST_1000 // Set Watchdog 1000ms; reset after expired
time
IE1 |= WDTIE; // Enable WDT interrupt
//I2C ausführen lassen
USICTL1 |= USIIFG; // Set flag and start communication
LPM0; // CPU off, await USI interrupt
_NOP(); // Used for IAR
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
Gruss Klaus.
Datum: 03.05.2008 12:11
> Frage: Mit LPM0 wird wohl auf den Interupt gewartet. Wird nach > Ausführung des USI interrupts wieder ein Rücksprung zu LPM0 durchgeführt > und _NOP() ausgeführt? Meiner Meinung nach wird _NOP() nie ausgeführt.
Datum: 03.05.2008 13:16
LPM0 schaltet die CPU ab.(siehe User`s Guide...) Der Mikrocontroller reagiert nur noch auf Interrupts. Solange du keinen Befehl wie LPM_EXIT o.ä. in deiner ISR hast, wird immer wieder in den Stromsparmodus zurückgekehrt. (und damit auch die Befehle nach LPM0; nie ausgeführt)
Datum: 03.05.2008 16:12
Hallo Martin, in der Interruptroutine ist ein "LPM0_EXIT;" vorhanden. Wie gesagt, das I2C Senden/Empfangen läuft sehr gut. Ich möchte nur Fehlersituationen abfangen. Meine Frage ging auch dahin ob es so üblich ist den Watchdog so einzusetzen. WDTCTL = WDT_ARST_1000 // Set Watchdog 1000ms; reset after expired time IE1 |= WDTIE; // Enable WDT interrupt //--------------------- //I2C ausführen lassen USICTL1 |= USIIFG; // Set flag and start communication LPM0; // CPU off, await USI interrupt //Ausführung der Interruptroutine und Rückkehr _NOP(); // Used for IAR //-------------------- WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer Weitere Frage: die Zeile " LPM0; " ist doch sicher so etwas wie ein Funktionsaufruf der Interruptroutine an dem wie bei einem normalen Funktionsaufruf wieder zurückgekehrt wird? Gruss Klaus.
Datum: 03.05.2008 16:39
LPM0 ist eigentlich nur ein #define. Dahinter stecken glaub ich nur ein paar Assemblerbefehle die lediglich die nötigen Bits im Statusregister setzen. Schau mal in das zugehörige Headerfile, da steht das #define drin. LPM0 ruft nicht die Interruptroutine auf, es setzt lediglich die nötigen Bits um die CPU anzuhalten. Der Programcounter zeigt auf den nächsten Befehl nach LPM0. Tritt ein Interrupt (asynchron!) auf, wird das Statusregister, und Program Counter etc. auf den Stack gelegt, und dann die ISR ausgeführt. Nach der Ausführung wird das alte Statusregister wieder hergestellt, in welchem die Bits so gesetzt sind, dass die CPU wieder abgeschaltet wird. Das LPM_EXIT ändert im übrigen die Bits des Statusregister auf dem STACK, so dass nach dem Wiederherstellen die Bits so gesetzt sind, dass die CPU wieder läuft und der nächste Befehl im Program Counter ausgeführt wird. Hoffe das war jetzt nicht so verwirrend. Den Watchdog kannst du natürlich so benutzen, was ist schon üblich :) Du könntest natürlich auch einfach einen normalen Timer benutzen und den MSP nach einer Sekunde, mit einem LPM_EXIT in dessen ISR, aufwecken. Dabei kannst du mit einer globalen Variable o.ä. anzeigen, aus welcher ISR du geweckt wurdest, also ob I2C ok, oder "Timeout"...
Datum: 04.05.2008 13:33
Hallo Martin, Deine Erklärungen waren hilfreich und hat mir schon weitergeholfen. Gruss Klaus.
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
- Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel