== kurzes Hallo ==
Hallo Leute,
ich bin im Moment dabei mich wegen meiner Bachelorarbeit in das Thema
der µC Programmierung einzuarbeiten. Bei der Suche nach Hilfe hat google
mich des öfteren auf diese Seite geführt, die mir stellenweise gut
geholfen hat.
Ich dachte mir ich gebe was zurück, auch wenn das mit meinen Kentnissen
natürlich auf einem total niedriegen level ist :P
Nachdem ich irgendwann die Begriffe Interrupts und Timer mit Inhalt
füllen konnte habe ich eine "sleep(time)" Funktion implementiert, die
ich gerne weitergeben würde, falls mal wieder jemand wie ich neu ist und
sowas leicht und schnell implementieren will (geht alles geschickter
nehme ich an, Infos willkommen).
Vermutlihc programmieren erfahrene Leute das in 3 Minuten, aber ich vlt
ist es ja mal für jemanden hilfreich :)
Ich versuche übermäßig detailiiert zu erklären, dass ist etwas worüber
ich mcih beim lesen immer gefreut habe^^
== Der Delay Timer =
Die Software die ich programmiere liest Temperatur- und Druckwerte aus
einem Sensor aus. Dafür brauch ich regelmäßig Wartezeiten (zB um dem
Sensor Zeit zum Messen zu lassen). Habe ich anfangs alles über
__delay_cycles(xxxx) gelöst. Funktionierte, allerdings setzt diese Art
des Delays den Prozessor für xxxx Takte unter Vollast. Für
Batteriegeräte nicht der Hammer.
Ich brauchte also eine Möglichkeit, variable Pausen zu generieren, die
wenig oder keine Energie verbrauchen. Der hier gezeigte Delay schickt
den µC in einen Low Power Mode und weckt ihn nach X ms wieder auf. Das
ist sehr viel sparsamer und kann auch von Variablen gefüttert werden,
was beim __delay_cycles nicht der Fall ist.
Mein µC ist ein F5529.
Alles was ihr bruacht ist das hier:
== Aufbau und Verwendung ==
Der dargestellt Delay enthält 3 Dinge:
* Eine Initialisierungs-Funktion, die die erforderlichen Register so
setzt, dass der Timer seine Funktion erfüllen kann.
* Eine Funktion die später verwendet wird um den Timer zu setzen.
* Ein Interrupt
Um den delay zu verwenden reicht folgendes aus (hier wird einfach eine
LED blinken gelassen mit Unterschiedlichen Zeiten):
Packt das oben Dargestellte in eure C Datei.
Dann könnt ihr in der main() function eine Pause mit sleep(t) aufrufen.
NOTE: sleep(1000) ist nicht exakt eine Sekunde, sondern ein kleines
bisschen weniger (ca 0,98s)
Hallo Lars,
Ansich sieht der Code gut aus und wird sicher anderen Leuten helfen bzw.
Anregungen geben.
Ich persönlich würde zuerst TACCR0 Register setzen und dann den Timer
starten. Sonst könnten ggf. unerwünschte Sideeffekts auftreten (In
diesem Fall sicherlich nicht, aber man sollte das immer im Hinterkopf
behalten ;)).
Ausschnitt aus einem Userguide des MSP430:
It is recommended to stop the timer before modifying its operation (with
exception of the interrupt enable, interrupt flag, and TBCLR) to avoid
errant operating conditions.
Hi Watsche,
Prinzipiell möglich.
Aber für diese Anwendug suboptimal, da der WDT beim MPS430 nur bestimmte
Intervalle zulässt, die abhängig vom Clocksource sind. Somit wären die
Delays nicht frei wählbar.
MfG
Felix
Hää? Jeder Timer hat nur bestimmte Auflösungen. Das gilt für Timer A, B
und auch den WDT. Wer keinen Watchdog braucht, kann für das delay den
WDT nutzen u d den Timer für wichtige Gere Dinge nutzen.
Ich sehe beim WDT nur das Controllregister, mit dem vorbestimmte
Intervalle eingestellt werden können. Damit kann man den WDT nicht
wirklich einsetzen.
Da je nach Derivat der MSP430 recht gut bestückt ist(Anzahl der Timern),
nehme ich lieber ein Timer und Stelle im ms-Bereich mein Delay, als
einen WDT der nur 1,95ms , 15,625ms, 250ms, 1s ... kann ;)
Wenn natürlich das geforderte Delay zufällig damit möglich ist okay.
Den WDT zu benutzen ist vielleicht gar keine so schlechte Idee. Weiß
grade nicht wie das im LPM3 damit aussieht, kann mir vorstellen dass der
dann abgeschaltet ist, sonst wäre warten im LPM3 ja nie möglich ohne
Reset?!
WDT ist in LPMx nicht abgeschaltet. Beachtet werden muss nur, dass die
Clocksource aktiv bleibt und somit bspw. mit ACLK(LFXT1) trotz
LPM4-Befehl der LFXT1 weiterläuft und somit der Stromverbrauch
wesentlich höher wäre.
Falls du ihn für deine Zwecke verwenden möchtest, wird der PUC eh
deaktiviert und du bekommst nur einen Interrupt, der das Device wieder
aufweckt.
Ich habe jetzt, ein halbes Jahr später, bemerkt, dass es einen Fehler im
obigen Code gibt^^. Der Timer wird nämlich nicht gestoppt. Das fällt
auf, wenn man etwas im Stil von
1
P4OUT^=BIT7;
2
sleep(100);
3
__bis_SR_register(LPM0_bits+GIE);// Warten bis foo
programmiert. Die LED binkt rapide, weil der timer nach Ablauf von 100
Takten weiter läuft, und nach weiteren 100 Takten den nächsten LPM
Modus, welcher erst durch ein Event hätte verlassen werden sollen,
verlässt.
Ich habe .c und .h Datei für die aktuelle Version angehängt (kann den OP
leider nicht mehr ändern)