Hallo, hab ein kleines Problem, stecke noch nicht so in der Materie: Arbeite mit dem MSP430. Und wenn ich das richtig verstanden habe, läuft ein Timer immer und ewig, nachdem man ihn initialisiert hat, oder? Ich möchte nun aber, dass dieser Timer nur 1x hochläuft. Wie kann ich den Timer wieder auf 0 setzen oder ganz deinitialisieren? Wäre schön, wenn jemand was weiß. Gruß Der Anfänger...
Leider klappt es mit dem Zurücksetzen nicht so richtig. Muss wohl mein Problem genauer darstellen: In meinem Programm wird eine Funktion durch einen Interrupt am Port2 aufgerufen. In dieser Funktion wird ein Timer inintialisiert und der Port3 auf 1 gesetzt. Nach einer gewissen Zeit soll dieser Port wieder auf 0 gesetzt werden. Dies soll aber nur 1x passieren. Deshalb soll der Timer zurückgesetzt werden. Nur zur Info: in der Zwischenzeit erreichen weitere Interrupts den Port2. Die Initialisierung meines Timers in der aufgerufenen Funktion "Funktion" sieht so aus: void Funktion(void) { TBCTL = TBSSEL1 + TBCLR; TBCCTL0 = CCIE; TBCCR0 = 10000; TBCTL |= TBSSEL_2 + MC_2 + TBIE; _BIS_SR(LPM0_bits + GIE); P3OUT = 0x01; //Port auf 1 setzen } Der Interrupt, in dem der Timer und der Port zurückgesetzt werden sollen, sieht so aus: __interrupt void TIMER_B(void) { P3OUT = 0x00; TBCTL = 0; } Hab das Gefühl, das der Controller in Zeile, in der der Port3 auf 1 gesetzt wird, hängen bleibt. Hätte jmd 'ne Idee?
>Hab das Gefühl, das der Controller in Zeile, in der der Port3 auf 1 >gesetzt wird, hängen bleibt. Was soll er denn sonst machen? Du schickst ihn ja schlafen:
1 | _BIS_SR(LPM0_bits + GIE); |
Vermutlich kommen Deine Port2-IRQ's noch bevor TimerB ablaufen kann (also 10000 erreicht). Dann erweckt der P2-IRQ Deinen MSP wieder kurz zu leben, springt in "Funktion" und setzt P3OUT = 0x01 ! Sieht auch verdammt nach rekursiven Funktionsaufrufen aus, denn der P2-IRQ springt ja wieder und wieder in "Funktion"...
Was genau macht der Befehl _BIS_SR(LPM0_bits + GIE); denn eigentlich? Ich hab die Befehle von der TI-Seite. Leider steht da selten wofür die einzelnen Befehle sind. Soll ich den Befehl denn ganz weglassen? Wie sollte ich das ganze denn anders aufbauen? Du hast recht, der P2-IRQ kommt in der Zeit, wo der Timer abläuft. Stellt das ein Problem dar?
@ Sebastian S. (harryporter1980) >Was genau macht der Befehl >_BIS_SR(LPM0_bits + GIE); >denn eigentlich? Ich hab die Befehle von der TI-Seite. Leider steht da Die Frage kommt ein wenig spät ;-) >selten wofür die einzelnen Befehle sind. Soll ich den Befehl denn ganz >weglassen? Kommt drauf an was du machen willst. Der Befehl schaltet die Interrupts global ein (GIE) und versetzt die CPU in den LPM0, Low Power Mode 0. Dabei wird die CPU angehalten. Sie wacht nur auf wenn ein Interrupt ausgelöst wird, führt den aus und legt sich am Ende des Interrupts wieder schlafen. Das Hauptprogramm bleibt dabei stehen. MFG Falk
>Ich hab die Befehle von der TI-Seite. Leider steht da >selten wofür die einzelnen Befehle sind. Dafür gibt's ja die MSP-User-Guides bzw. die User-Guides der IAR-Entwicklungsumgebung, die dich darüber umfassend informieren. Ich gebe zu, ist am Anfang etwas viel zu lesen... aber es ist noch kein Meister vom Himmel gefallen... da musst Du halt durch, wie alle anderen auch ;-) >Soll ich den Befehl denn ganz weglassen? S.oben! Durch planloses rumprobieren entsteht nur in den seltensten Fällen ein lauffähiges Programm!!! Ohne nähere Informationen, was Dein Programm genau machen soll, ist weitere Hilfe unmöglich. Nur ein genereller Hinweis:
1 | _BIS_SR(LPM0_bits + GIE); |
birgt gleich zwei Gefahren in sich: 1.) Den globalen IRQ (GIE) innerhalb einer ISR wieder frei zu geben, sollte man möglichst vermeiden. Führt oft zu unvorhersagbarem Verhalten! 2.) Den Sleep-Modus innerhalb einer ISR zu aktivieren ist nicht der richtige Weg! Die ISR kann nie beendet werden und jeder neue IRQ ruft eine "neue" ISR auf, die wiederum nicht beendet werden kann. D.h. früher oder später wird dir der Stack überlaufen. Besser wäre es, in Deiner ISR lediglich Status-Flags zu setzen, und diese in Deinem main-Programm auszuwerten und dort den LPM zu setzen. Oder Du verwendest zumindest
1 | _BIS_SR_IRQ(LPM0_bits); |
damit LPM0 erst aktiviert wird, nachdem die ISR abgearbeitet wurde! >Wie sollte ich das ganze denn anders aufbauen? Du hast recht, der P2-IRQ >kommt in der Zeit, wo der Timer abläuft. Stellt das ein Problem dar? Offensichtlich schon, denn jeder P2-IRQ setzt Deinen Timer_B zurück, bevor dieser den gewünschten CCR0-IRQ aulösen kann! Vielleicht solltest Du darüber nachdenken, den P2-IRQ nach dessen erstem Auftreten wieder zu sperren, damit er Dir nicht mehr in die Quere kommt. Nachdem Dein Timer dann gefeuert hat, kannst Du u.U. den P2-IRQ wieder zulassen, falls für Dein Programm notwendig ?!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.