Hallo Forumsmitglieder, ich nutze seit längerem den MSP430F447 mit dem 12 Bit AD Wandler. Dort hatteich nie Probleme die AD Wandler anzusprechen und vernünftige Ergebnisse zu erhalten. Seit kurzem teste ich den MSP430F2012 mit dem 10 Bit AD Wandler. Dieser lässt sich leider nicht richtig ansprechen, ich erhalte stets den Messwert 0. Vielleicht ist euch ein Fehler ersichtlich. Vielen Dank! Anbei meine AD Routine in Assembler: // -- AD Wandler ---------------------------------------------------------- // MSP 430F2012 Port P1.2 als AD Eingang A2 nutzen // ------------------------------------------------------------------------ AD2; bic.w #ENC,&ADC10CTL0 ; ENC Bit auf Null setzen, um Steuerbits verändern zu können bis.w #SREF_1,&ADC10CTL0 ; Interne Referenz auswählen bis.w #REF2_5V,&ADC10CTL0 ; 2,5 V Referenz auswählen bis.w #REFON,&ADC10CTL0 ; Interne Referenz einschalten bis.w #ADC10SHT_2,&ADC10CTL0 ; Anzahl der Taktzyklen für eine Wandlung (4, 8, 16, 64) bis.w #ADC10ON,&ADC10CTL0 ; ADC einschalten bis.w #ADC10DIV_3,&ADC10CTL1 ; bis.w #INCH_2,&ADC10CTL1 ; Wahl des AD Eingangs (0,1,2,3) bis.w #SHS_1,&ADC10CTL1 ; Sample / Hold Source 1 bis.w #CONSEQ_2,&ADC10CTL1 ; Wiederholte Messung eines AD- Kanals bis.b #04h,&ADC10AE0 ; P1.2 ADC10 option select bis.w #ENC,&ADC10CTL0 ; Einschalten des ADC (Steuerefehle blockiert) bis.w #ADC10SC,&ADC10CTL0 ; Start sampling/conversion mov.w &ADC10MEM,R8 ; AD Wandler Ergebnis speichern ret
Kann es sein das du überhaupt nicht abwartest bis die Wandlung fertig ist?
Hallo Jörg, mhm, bei dem MSP430F447 habe ich keine spezielle Pause eingebracht und die AD Wandler arbeiten dort. Wo sollte ich hier eine Pause einplanen? Ich habe bis jetzt ehr das Gefühl das ich bei der Initialisierung einen Fehler habe, und evtl. den Falschen Port ect. messe. Schönen Gruß, Heiko.
>mhm, bei dem MSP430F447 habe ich keine spezielle Pause eingebracht und >die AD Wandler arbeiten dort. >Wo sollte ich hier eine Pause einplanen? Du solltest warten bis der AD Wandler mit der Messung fertig ist bevor du den Wert abholst :) Aber wenn ich das richtig sehe machst du Dauermessung, da ist das kein Problem. Dein Code mit dem lesen von ADC10MEM passt halt nicht dazu... > bis.w #ENC,&ADC10CTL0 ; Einschalten des ADC > bis.w #ADC10SC,&ADC10CTL0 ; Start sampling/conversion Es scheint so als würdest du ENC setzen und danach versuchen auf ADC10CTL0 zu schreiben. Geht natürlich nicht, wie du selbst im Code Kommentiert hast :)
Jörg S. schrieb: >> bis.w #ENC,&ADC10CTL0 ; Einschalten des ADC > >> bis.w #ADC10SC,&ADC10CTL0 ; Start sampling/conversion > > Es scheint so als würdest du ENC setzen und danach versuchen auf > > ADC10CTL0 zu schreiben. Geht natürlich nicht, wie du selbst im Code > > Kommentiert hast :) Das ADC10SC-Bit ist eines der Steuerbits die sich auch mit gesetztem ENC Bit beschreiben lassen. Zumindest ist das beim 12 Bit ADC vom 447 so, wo es sich ADC12SC nennt. Ich finde leider niergendwo ein vernünftiges Beispiel für den AD Wandler. Die Texas Beispiele sind meist nicht kommentiert und man kann nicht nachvollziehen was dort welcher Befehl genau macht...
Heiko schrieb: > Das ADC10SC-Bit ist eines der Steuerbits die sich auch mit gesetztem ENC > Bit beschreiben lassen. Zumindest ist das beim 12 Bit ADC vom 447 so, wo > es sich ADC12SC nennt. Ja, stimmt... Wobei der User Guide sagt: "ADC10SC and ENC may be set together with one instruction." > Die Texas Beispiele sind meist nicht kommentiert ... Ich würde sagen die Beispiele sind schon sehr gut kommentiert.
Bei mir funktioniert der 2012-ADU prima. Ich hab mich bei der Programmierung an die TI-Beispiele gehalten.
Ich habe mal die Reihenfolge der Steuerbefehle getauscht, das ENC-Bit als letztes wieder gesetzt, leider ohne Erfolg. Die Texas Beispiele laufen bei mir ebenfalls, dennoch wird aus ihnen nicht genau ersichtlich welcher Steuerbefehl genau für welche Aktion zuständig ist. Ich benötige eine Messung an P1.2 ohne Interrupts oder Timernutzung. Solch ein Beispiel gibt es leider nicht... @Uhu Hast du eine asm Routine die Port P1.2 nutzt? Schönen Gruß!
Was willst du denn jetzt eigentlich machen? Dauermessung auf einem Kanal oder nur Einzelmessung?
Da die Anwendung weder Zeitkritisch noch Energietechnisch relevant ist, wollte ich den AD Kanal dauerhaft messen. Die Routiene des AD Kanals wird dann ca. 40 mal aufgerufen, eine Mittelwert berechnet und das Ergebnis ausgewertet. Das ganze Soll auf P1.2 gemessen werden. Evtl. wird später noch ein zweiter AD Eingang benötigt, den ich über eine getrennte Routine, mit weniger Messdurchläufen abrufen möchte.
Heiko schrieb: > Die Routiene des AD Kanals wird dann ca. 40 mal aufgerufen, eine > Mittelwert berechnet und das Ergebnis ausgewertet. Wieso willst du die Routine ständig aufrufen? Es reicht doch die Routine zu beginn einmalig aufzurufen und dann einfach nur noch ADC10MEM zu lesen. Genau darum geht es doch bei der Dauermessung, das du eben gerade NICHT ständig den AD Wandler neu einstellen musst.
Mhm, das stimmt schon. Ich kann auch nur ADC10MEN mehrmals auslesen. Aber das ändert nichts daran, das ich bis jetzt nur 0 als Wert erhalte... Sofern ich dort etwas messen könnte, wäre das mehrmalige Abrufen des MEM eine einfache Sache.
Ja, ich hab in auf P1.2 und P1.3 laufen. Hier mal die wesentlichen Codefragmente, die den ADC10 bedienen:
1 | #define HumiditySensor 0x04 // P1.2 / Pin 4: SHS A5 humiditiy |
2 | #define CondSensor 0x08 // P1.3 / Pin 5: SHS A5 conductance |
3 | |
4 | #define INCH_HumiditySensor INCH_2 // ADC10 Input channel select for HumiditySensor |
5 | #define INCH_CondSensor INCH_3 // ADC10 Input channel select for CondSensor |
6 | |
7 | ; Initialize ADC10 |
8 | mov.w #SREF_0+ADC10SHT_3+ADC10SR+ADC10ON, ADC10CTL0 |
9 | ; SREF_0 Ref. Voltage. VR+ = Vcc and VR- = Vss |
10 | ; ADC10SHT_3 Sample & hold time. 64 x ADC10CLKs = 4µs |
11 | ; ADC10SR Sampling Rate: 50ksps |
12 | ; ~REFOUT Reference output |
13 | ; ~REFBURST Reference burst |
14 | ; ~ADC10MSC Multiple sample and conversion |
15 | ; ~REF2_5V Reference generator: 1.5 V |
16 | ; ~REFON Reference off |
17 | ; ADC10ON ADC10 on on |
18 | ; ~ADC10IE ADC10 interrupt enable |
19 | ; ~ADC10IFG ADC10 interrupt flag |
20 | ; ~ENC Enable conversion |
21 | ; ~ADC10SC ADC10 start conversion |
22 | mov.b #CondSensor+HumiditySensor, ADC10AE0 ; ADC10 sensor input pins |
23 | |
24 | |
25 | ; ------------------------------------------------ |
26 | |
27 | CmpSt_4 ; Conductivity sensor complete - store result |
28 | ; Store conductivity data |
29 | mov.w ADC10MEM, CondSensData ; Store ADC10 result |
Ich hoffe, es nützt dir was.
Vielen Dank für die Antworten. Ich habe das Problem lösen können. Das SHS_1 Bit darf NICHT gesetzt sein. Ist dieses gesetzt wartet der AD Wandler auf einen Interrupt durch Timer A. Dieser wird in der simplen Routiene nicht angesprochen und so wartet er bis in alle Ewigkeit...... Hier noch mal den richtigen Code mit Erläuterung zu jedem Befehl: //Wandlung an Port P1.2 (A2) //__________________________ bic.w #ENC,&ADC10CTL0 ; ENC Bit auf Null setzen, um Steuerbits verändern zu können bis.w #SREF_1,&ADC10CTL0 ; Interne Referenz auswählen = (1) VCC = (2) bis.w #REF2_5V,&ADC10CTL0 ; 2,5 V Referenz auswählen bis.w #REFON,&ADC10CTL0 ; Interne Referenz einschalten bis.w #ADC10SHT_2,&ADC10CTL0 ; Anzahl der Taktzyklen für eine Wandlung (4, 8, 16, 64) bis.w #ADC10SR,&ADC10CTL0 ; Samplingrate des AD Wandlers auf 50 kbs bis.w #ADC10ON,&ADC10CTL0 ; ADC einschalten call #ZEIT3$ ; Wartezeit aufrufen bis.w #ADC10DIV_0,&ADC10CTL1 ; ADC Taktteilung bic.w #SHS_1,&ADC10CTL1 ; Sample / Hold Source 1 nur bei Timer auslösung aktivieren! bis.w #CONSEQ_2,&ADC10CTL1 ; Wiederholte Messung eines AD-Kanals bis.w #INCH_2,&ADC10CTL1 ; Wahl des AD Eingangs (0,1,2,3) bis.b #04h,&ADC10AE0 ; P1.2 ADC10 option select bis.w #ENC,&ADC10CTL0 ; Einschalten des ADC (Steuerefehle blockiert) bis.w #ADC10SC,&ADC10CTL0 ; Start sampling/conversion call #ZEIT3$ ; Wartezeit aufrufen mov.w &ADC10MEM,R8 ; AD Wandler Ergebnis speichern ret
Heiko schrieb:
1 | > bis.w #SREF_1,&ADC10CTL0 ; Interne Referenz auswählen |
2 | > = (1) VCC = (2) |
3 | > bis.w #REF2_5V,&ADC10CTL0 ; 2,5 V Referenz auswählen |
4 | > bis.w #REFON,&ADC10CTL0 ; Interne Referenz |
5 | > einschalten |
6 | > bis.w #ADC10SHT_2,&ADC10CTL0 ; Anzahl der Taktzyklen für |
7 | > eine Wandlung (4, 8, 16, 64) |
8 | > bis.w #ADC10SR,&ADC10CTL0 ; Samplingrate des AD |
9 | > Wandlers auf 50 kbs |
10 | > bis.w #ADC10ON,&ADC10CTL0 ; ADC einschalten |
Du weißt, daß du diese fünf Befehle in einen einzigen packen kannst? (Bei den kleinen Controllern kommt man recht schnell ans Ende der Fahnenstange.)
Ja klar, ich habe sie extra auseinander gezogen um sie übersichtlich darzustellen. Die CTL0 und CTL1 Steuerbefehle lassen sich in zwei Zeilen zusammen fassen. Ist halt nur nicht so übersichtlich... Bei der Anwendung ist der Programmspeicher mehr als ausreichend, zumal ich in Assembler schreibe und von daher eh weniger Code kompiliere.
Heiko schrieb: > Bei der Anwendung ist der Programmspeicher mehr als ausreichend, zumal > ich in Assembler schreibe und von daher eh weniger Code kompiliere. Na ja, wenn die Anwendung einfag genug ist... Ich habe mit ASM schon mal einen voll gekriegt, bevor die Anwendung fertig war.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.