Datum: 04.04.2008 11:38
Hallo, ich erfasse mit dem MSP430F169 eine Spannung zwischen 0,6 und 2,2V (Externe Referenz liegt an eREF+ und VeREF-) Die Messspannung ist an P6.5 / A5 angelegt Den gemessenen Wert zwischen 0 und 4095 gebe ich auf einem Display aus, bzw betrachte ihn im Debugger. Bei einer langsamen Änderung der Eingangsspannung kann ich nicht alle Werte erfassen, es gibt Sprünge im Messwert. Hier ein Auszug, welche Messwerte möglich sind. Diese Werte werden durch langsames erhöhen der Eingangsspannung angezeigt. 1571 011000100011 1603 011001000011 1619 011001010011 2051 100000000011 2083 100000100011 2115 100001000011 2131 100001010011 2155 100001101011 2259 100011010011 2339 100100100011 Auch beim Debuggen und beobachten des ADC12MEM0 bekomme ich genau diese Werte angezeigt. Es fällt auf, dass immer die letzten 3 Binärstellen "011" sind. Ich schaffe es also nicht, irgendeinen Zwischenwert bei den obigen Messwerten einzustellen. Dieses Problem zieht sich über den gesamten Messbereich hin. Hier mein Code: Erst mal die Initialisierung...
ADinternInit() //Grundeinstellung AD-Wandler { ADC12CTL0 = ADC12ON + SHT0_0 + REFON; // ADC12ON:ADC in Bereitschaft // REFON zwar eingeschaltet, aber nicht verwendet, da externe Spannung ADC12 anschalten, ADC12CTL1 = SHP; // Sampling Timer benutzen (SHP = Sample-and-hold-pulse) Einstellungen werden automatisch vorgenommen // ----------------------------- // ADC12MCTL0 steuert ADC12MEM0. Das Conversion-Ergebnis steht im 16Bit-Register ADC12MEM0. // Die führenden 4 Bit sind "0" ADC12MCTL0 = SREF_6 + INCH_5; // SREF_6: Referenzspannung einstellen: Verwendet wird: Extern: VeREF+ und Extern: VeREF- // INCH=Input Channel A0 bis A11. Gewählt: P6.5 = A5 ADC12CTL0 |= ENC; // jetzt anfangen ... Enable Conversion muß HIGH sein um zu starten } |
Hier der Aufruf im Programm:
int temperaturmessung() { extern int ADCkty; // Die externe Variable ADCkty verwenden ADC12CTL0 |= ADC12SC; // Konvertierung durchfuehren while ((ADC12IFG & BIT0)==0) // Wenn das Bit 0 auf 1 geht, dann ist ein Wert in ADC12MEM0 geschrieben worden. {}; //warten.... ADCkty=ADC12MEM0; // ADCkty den Wert zuweisen(Bereich von 0 bis 4095) } |
Da die Messung zeilich nicht kritisch ist, verwende ich keine Interrupts, sondern warte auf den Abschluß der Wandlung. Was muss ich ändern, damit ich auch ALLE Zwischenwerte angezeigt bekomme? Martin
Datum: 04.04.2008 12:30
Du könntest etwas mit der Sample and Hold Zeit rumspielen, aber die 011 sieht nach einem generellen Problem aus. Sehr komisch, hatte ich noch nie.
Datum: 04.04.2008 12:45
Ich bezweifle dass du richtiges Programm angehängt hast. Bei
int temperaturmessung()
..
|
fällt dir nämlich Rückgabewert(return) und Compiler kann so etwas nicht Kompilieren.
Diese Werte werden durch langsames erhöhen der Eingangsspannung. |
Wie erhöhst du der Spannung? Mit einem Poti? Ist "langsam" auch präzis? Ich meine, nimm besser einer Spindelpoti oder Trimmer mit 10-20 Umdrehungen. Nur so ist "langsam" auch "präzis".
Datum: 04.04.2008 12:57
Komische Effekte im Zusammenhang mit dem ADC kenne ich nur wenn der Port-Pin nicht auf ADC Funktion geschaltet ist.
Datum: 04.04.2008 13:12
@Branko: Rückgabewert ist nicht nötig, da eine externe Variable beschrieben wird. Einstellgenauigkeit: 20-fach Spindel-Trimmer im Spannungsteiler, mit dem ich die Spannung in < mV-Auflösung einstellen kann. Das kann auch kein Problem sein, da immer wieder die GLEICHEN Werte nicht angezeigt werden. @Jörg: Portdefinition:
P6SEL = 0x20; P6DIR = 0xDF; P6OUT = 0x00; |
@Christian: Ich verwende ADC12CTL1 = SHP. So sollte doch alles soweit automatisch funktionieren? Habe keine schnellen Änderungen im Signal.
Datum: 04.04.2008 13:52
@Branko: Rückgabewert ist nicht nötig, da eine externe Variable beschrieben wird. |
Warum schreibst du dann:
int temperaturmessung...
|
statt
void temperaturmessung...
|
Datum: 04.04.2008 14:19
Stimmt, mein Fehler. Hatte zuvor eine Version mit Rückgabewert, die ich aber dann geändert habe. Das int hatte ich vergessen wegzunehmen. Ich habe jetzt nochmal alles zusammengefasst. Dieses Programm liefert genau den gleichen Fehler: Beim drehen am Poti springt der Wert z.B. von 2051 direkt auf 2083 und dann auf 2115 Ich lese am Breakpoint den Wert von ADC12MEM0 in IAR aus.
#include <msp430x16x.h> int ADCkty=0; main() { WDTCTL = WDTPW + WDTHOLD; // Stop Watchdogtimer // Port init P1SEL = 0x00; P1DIR = 0xF3; P1OUT = 0x03; P2SEL = 0x00; P2DIR = 0xEF; P2OUT = 0x00; P3SEL = 0x30; P3DIR = 0xCF; P3OUT = 0x00; P4SEL = 0x00; P4DIR = 0xFF; P4OUT = 0x00; P5SEL = 0x00; P5DIR = 0xFF; P5OUT = 0x8C; P6SEL = 0x20; P6DIR = 0xDF; P6OUT = 0x00; //AD-Init ADC12CTL0 = ADC12ON + SHT0_0 + REFON + REF2_5V; // ADC12ON:ADC in Bereitschaft ADC12CTL1 = SHP; // Sampling Timer benutzen (SHP = Sample-and-hold-pulse) Einstellungen werden automatisch vorgenommen ADC12MCTL0 = SREF_6 + INCH_5; // Extern: VeREF+ und Extern: VeREF- INCH=Input Channel A0 bis A11. Gewählt: P6.5 = A5 ADC12CTL0 |= ENC; // jetzt anfangen ... Enable Conversion muß HIGH sein um zu starten for(;;) { ADC12CTL0 |= ADC12SC; // Konvertierung durchfuehren while ((ADC12IFG & BIT0)==0) // Wenn das Bit 0 auf 1 geht, dann ist ein Wert in ADC12MEM0 geschrieben worden. {}; //warten.... // Das Ergebnis der Wandlung steht in ADC12MEM0 (rechten 12 Bit) ADCkty=ADC12MEM0; //BREAKPOINT // ADCkty behält immer den ADC-Wert. }// end for } //end main |
Datum: 04.04.2008 15:12
Kann es sein das dies durch die extrem kurze S&H-Zeit (4-Takte, SHT0_x) und den hohen Takt (kein Vorteiler, ADC12DIVx) verursacht wird?
Datum: 04.04.2008 16:22
Oder es ist ein Offset drauf. Weiß ja nicht, wie du die Ref-Quelle angeschlossen hast. Du musst ja die Differenz bei dir. Aber so konstant ist auch verwunderlich. Mal ins Errata-Sheet geschaut? Vielleichthat dein ADC12 ja einen bekannten Bug?
Datum: 04.04.2008 17:16
hatte ähnliche Probleme; siehe Beitrag "MSP430 Erfahrungsaustausch zu ADC12 gesucht", vielleicht ist etwas brauchbares dabei
Datum: 07.04.2008 10:21
Hallo Wolfgang, danke für den Tipp. Genau das war auch mein Problem. Mit Kondensatoren funktioniert es jetzt einwandfrei, ohne irgendwelche Änderung des Programmes! Danke Gruß Martin
Datum: 07.04.2008 10:58
Ich freue mich über Deine Rückmeldung und dass ich Dir helfen konnte. MfG Wolfgang
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
- Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel