Forum: Mikrocontroller und Digitale Elektronik MSP430 Frage zu ADC


von Uwe Saal (Gast)


Lesenswert?

Hi und hallo,

ich beschäftige mich gerade ein wenig mit dem adc von meinem
msp430f149.

habe mal am Port6.0 eine Variable Spannung angelegt und bhängig vom
Pegel eine LED an oder aus gemacht. Das funktioniert auch. Nun wollte
ich das ganze mal mit Port 6.0 und 6.7 machen und zwei verschiedene
LED's an oder ausmachen, aber irgendwie funktioniert das nicht. Ich
wollte erste inmal nur den 6.7 nutzen und wie zuvor ein Poti
anschließen usw., aber das bekomme ich schon nicht anslaufen.

Hierm almein Code dazu. Wäre toll, wenn mir da jemand auf die Sprünge
hlfen könnte.

  P6DIR=0x00;            // Port 6 als Eingänge nutzen
  P6SEL=0x81;            // Port 6.0 und 6.7 als A/D-Wandler benutzen,

                         // den Rest als GPIO

  ADC12CTL0 = ADC12ON+SHT0_0+REFON;          // ADC12 an
                                             // Referenz 1,5V
  ADC12CTL1 = SHP;
  ADC12MCTL0 = SREF_1+INCH_0;
  ADC12CTL0 |= ENC;                          // anfangen
  for(;;)
  {
    ADC12CTL0 |= ADC12SC;                    // Konvertierung starten

   var = ADC12MEM1;                     // ADC12MEM0 für Port 6.7
                                        // ADC12MEM0 für Port 6.0

Hab ich was vergessen zu initialiseiren? Ich komme auch noch nciht so
ganz mit den Registern klar.

Wäre toll, wennir jemand sagen könnte wo der wurm drin steckt.

Danke.
Gruß
Uwe

von Jörg S. (Gast)


Lesenswert?

INCH_0  ist nur Port 6.0, wenn du 6.7 haben willst, muss da INCH_7 oder
sowas in der Richtung stehen.

von Uwe Saal (Gast)


Lesenswert?

habs jetzt mal so probiert, aber läuft irgendwie noch nicht.

ADC12CTL0 = ADC12ON+SHT0_0+REFON+REF2_5V;
  ADC12CTL1 = SHP;
  ADC12MCTL7 = SREF_1+INCH_7;
  ADC12CTL0 |= ENC;
  for(;;)
  {
    ADC12CTL0 |= ADC12SC;
    wait(50);

    spannung_double = (ADC12MEM7);

von Uwe Saal (Gast)


Lesenswert?

Wenn ich folgendes mache, funktioniert es aber ich muss doch auch
irgendwie die anderen register ansprechen können oder verstehe ich da
was falsch?

  P6DIR=0x00;
  P6SEL=0x80;

  ADC12CTL0 = ADC12ON+SHT0_0+REFON+REF2_5V;
  ADC12CTL1 = SHP;
  ADC12MCTL0 = SREF_1+INCH_7;
  ADC12CTL0 |= ENC;
  for(;;)
  {
    ADC12CTL0 |= ADC12SC;
    wait(50);
    var = (ADC12MEM0);

also es muss doch auch ADC12MEM1, ADC12MEM2 usw.wählen können.
lieg ich da richtig? wenn ja wie stellt man das denn an?

gruß
uwe

von szimmi (Gast)


Lesenswert?

Hiho,
also der F149 hat insgesamt 16 ADC-Puffer ADC12MEM0...ADCMEM16.
Wenn Du es nicht anders einstellst, landet die Wandlung eines einzelnen
Kanals immer im ADC12MEM0, egal, welchen Kanal Du wandelst.
Sofern das Ergebnis in einem anderen Puffer landen soll, dann ist das
in ADC12CTL1, Bits 12-15 einstellbar. Bei Sequenzen steht in diesen
Bits die Start-Adresse und wird nach jeder Wandlung inkrementiert.

von szimmi (Gast)


Lesenswert?

Nochwas,
ehe ich es vergesse, das wait ist schlechter Stil. Besser auf das Ende
der Wandlung warten (z.B.über Abfrage ADC12BUSY).

von SupaChris (Gast)


Lesenswert?

Noch besser mit dem ADC-Interrupt. Am Ende jeder Umwandlung(ssequenz)
gibts doch nen Interrupt.
Notfalls hat das Flag pollen.

von uwe saal (Gast)


Lesenswert?

hallo,

das mit dem wait habe ich nun mal so gelöst:

while ((ADC12CTL1 & ADC12BUSY) == 1);


muss das mit den puffern nicht in ADC12MCTL0 eingestellt werden. so
verstehe ich das nämlich aus der msp-doku.

hab das jetzt so, aber das funzt auch nicht:

  ADC12CTL0 = ADC12ON+SHT0_0+REFON;
  ADC12CTL1 = SHP;
  ADC12MCTL0 = SREF_7+INCH_7;
  ADC12CTL0 |= ENC;
  for(;;)
  {
    ADC12CTL0 |= ADC12SC;
    while ((ADC12CTL1 & ADC12BUSY) == 1);

    var = (ADC12MEM7);


mit dem sref wird doch angegeben, wo die referenzspannung verwendet
werden soll!?

uwe

von Jörg S. (Gast)


Lesenswert?

Nein, die sref ist eine Allgemeine Einstellung WELCHE Referenzspannung
verwendet werden soll.
Und wenn ich mich nicht irre, ist ADC12MCTL0 auch nur für ADC12MEM0
zuständig.

"Each ADC12MEMx is configured with an associated ADC12MCTLx
control register."

von Tenner (Gast)


Lesenswert?

[quote]
szimmi schrieb:
Wenn Du es nicht anders einstellst, landet die Wandlung eines
einzelnen
Kanals immer im ADC12MEM0, egal, welchen Kanal Du wandelst.
Sofern das Ergebnis in einem anderen Puffer landen soll, dann ist das
in ADC12CTL1, Bits 12-15 einstellbar.
[/quote]
und wer schreibt nun das Datenblatt um?

Der MSP hat 16 conversion memory register (ADC12MEMx). Jedes register
hat ein korrespondierendes Konfigurationsregister (ADC12MCTLx). Über
diese Register wird gesteuer welcher ADC-Kanal in welches register
schreibt.
mit:
ADC12MCTL0 = SREF_7+INCH_7;
landet das conversions-Ergebnis des ADC-Kanal 7 im conversion memory
register 0. Wobei als Referenzspannung mit SREF_7 die externe
referenzspannung gewählt wird.

Um das Ergebnis in Register 7 zu bekommen und als Referenzspannung die
interne zu nutzen müßte es wie folgt aussehen:

ADC12MCTL7 = SREF_1+INCH_7;

Will man nun mehrere Kanäle nutzen, ist eine sequenz sinnvoll. In
diesem Fall wäre es sinnig das Ergebnis von Kanal 0 in das Register 0
und das Ergebnis von Kanal 7 in das Register 1 zu schreiben.

ADC12CTL1 = CSTARTADD_0+SHP+CONSEQ_1;

ADC12MCTL0 = SREF_1+INCH_0;
ADC12MCTL1 = SREF_1+INCH_7+EOS;

CSTARTADD_0 gibt an das mit dem ADC12MEM0 register begonnen wird.
CONSEQ_1    eine sequenz von ADC-Kanälen wird gesampled

EOS bei ADC12MCTL1 bedeutet das mit ADC12MEM1 die sequenz beendet ist.

aber eigentlich wird das alles im Datenblatt sehr gut beschrieben ...

gruß Tenner

von uwe saal (Gast)


Lesenswert?

hallo,

ich habe mal einwenig rumprobier und nochmal in die doku geschaut, aber
so ganz steige ich da immer noch nicht durch. wenn ich das folgende
anstelle, landet der wert für meinen port 6.7 in ADC12MEM0. das ist
auch nun klar.

ADC12CTL0 = ADC12ON+SHT0_0+REFON;
ADC12CTL1 = SHP;
ADC12MCTL0 = SREF_1+INCH_7;
ADC12CTL0 |= ENC;

  for(;;)
  {
    ADC12CTL0 |= ADC12SC;
    wait(50);
    var = (ADC12MEM0);

wenn ich INCH_7 gegen INCH_0 tausche, landet mein werte von port 6.0 in
ADC12MEM0. das ist auch klar und funktioniert.

wenn ich das dann wie folgt mache, funzt es nicht mehr. es scheint, als
ober der anliegende wert an dem jeweiligen port einmal gewandelt wird
und dann ende. wenn ich dann z.b. an port 6.0 die spannung variiere,
bleibt der wert immer gleich und ändert sich nicht mehr. der wert von
port 6. scheint komplett falsch zu sein.


ADC12CTL0 = ADC12ON+SHT0_0+REFON;   // adc an, ref 1.5v
ADC12CTL1 = CSTARTADD_0+SHP+CONSEQ_1;
ADC12MCTL0 = SREF_1+INCH_0;     // wert von p 6.0 landet in ADC12MEM0
ADC12MCTL1 = SREF_1+INCH_7+EOS; // wert von p 6.7 landet in ADC12MEM1
ADC12CTL0 |= ENC;               // los
  for(;;)
  {
    ADC12CTL0 |= ADC12SC;       // konvertierung starten
    wait(50);
    var = (ADC12MEM0);     // wert von 6.0 in variable var
    var2 =(ADC12MEM1);     // wert von 6.7 in variable var2

hab ich da noch etwas übersehen?

von johnny.m (Gast)


Lesenswert?

Also ich bin jetzt nicht wirklich der große MSP430-Experte, aber bei
anderen µCs muss man jeden Kanal separat wandeln. Der µC hat ja nur
einen A/D-Wandler. Wenn Du einen Kanal gewandelt hast, dann musst Du
den Kanalmultiplexer umschalten auf den zweiten Kanal und eine neue
Wandlung starten. Dann das ganze wieder von vorne, immer abwechselnd.
Was Du anscheinend machst, ist eine einzige Wandlung starten und dann
beide Werte auslesen. Das geht sicher nicht!

Und dass das mit der Wartezeit ziemlich ungut ist, ist ja weiter oben
schon mal angedeutet worden. Besser ADC-Flag abfragen...

von uwe saal (Gast)


Lesenswert?

so,

ich glaube ich habs. folgende zeile musste ich noch korrigieren:

ADC12CTL0 = ADC12ON+SHT0_0+MSC+REFON;

ich habe da noch das MSC hinzugefügt und nun werden die kanäle
kontinuierlich gewandelt.

danke.

von szimmi (Gast)


Lesenswert?

[quote]
und wer schreibt nun das Datenblatt um?
[/quote]
Das schreibt natuerlich niemand um. Sorry, dass ich mich geirrt habe.

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.