Hallo
ich versuche mit Hilfe des ADC´s einen Spannungswert digital zu
erfassen. Es geht ersteinmal darum den Wert in ein Memory-Register des
ADC zu bekommen.
Ersteinmal etwas zum Aufbau. Mit Hilfe des TimerA wird ein 1ms Interrupt
ausgelöst. In diesem Interrupt soll ein Spannungswert eingelesen werden.
Dieser liegt nicht dauerhaft an, sondern wird im TimerA -Interrupt
eingeschaltet und nach kurzer Zeit wieder ausgeschaltet. In dieser
Zwischenzeit soll dieser Wert eingelesen werden. Ich bekomme jedoch
entweder als Ergebnis 0x00 im ADC12MEM1 oder 0xFFF, wobei der Pegel aber
eigentlich nicht größer als die Referenz ist, sondern minimal ca. 1V
ist. Selbst bei 1V bekomme ich sehr große Werte, meistens aber immer
0xFFF
Hier mal Auszüge aus dem Quelltext:
in der main:
ADC12CTL0 = ADC12ON + MSC; // ADC12 ON
ADC12CTL1 = SHP + CONSEQ_1; // SAMPCON Source
ADC12MCTL0 = INCH_5 + SREF_0 + EOS;
ADC12CTL0 |= ENC;
in der TimerA-ISR:
(Spannungswert EIN)
ADC12CTL0 |= ADC12SC;
while ((ADC12CTL1 & ADC12BUSY)==1);
(Spannungswert AUS)
Wie zu erkennen benutze ich als Referenz AVcc (3.3V). REFON kann ich
also auslassen oder?
Da das Einlesen nicht nur einmal sondern immer während des erwähnten
Zeitraumes passieren soll, habe ich mich für Sequenz of Channels
entschieden. Durch EOS wird dafür nur ADC12MEM0 verwendet. Hat also den
selben Effekt, als würde ich Repeat-Singel-Channel für MEM0 verwenden
oder?
Danke für die Antwort
Ja als AD sind sie konfiguriert. Nur vergessen zu posten.
P6SEL = BIT4 + BIT5 + BIT6;
Testweise werden alle 3 Pins ausprobiert. Demzufolge wird dann natürlich
auch INCH_4, INCH_5 oder INCH_6 gewählt.
Was meinst du mit SREF_0 definiert? Im User-Guide steht da Bereich von
AVcc bis AVss. Im Stromlaufplan sehe ich an Pin AVcc (100) dass da 3.3V
angeschlossen sind. Ist da noch etwas zu beachten?
Martin schrieb:
>> Was meinst du mit SREF_0 definiert? Im User-Guide steht da Bereich von> AVcc bis AVss.
Anscheinend hat es da mal Probleme gegeben, in CVS steht nämlich für
adc12.h:
1
-#defineSREF_00
2
+#defineSREF_0(0<<4)
> Im Stromlaufplan sehe ich an Pin AVcc (100) dass da 3.3V> angeschlossen sind. Ist da noch etwas zu beachten?
Ich wüsste jetzt auf die Schnelle nichts, bin aber ein n00b.
> Das sagt mir jetzt nicht so viel. Heißt das für SREF_0 bis SREF_4 gilt> immer SREF_0 ..?
Noe, das ist ein Schiebeoperator. damit wird SREF_0 binär 000 (glaub'
ich).
Ja genau. Und wenn schon SREF_0 steht für die Referenz AVcc...?
Das löst mein Problem aber immer noch nicht. Komisch ist auch, dass
manchmal eben ein etwas kleinerer Wert als 0xFFF drin steht. Wenn ich
dann nochmal resete und wieder ausführe steht wieder oxFFF drin. Die
Spannung am Pin ist aber eigentlich nicht größer als Referenz.
>in der TimerA-ISR:>(Spannungswert EIN)>ADC12CTL0 |= ADC12SC;>while ((ADC12CTL1 & ADC12BUSY)==1);>(Spannungswert AUS)
Bist Du Dir sicher, dass Deine zu messende Spannung während des
Samplings stabil ist oder schwingt die da noch ein/über? Oder hast Du
einen ausreichenden Delay zwischen Spannung EIN und ADC-Start?
Wo, wann und wie liest Du ADC12MEM0 aus?
Direkt nach
1
while((ADC12CTL1&ADC12BUSY)==1);
steht das neue Ergebnis da noch nicht drin!
>entweder als Ergebnis 0x00 im ADC12MEM1 oder 0xFFF,
Schreibfehler?
Also nein ich bin mir nicht sicher ob die zu messende Spannung schon
stabild ist. Sie ist aus dem Überschwingen schon raus, weil ich eine
Delay-Zeit eingebaut habe. (ich probiers auch mal mit einer etwas
größeren) Um das von euch genauer beurteilen zu lassen, müsste ich
weiter ausholen: Ich hab mal ein Bild gepostet. Auflösung 1V bzw.2V. Ich
denke das ist stabild genug oder? Die Spannungs die dann aber am Pin
anliegt, ist zwar leicht verzerrter, das sollte aber ausreichend sein.
Ja das unten war ein Schreibfehler.
Zum Auslesen. Wann steht denn dann das Ergebnis im Speicher-Register?
Bis jetzt habe ich es immer so gemacht: Programm starten, irgendwann
stoppen. Und mit Software mir das Register anschauen. Aber irgendwie
vermute ich jetzt, dass das ein Fehler ist oder? Weil ich das Programm
ja immer zu unterschiedlichen Zeiten stoppe. Zufall eben. Mal im
Interrupt. Mal gerade nach dem Einlesen. Unterschiedlich halt.
>Die Spannungs die dann aber am Pin>anliegt, ist zwar leicht verzerrter, das sollte aber ausreichend sein.
Jo mei... schaut net so schlimm aus...zumindest nicht nach 0x0FFF ;-)
>Wann steht denn dann das Ergebnis im Speicher-Register?
Wenn das entsprechende ADC12IFGx gesetzt ist.
Ich würde auch mal lieber den single-channel, single-conversion mode
auswählen, nichts anderes machst Du ja schließlich!
Ob's das allerdings ist...?
und dann die Conversion mit dem ADC12SC-Bit starte. Also
Single-Conversion. Werden dann alle 4-Register beschrieben, mit den
entsprechenden Werten? Oder funktioniert das in Single-Conversion so
nicht?
Ja ich teste halt erstmal. Wäre nich schlecht wenn erstmal einfaches
Wandeln funktonieren würde.
Heißt also, wenn ich das so machen will wie in meinem letzten post,
müsste ich 4mal ADC12SC setzen und kurz vorher noch einen neuen
Startpunkt festlegen..?
Hast du denn mal die Code-Beispiele von TI getestet, um sicherzustellen,
dass der ADC überhaupt seinen Dienst tun? Hast du die Kondensatoren an
AVCC und VREF dran, wie im Datenblatt angegeben?
Ich nutze den MSP430FG4619
Zu den TI-C-Beispielen. Ich habe sie mir angeschaut ja. Ich kann sie
natürlich nciht einzueins übernehmen, weil ich hier mit einer fertigen
Baugruppe arbeite und aufpassen muss was ich mit den Pins mache. Um
Fehler auszuschließen hab ich mal mein C-Programm minimiert und nur
folgendes ausprobiert:
Also im Prinzip das Gleiche. Und siehe da: Es funktioniert. Was mich
jedoch gewundert hat ist, dass es ebenso funktioniert wenn ich P6.5
NICHT als a/d Eingang verwende, also P6SEL weglasse.
Umsomehr wundere ich mich, warum es in meinem kompletten Testprogramm
nicht funktioniert. Liegt es daran, das ich TimerA-Interrupt, DAC und
ADC benutze? Mögen die sich nicht? Wenn gewünscht kan ich auch mal
Auszüge aus meinem kompletten Testprogramm posten.
>Was mich jedoch gewundert hat ist, dass es ebenso funktioniert>wenn ich P6.5 NICHT als a/d Eingang verwende, also P6SEL weglasse.
P6SEL schaltet in diesem Fall nicht die ADC12 Funktionalität des Port6
frei, sondern deaktiviert dessen digitalen Ein-/Ausgangsbuffer. D.h. der
jeweilige P6-Pin wird zu einen "reinen" analogen Eingang, was parasitäre
Ströme durch die CMOS-Gates unterbindet (s. User-Guide!)
1
>while((ADC12CTL1&ADC12BUSY)==1);
2
>if((ADC12IFG&0x01)==1)b1=ADC12MEM0;
einfacher:
1
while(!(ADC12IFG&ADC12IFG0));
2
b1=ADC12MEM0;
>Umsomehr wundere ich mich, warum es in meinem kompletten Testprogramm>nicht funktioniert. Liegt es daran, das ich TimerA-Interrupt, DAC und>ADC benutze? Mögen die sich nicht? Wenn gewünscht kan ich auch mal>Auszüge aus meinem kompletten Testprogramm posten.
Prinzipiell "mögen" die sich schon, wenn man's richtig macht ;-)
Aber ohne Deinen source code im Detail kann man den Fehler darin wohl
kaum feststellen!
Der Uhrzeit angemessen nur zwei kurze Hinweise ohne den Code im Detail
durchgegangen zu sein:
1.)
1
volatileinti,a,b1,b2;
2.)
Deine ganzen Delays und Warteschleifen in der Timer-ISR könnten zwar
zeitlich hinkommen, aber eleganter wäre es sicher, den ADC-Meswert in
einem ADC-Interrupt abuholen und nicht in der Timer ISR-darauf zu
warten!
Ich glaube ich komme der Ursache auf den Grund.
Was für folgen kann es haben, wenn AVcc merklich von 3.3V abweicht?? Ist
dieser Wert vorgegeben oder kann ich den Controller mit "jeder" (laut
Datenblatt) beliebigen Spannung betreiben, ohne das dies Auswirkungen
auf den Programmabläufe hat?
>Ich glaube ich komme der Ursache auf den Grund.
glaub ich nicht ;-)
>Was für folgen kann es haben, wenn AVcc merklich von 3.3V abweicht??
Was ist merklich ?
1V, 5V 10V ...???
>kann ich den Controller mit "jeder" (laut>Datenblatt) beliebigen Spannung betreiben, ohne das dies Auswirkungen>auf den Programmabläufe hat?
Na sicher, sonst würd's TI im DB ja nicht so angeben!
Es ist lediglich so, dass Vcc umso größer sein muss, je schneller der
MSP getaktet wird. Und zum Programmieren muss Du auch eine
Mindestspannung einhalten, die größer ist als die minimale
Betriebsspannung.
Steht aber alles im DB
Bis jetzt bin ich davon überzeugt, dass es an einer schlechten
Kontaktierung des Pins 100 (Avcc) liegt. Da ich die gleiche Baugruppe
2mal vorliegen habe, bin ich mir dessen sicher. Bei der 2ten tritt
dieser Fehler nicht auf.
Werde dies mal beheben und weiter berichten. Habs übrigens auch mit dem
ADC Interrupt ausprobiert- selber Effekt.