Forum: Mikrocontroller und Digitale Elektronik MSP430 ADC "Anfängerfrage"


von Christian M. (charlie)


Lesenswert?

Hallo zusammen!

seit heute Mittag bin ich stolzer Besitzer eines MSP430F2410 + U64 dev. 
board. Nachdem ich mich erfolgreich mit dem Komparator und UART 
rumgeschlagen hab, wollte ich den ADC12 testen, aber irgendwie komme ich 
gerade nicht weiter.

Ich benutze ansonsten externe AD-Wandler, dort sampelt der einfach 
fröhlich vor sich hin und ich lese dann die 8/12Bits vom Port aus. Es 
ist egal, ob ich das ein oder andere Byte verpasse.

Das möchte ich auch so mit dem MSP430 versuchen. Also der AD-Wandler 
soll permanent im Hintergrund laufen und ich möchte dann aus dem 
ADC12MEM lesen, wann ich auch immer an die entsrechende Stelle am 
Programmcode komme. Wichtig ist, dass die Daten schon verfügbar sind, 
wenn ich lesen will, also der Samplevorgang soll nicht gestartet werden, 
dann warten und dann erst lesen und das ganze von vorn. Genau dies 
möchte ich vermeiden.

Ich stelle es mir nicht so schwierig vor, aber irgendwie komme ich grad 
nicht drauf. Kann mir einer einen Tipp geben?

Danke!

Christian

von MSP-Fan (Gast)


Lesenswert?

> Also der AD-Wandler soll permanent im Hintergrund laufen

Das macht zwar wenig Sinn, wird aber unterstützt.
Steht im User Guide unter: Repeat-Single-Channel Mode.

Da das ganze nicht mit dem Hauptroutine synchronisiert ist,
wirst Du mit rechnen müssen, das Werte durch neue Wandlungen
überschrieben sind, bevor sie abgeholt werden.


"Richtig" macht man das MSP430 etwa so:
- Timer benutzen, der die ADC-Wandlung triggert.
- Im ADC-Interrupt den Wert abholen und den Low-Power-Mode beim
  Verlassen ausschalten
- Im Hauptprogramm mit dem Wert irgendetwas anstellen.
- MSP430 wieder schlafen legen.

Aber mach ruhig.

von Christian M. (charlie)


Lesenswert?

> Da das ganze nicht mit dem Hauptroutine synchronisiert ist,
> wirst Du mit rechnen müssen, das Werte durch neue Wandlungen
> überschrieben sind, bevor sie abgeholt werden.

das macht in meinem Fall nichts, ich brauche nicht unbedingt alle Werte. 
Wichtig ist nur, dass ich immer sofort welche habe, und nicht durch 
unnützes warten Zeit verschwende. Also sowas hier:
1
while ((ADC12IFG & BIT0)==0);
 will und muss ich möglichst vermeiden.

Bei Interrupt bin ich mir nicht sicher, bis er auf das Beenden der ISR 
wartet und dann erst weitersampelt. Es kommt mir zumindest so vor. Dort 
habe ich schon ein "endlos-sampeln" hinbekommen. Ansonsten wäre es 
natürlich DIE Lösung. Aber bin mir nicht sicher.

Es handelt sich (wenns denn mal fertig ist) grob gesagt um einen 
Datenrecorder für Sensorwerte. Der soll ja auch nicht andauernd sampeln, 
sondern nur wenn irgendwas besonderes passiert (Schwellwert 
überschritten oder sonst was). Ansonsten ist der im LPM.

Während des sampelns darf der sowieso auch nicht wieder zurück in den 
LPM, da gehen mir immer Wertvolle µs verloren bis der wieder aufgewacht 
ist... Jetzt wo ich das schreib bemerk ich, dass ich den immer wieder in 
schlaf geschickt hab... vergessen die Flags zu löschen.. ok.

Aber vielleicht hat noch jemand eine idee wie man das "besser" 
hinbekommen könnte, also ohne zu warten.


> Aber mach ruhig.
trotzdem Danke.


Viele Grüße
Christian

von MSP-Fan (Gast)


Lesenswert?

Das IFG beim Register ADC12IFG steht für Interruptflag :-)

Nicht das man es nicht pollen dürfte, es macht halt wenig Sinn.

> while ((ADC12IFG & BIT0)==0);

Im ADC12MEM wird immer der Wert der letzten Umsetzung stehen.
Egal ob das IFG gesetzt oder nicht.

von Christian M. (charlie)


Lesenswert?

ja, hab ich grad aus einem TI Beispielcode raus. Kam mir zuerst auch 
sehr merkwürdig vor. Aber das klappt so schon, zumindest für einmalige 
Samplings. Bei Dauersampling macht das kein Sinn, da hast du natürlich 
Recht.

Ich denke ich werde es erstmal weiterhin mit der Interruptmethode 
versuchen, also wie ich es zuerst angefangen hab und du es grob in 
Punkte gefasst hast. Dass ich die Flags für den LPM nicht gelöscht hab 
erklärt den Zeitverlust. Dass ich das nicht gesehen hab...
Und alles andere sieht einfach nicht wirklich gut aus aber vielleicht 
erweist es sich auch doch noch als zweckmäßig.

Viele Grüße
Christian

von MSP-Fan (Gast)


Lesenswert?

Wenn in der ISR oder einer anderen:

> - Im ADC-Interrupt den Wert abholen und den Low-Power-Mode beim
>   Verlassen ausschalten

also:
  bic.w  #LPM4,0(SP)
  reti
oder:
  __low_powermode_off_on_exit();

fehlt, passiert meistens gar nichts mehr.

Das Hauptprogramm kann nämlich selbst nicht mehr den LPM deaktivieren.

Aber damit, das ganze interruptgesteuert zu gestalten, bist Du ja
schon auf dem richtigen Weg.

von Christian M. (charlie)


Lesenswert?

ja, ich habs nicht bemerkt, weil mein Hauptprogramm noch nicht wirklich 
was gemacht hat. Ich hab nur die ISR aufgerufen, ein Pin getoggelt und 
wieder raus. Beim nächsten ADC Interrupt wieder in die ISR usw. Ich 
hatte mich nur gewundert warum das alles so ewig dauert, deswegen ja die 
Idee im ersten Beitrag...

Aber ich seh das ganze jetzt wesentlich klarer, danke für den 
Denkanstoß!

Viele Grüße
Christian

von MSP-Fan (Gast)


Lesenswert?

> Aber ich seh das ganze jetzt wesentlich klarer, danke für den
> Denkanstoß!

Gern geschehen.

Buchtipp: John Davies - MSP430 Microcontroller Basics
Elsevier/Newnes-Verlag 2008

Sehr gut und verständlich geschrieben.

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.