www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 ADC: Wert wird nicht richtig eingelesen


Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

vielleicht kann mir jemand mit meinem ADC weiterhelfen. Ich habe schon 
viele Beträge durchforstet aber so richtig konnte ich meinem Fehler 
trotzdem nicht auf die schlieche kommen.

Mein Problem ist, dass der ADC mir immer im Register ADC12MEM7 den Wert 
0 ausgibt. Also im Debug Modus ist dieser Wert immer 0. Die Rechnung die 
unten stattfindet betrachte ich zunächst garnicht, sondern ich habe mir 
einen Breakpoint in der Zeile  temp_value    = (Vref/4095)*ADC12MEM6; 
eingefügt und betrachte mir im Debug Modus den Wert von ADC12MEM7.
An dem Pin eine Spannung von 0.1V an, sodass eigentlich ein Wert zu 
erwarten ist.

Hier ist der Code meines ADCs:

P6DIR  = 0x27;
P6SEL |= 0xD8;                     // Current Sensor --> ADC Function
ADC12CTL0 = ADC12ON+SHT0_8+MSC+REFON;
ADC12CTL1 = CSTARTADD_0+SHP+CONSEQ_1;
ADC12MCTL3 = SREF_1+INCH_3;       // wert von p 6.3 landet in ADC12MEM3
ADC12MCTL4 = SREF_1+INCH_4;   // wert von p 6.4 landet in ADC12MEM4
ADC12MCTL6 = SREF_1+INCH_6;   // wert von p 6.6 landet in ADC12MEM5
ADC12MCTL7 = SREF_1+INCH_7+EOS;   // wert von p 6.7  ADC12MEM7
                                         //Sequenz End by EOS


ADC12CTL0 |= ENC;                 // los
ADC12CTL0 |= ADC12SC;             // konvertierung starten
wait(10000);
//   while ((ADC12CTL1 & ADC12BUSY) == 1);
current_LNA  = (Vref*ADC12MEM3)/(4095*24e3/5e3);
current_AMPs = (Vref*ADC12MEM7)/(4095*24e3/5e3);
current_MIXER = (Vref*ADC12MEM4)/(4095*1e3/5e3);
temp_value    = (Vref/4095)*ADC12MEM6;


vielleicht sieht ja jemand direkt was ich falsch mache.
ich weiß im Moment leider erstmal nicht weiter.

Viele Grüße,
Andreas

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Mein Problem ist, dass der ADC mir immer im Register ADC12MEM7 den Wert
>0 ausgibt.
Und die anderen Wandlungen funktionieren?

Du setzt ENC nach der Wandlung oder vor einer neuen Wandlung wieder 
zurück? Oder willst du nur einmalig wandeln?

