Forum: Mikrocontroller und Digitale Elektronik MSP 430 G2553 ADC10 mehrere Eingänge - wie?


von Ben P. (ben5en)


Lesenswert?

Hallo,

Ich arbeite mich gerade in das MSP 430 G2553 Launchpad ein und bin 
völlig neu auf dem Gebiet. Bislang habe ich eine PWM über ein Poti 
(Helligkeitseinstellung LED) und Anzeige der Modulationsweite in Prozent 
auf einem LC-Display realisiert.

Nun möchte ich einen weiteren analogen Eingang nutzen und weiß nicht 
wie.
Die PWM habe ich im vorherigen Projekt ganz simpel mittels Vergleich des 
ADC10MEM - und des Timerwertes umgesetzt:
1
// als Auszug:
2
TACCR0 = 1023;               // CCR0 -> cycle time
3
TACCR1 = duty_cycle;         // CCR1 -> duty cycle
4
duty_cycle=(unsigned long)ADC10MEM;
5
// ... und Ausgabe auf Display

Wie ich gesehen habe, gibt es ebenfalls ADC12 Wandler mit mehreren 
"Ergebnisregistern" ala ADC12MEM0, ADC12MEM1, in welchem die Werte der 
AD Wandlung abgelegt werden - doch wird dies in dieser Form nicht vom 
G2553 unterstützt.

Ich habe hier im Forum bereits einen Code von TI gefunden, welcher sich 
der Porblematik des ADC10 und mehreren Eingängen annimmt. Mir ist jedoch 
leider nicht ersichtlich, was zB. bei ADC10SA genau geschieht und wie 
ich die abgelegten Daten zur weiteren Verwendung aufrufe.

Wenn nicht unbedingt nötig, möchte ich einen Interrupt vermeiden. Bei 
meiner Anwendung kommt es auch nicht auf lowcurrent an.

Ziel ist es an P1.1 ein Poti für eine PWM anzuschließen und an P1.2 
einen LEM Stromwandler. Über ein Display möchte ich mir den 
Momentanstrom meines (externen) Verbrauchers anzeigen lassen.

Über Anregungen und Tipps würde ich mich sehr freuen.
Vielen Dank.

von Clemens L. (c_l)


Lesenswert?

Siehe Beispielprogramm msp430g2x33_adc10_10.c.

von Ben P. (ben5en)


Lesenswert?

Benjamin P. schrieb:
> Ich habe hier im Forum bereits einen Code von TI gefunden, welcher sich
> der Porblematik des ADC10 und mehreren Eingängen annimmt. Mir ist jedoch
> leider nicht ersichtlich, was zB. bei ADC10SA genau geschieht und wie
> ich die abgelegten Daten zur weiteren Verwendung aufrufe.

"Siehe Beispielprogramm msp430g2x33_adc10_10.c." -> diesen Code habe ich 
bereits gefunden und stehe somit vor selbigen Problem.

von Dietmar S. (dsausw)


Lesenswert?

Hi Benjamin,

das Beispiel hast Du?
slau144 auch?
Ergebnis in ADC10MEM.
Das Beispiel von Clemens ist genau richtig:
Einlesen mehrerer ADins.
Interrupts beissen auch nicht, aber zum Testen
reicht auch Polling.
Du solltest Dir die Kapitel im User's Guide einmal durchlesen.
Bei TI gibt es auch noch jede Menge Literatur.

Gruss
Dietmar

von Ben P. (ben5en)


Lesenswert?

Dietmar S. schrieb:
> das Beispiel hast Du?
> slau144 auch?

Das Beispiel entspricht in etwa diesem hier: 
https://www.mikrocontroller.net/attachment/38868/msp430x22x4_adc10_10.txt

Was meinst du mit slau144?

Okay, ich werde mich auch noch mal an die TI PDF's setzen.
Ich habe gehofft über die Frage hier auf einem kürzeren Weg zum 
Verständnis zu kommen, dass es mir eventuell den Einstieg erleichtert 
aber die Tipps sind auch in jedem Fall gut.

Somit besten Dank.
Eventuell gebe ich noch mal Rückmeldung.

Über weitere Hinweise bin ich natürlich trotzdem dankbar.
Viele Grüße

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Benjamin P. schrieb:
> Was meinst du mit slau144?

Das ist der "MSP430x2xx Family User's Guide"

www.ti.com/lit/ug/slau144j/slau144j.pdf

von Clemens L. (c_l)


Lesenswert?

Benjamin P. schrieb:
> Mir ist jedoch leider nicht ersichtlich, was zB. bei ADC10SA genau
> geschieht

Das ist die Adresse der Variablen, wo die Werte hineingeschrieben 
werden. Eine feste Adresse zu benutzen ist natürlich sehr dreckig.

von Ben P. (ben5en)


Lesenswert?

Guten Morgen,

mittlerweile läuft es.

ADC10SA fungiert als Pointer, das wusste ich bis dato nicht.
Ebenfalls konnte ich mit "0x200":
1
ADC10SA = 0x200;                        // Data buffer start
nicht viel anfangen.

Es läuft einwandfrei mit:
1
#include "msp430g2553.h"
2
3
unsigned int ADCMEM0 ;         // ADC gewandelter Wert von P1.0
4
unsigned int ADCMEM1 ;         // ADC gewandelter Wert von P1.1
5
unsigned int ADCMEM[2];        // ADC Wert 
6
7
void main(void)
8
{
9
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
10
  ADC10CTL1 = INCH_1 + CONSEQ_1;            // A1/A0, single sequence
11
  ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
12
  ADC10DTC1 = 0x02;                         // 2 conversions
13
  ADC10AE0 |= BIT0 + BIT 1                  // P1.0,1 ADC10 option select
14
15
for (;;)
16
 {
17
    ADC10CTL0 &= ~ENC;
18
    while(ADC10CTL1 & BUSY);
19
    ADC10SA = (unsigned int)ADCMEM; 
20
    ADC10CTL0 |= ENC + ADC10SC
21
    ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
22
    __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit
23
    ADCMEM1 = ADCMEM[1]; 
24
    ADCMEM0 = ADCMEM[0];
25
  }
26
}
27
28
// ADC10 interrupt service routine
29
#pragma vector=ADC10_VECTOR
30
__interrupt void ADC10_ISR(void)
31
{
32
  __bic_SR_register_on_exit(CPUOFF);        // Clear CPUOFF bit from 0(SR)
33
}

von Ben P. (ben5en)


Lesenswert?

* eben bemerkt:
Beim zusammenschieben vom Code im vorherigen Post haben sich beim 
zusammenschieben kleine Fehler eingebaut. Sollte man aber finden können.

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.