Hallo zusammen, ich habe folgendes Problem: Der MSP wartet im LP-Mode bis ein WD-Irq auftritt. Nach einer best. Anzahl irqs wird die Batteriespannung mit dem ADC10 gesampelt. Da klappt auch sehr gut. Aber es gibt sporadisch Fehlmessungen. Ich habe keine Idee woher das kommen kann. Wo fange ich an zu suchen? Anbei eine Datei die die Messungen zeigen. Es gibt an zwei Stellen Ausreisser. Ansonsten immer gute Messungen über Stunden. Danke und Gruß, Peter
Der Source Code wäre interessanter als die Messwerte. Messung mit MSP Ref.Spg? Wird gewartet bis Ref.Spg korrekt anliegt?
Hallo, >Messung mit MSP Ref.Spg? Ja >Wird gewartet bis Ref.Spg korrekt anliegt? Nein. Gerade im Manual gelesen: " The total settling time when REFON becomes set is 30 us." Werde vor dem Setzen von ENC 30us warten und prüfen ob es weiterhin diese Ausreisser gibt. Danke für den Tip. Anbei mein Code. Habt ihr sonst noch Hinweise? Peter
Hier der Code (war in der ersten Mail mit Formatierung drin, ist aber irgendwie verschwunden. Jetzt nochmal ohne Formatierung. unsigned short read_ubatt(void){ unsigned long calc; ADC10CTL1 = ADC10DIV_3 + INCH_0; ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ENC + ADC10SC; _BIS_SR(CPUOFF + GIE); // LPM0 with interrupts enabled calc = ((unsigned long)ADC10MEM*(unsigned long)1500); return calc/1023; } // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { ADC10CTL0 &= ~(ENC + ADC10SC); _BIC_SR_IRQ(CPUOFF); // Clear CPUOFF bit from 0(SR) }
Bist Du Dir auch sicher, dass Deine Batteriespannung konstant bleibt während der Messung? Ich meine, wenn Du einen Impuls-artigen Verbraucher dranhängen hast, dann wirst Du auch Spannungseinbrüche mit dem ADC messen. Die Chance diese Einbrüche zu "treffen" ist gering, deshalb vielleicht auch nur die sporadischen "Fehlmessungen"! Was noch fehlt ist der Code für den WDT-IRQ. Gruß Stefan
> Werde vor dem Setzen von ENC 30us warten und prüfen ob es > weiterhin diese Ausreisser gibt. Die Zeit ist stark abhängig vom Kondensator der am Vref Pin hängt (den du hoffentlich verwendest). Am besten mit den Oszi messen wie schnell der sich läd und das Delay entsprechend anpassen.
>Die Zeit ist stark abhängig vom Kondensator der am Vref Pin hängt (den >du hoffentlich verwendest) Ich weiß jetzt nicht auswendig wie das bei anderen MSP430 Typen ist, aber bei den MSP430x1xx braucht man an Vref keinen Kondensator, vorallem nicht, wenn man die interne Referenzspannung benutzt (was ja aus dem Code-Schnipsel hervorgeht). Zum Entkoppeln reicht laut User-Guide 10uF parallel mit 100nF zwischen Vcc und Vss!
Bei den anderen MSPs könnte man sich das auch sparen, ist halt die Frage wie genau der AD Wandler betrieben werden soll.
Den Kondensator (100nf || 10µF) an Vref braucht man bei den F1xx Typen genauso. Steht im Datenblatt. Ich habs auch mehrfach ohne probiert, da kommen keine reproduzierbare Ergebnisse raus. Gabs nicht auch irgendwo ein Bit, das man setzen kann, damit während der eigentlichen Messung die CPU abgeschaltet wird, um Störungen zu vermeiden?
Man kann in Low Power Mode gehen, macht er ja auch schon :
1 | _BIS_SR(CPUOFF + GIE); // LPM0 with interrupts |
Also um Missverständnisse zu vermeiden: Für den ADC10, um den es sich in dieser Frage handelt, braucht man an Vref KEINEN Kondensator. Denn an Vref liegt überhaupt keine Ref-Spannung an, solangen man nicht explizit REFOUT in ADC10CTL0 setzt (was aber für eine Messung nicht notwendig ist)!
@Peter: Dein Code-Bsp. ist meiner Meinung nach nicht ganz optimal ;-) In 'read_ubatt(void)' startest Du eine conversion und legst die CPU danach schlafen. Sobald der ADC10 fertig ist, weckst Du die CPU in 'ADC10_ISR (void)' wieder auf, um dann in 'read_ubatt(void)' die Berechnung durchzuführen. D.h. die CPU ist nur für ein paar µs aus... lohnt sich das? Ich würde den ADC einmalig nach µC-Reset initialisieren, etwa so: <init>: ... ADC10CTL0 &= ~ENC; ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON; ADC10CTL1 = ADC10DIV_3 + INCH_0; ADC10AE = ADC10AE0; // enable analog input A0 ADC10CTL0 |= ENC; ... In deiner Funktion dann Batteriespannung messen und danach LPM: <read_ubatt>: ADC10CTL0 |= ADC10SC; // Start conversion while(!ADC10CTL0 & ADC10IFG); // warten bis conversion fertig ... Berechnung ... _BIS_SR(CPUOFF + GIE); // LPM0 Aufwecken der CPU über WDT-ISR: #pragma vector=WDT_VECTOR __interrupt void WDT_ISR (void) { _BIC_SR_IRQ(CPUOFF); } So in etwa zumindest als Anregung!
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.