Autor: Fabio S. (codehamster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich mache das so
void adc_init(void)
{
    int16 i;

    // Enable A/D channel A3 to A7
    P6SEL |= BIT3 + BIT4 + BIT5 + BIT6 + BIT7;

    // Turn on and set up ADC12
    ADC12CTL0 = MSC + SHT0_2 + ADC12ON + REF2_5V + REFON;
    ADC12CTL1 = CSTARTADD_0 + SHS_0 + SHP + ADC12DIV_0 + ADC12SSEL_3 + CONSEQ_1;

    // Messung Kanal 3
    // EOS = 0 / VR+ = VREF+(2.5V) VR- = AVSS(GND) / INCH = A3
    ADC12MCTL0 = SREF_1 + INCH_3;
    // Messung Kanal 4
    // EOS = 0 / VR+ = VREF+(2.5V) VR- = AVSS(GND) / INCH = A4
    ADC12MCTL1 = SREF_1 + INCH_4;
    // NTC Temperaturmessung
    // EOS = 0 / VR+ = VREF+(2.5V) VR- = AVSS(GND) / INCH = A5
    ADC12MCTL2 = SREF_1 + INCH_5;
    // Batterienspannungsmessung
    // EOS = 0 / VR+ = VREF+(2.5V) VR- = AVSS(GND) / INCH = A6
    ADC12MCTL3 = SREF_1 + INCH_6;
    // Messung des Motorenstrom
    // EOS = 1 / VR+ = VREF+(2.5V) VR- = AVSS(GND) / INCH = A7
    ADC12MCTL4 = EOS + SREF_1 + INCH_7;

    ADC12MEM5 = 0x00;
    ADC12MEM6 = 0x00;
    ADC12MEM7 = 0x00;
    ADC12MEM8 = 0x00;
    ADC12MEM9 = 0x00;
    ADC12MEM10 = 0x00;
    ADC12MEM11 = 0x00;
    ADC12MEM12 = 0x00;
    ADC12MEM13 = 0x00;
    ADC12MEM14 = 0x00;
    ADC12MEM15 = 0x00;

    // Delay for reference start-up
    for ( i=0; i<0x3600; i++);

    // Enable conversions
    ADC12CTL0 |= ENC;
}

und im Timer_A löse ich alle x ms die Messung aus
ADC12CTL0 |= ADC12SC;

Autor: Fabio S. (codehamster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich würde mal das Initialisieren des AD-Wandlers und das Auslösen der 
Messung in 2 verschiedenen Funktionen machen.

Dann kannst du mal versuchen mehrere Messungen auszulösen. Wenn die 
Messung beendet ist (Funktion)
Kannst du noch eine weitere Funktion erstellen die dann die Register 
ausliest oder du greifst direkt auf das ADC12_MEMx zu.

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>ADC12CTL0 |= ENC;
Du brauchst noch etwas um ENC wieder zurück zu setzen. Ansonsten geht 
die Zeile
   // Turn on and set up ADC12
    ADC12CTL0 = MSC + SHT0_2 + ADC12ON + REF2_5V + REFON;
schief, da ENC noch vom letzten Aufruf gesetzt ist.

Autor: Fabio S. (codehamster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg S,

er kann doch ENC stehen lassen, sofern er einmal den AD-Wandler 
initialisiert und danach separat die Messungen startet, oder habe ich 
jetzt einen Knopf in der Leitung?

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die ADC Einstellungen immer alle gleich bleiben, dann kann ENC 
stehen bleiben, ja.

Autor: Andreas (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

heute konnte ich endlich Eure Anregung genauer testen. Vielen Dank für 
die vielen Antworten!
Also mein Code sieht jetzt so aus:

eine Initalisierungs Fkt., die ich im Hauptprg einmal aufrufe,
void init_ADC(void)
{
int i;
ADC12CTL0 = ADC12ON + SHT0_2 + MSC + REFON;
ADC12CTL1 = CSTARTADD_0 + SHP + SHS_0 + ADC12DIV_0 + ADC12SSEL_3 + CONSEQ_1;
ADC12MCTL0 = SREF_1 + INCH_3;       
ADC12MCTL1 = SREF_1 + INCH_4;
ADC12MCTL2 = SREF_1 + INCH_6;   
ADC12MCTL3 = SREF_1 + INCH_7 + EOS;     

ADC12MEM4 = 0x00;
ADC12MEM5 = 0x00;
ADC12MEM6 = 0x00;
ADC12MEM7 = 0x00;
ADC12MEM8 = 0x00;
ADC12MEM9 = 0x00;
ADC12MEM10 = 0x00;
      ADC12MEM11 = 0x00;
      ADC12MEM12 = 0x00;
      ADC12MEM13 = 0x00;
      ADC12MEM14 = 0x00;
      ADC12MEM15 = 0x00;

for ( i=0; i<0x3600; i++);
ADC12CTL0 |= ENC;                   // los
}
und eine "Messfkt", die ich immer wieder aufrufe:
void current_meas(void)
{
int i=0;
ADC12CTL0 |= ADC12SC;
for ( i=0; i<0xFFFF; i++);  
 //while ((ADC12CTL1 & ADC12BUSY) == 1);
current_LNA   = (Vref*ADC12MEM0)/(4095*(24e3/5e3));           current_AMPs  = (Vref*ADC12MEM3)/(4095*(24e3/5e3));             current_MIXER = (Vref*ADC12MEM1)/(4095*(1e3/5e3));   
temp_value   = (Vref/4095)*ADC12MEM2;
}        
einen Breakpoint habe ich mir bei current_MIXER gesetzt um mir die 
beiden oberen Werte anzuschauen. Ich bekomme zwar Werte für z.B. 
current_AMPs aber dieser ist in den seltens Fällen richtig und in den 
meisten Fällen einfach "0". Kann es sein als wenn das Samplen irgendwie 
nicht lange genug ist? Allerdings liegt am Pin eine Gleichspannung an.
Ein weiteres Phänomen das machenmal auftritt ist der Vector Fehler der 
als Anhang beifefügt ist.

Vielleicht könntet Ihr mir nochmal ein paar Tipps geben?

Viele Dank.
Gruß,
Andreas

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann es vielleicht sein, dass ich die Messfkt im HP zu schnell wieder 
aufrufe (Endlosschleife)?

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm also dieses Vector Problem habe ich in den Griff bekommen. Es lag an 
meiner Initialisierung des Oszillators.

ich habe mal ein absolut abgespecke Version aus den Codebeispielen 
verwenden und meine Auslesefkt. auf ein minimum gekürzt:
unsigned int current_meas(void)
{
    ADC12CTL0 |= ADC12SC + ENC;
    ADC12CTL0 &= ~ADC12SC;

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

Die Init Fkt. ist wie oben nur die Zeile
 
ADC12CLT0 |= ENC

habe ich noch gestricken. Seit dem das Vektor problem nicht mehr 
auftritt ist aber mein Rückgabewert nur noch "0".

Im Moment hab ich keine Idee was ich noch versuchen kann.

Hoffe Ihr könnt mir noch einen Tip geben.

Gruß,
Andreas

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ADC12CTL0 &= ~ADC12SC;
Ist unnötig.

>Seit dem das Vektor problem nicht mehr auftritt ist aber mein
>Rückgabewert nur noch "0".
Bei allen Kanälen?


Bau doch erst mal ne Einkanalmessung. Wenn die funktioniert ist man erst 
mal sicher das es grundlegend funktioniert.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.