Forum: Mikrocontroller und Digitale Elektronik MSP430 ADC misst Mist


von Colin M. (colin80)


Lesenswert?

Hallo zusammen,

ich hab gerad ein ganz merkwürdiges ADC-Interrupt Verhalten.
Ich habe einen digitalen Filter im Interrupt am laufen. Bis zu einem 
bestimmten Zeitraum nimmt der msp430f1611 verschiedene Werte auf, die er 
als Array mit 32 Werten speichert. Irgendwann fängt dann der ADC12MEM an 
zu spinnen und misst nur noch dieselben Werte. Gibt es beim ADC auch so 
etwas wie ein Überlauf? Was läuft hier bloß falsch?


1
void INIT_ADC12()
2
{
3
  ADC12CTL0 = ADC12ON | MSC | REFON | REF2_5V | SHT0_15;           // Turn on ADC12, extend sampling time
4
                                            // to avoid overflow of results
5
  ADC12CTL1 = SHP + CONSEQ_3;                 // Use sampling timer, repeated sequence
6
  ADC12MCTL0 = INCH_0 + SREF_1;                      // ref+=AVcc, channel = A0
7
  ADC12MCTL1 = INCH_1 + SREF_1;                      // ref+=AVcc, channel = A1
8
  ADC12MCTL2 = INCH_2 + SREF_1;                      // ref+=AVcc, channel = A2
9
  ADC12MCTL3 = INCH_3 + SREF_1 + EOS;                  // ref+=AVcc, channel = A3, end seq.
10
  ADC12IE = 0x08;                           // Enable ADC12IFG.3
11
  ADC12CTL0 |= ENC;                         // Enable conversions
12
  ADC12CTL0 |= ADC12SC;                     // Start conversion  
13
}
14
15
#pragma vector=TIMERB0_VECTOR
16
__interrupt void Timer_B (void)
17
{ 
18
  P5OUT ^= BIT1;                // Toggle P1.0 
19
  TBCTL ^= MC_1;                //Stoppe Timer B
20
  TACTL ^= MC_1;                //Stoppe Timer A
21
  time= count + TAR ;                  //Hier Zeit aus Timer A rausholen
22
23
  ADC12CTL0 ^= ADC12SC;
24
  ADC12CTL0 ^= ENC;                                                     // Enable conversions
25
  ADC12IE = 0x08;                                                       // Enable ADC12IFG.3*/
26
27
}
28
29
#pragma vector=ADC12_VECTOR
30
__interrupt void ADC12ISR (void)
31
{
32
  A0results = ADC12MEM1;           
33
  mittelwert_filter1(A0results);                  
34
}
35
36
37
int mittelwert_filter1(int newval)
38
{
39
   if (mm < messfenster && newval > 0)                            //Mit dieser if Schleife wird die Fenstrgröße festgelegt
40
                                                  //hier sollte eine 2er potenz für die Größe gewählt werden.
41
   {
42
      avgsum1 [mm]= newval;                       //Wert n-mal aufaddieren
43
      avg += avgsum1[mm];
44
      mm++;                                       //n um eins erhöhen
45
   }
46
   else if( mm == messfenster && newval > 0)
47
   {
48
     avg = avg  - avgsum1[0];
49
     avg += newval;
50
     for(aa=1; aa<messfenster; aa++)
51
     {
52
        avgsum1[aa-1] = avgsum1[aa];
53
        avgsum1[messfenster-1] = newval;
54
     }
55
   }
56
   mittelwert = avg/ mm;
57
}

von Jörg S. (joerg-s)


Lesenswert?

- Was soll Timer B steuern?
- Ist der ADC immer noch Busy (ADC12CTL1) wenn dieselben Werte gemessen 
werden?
- Ist "Bis zu einem bestimmten Zeitraum" immer gleich lang oder 
variabel?

von colin80 (Gast)


Lesenswert?

- Der Timer B misst die Inkremente eines Drehmomentsensors. Solange soll 
auch der ADC gemessen werden.

- Der ADC ist noch Busy. Und das verhalten bleibt auch erhalten, wenn 
ADC ausgeschaltet wird und beim nächsten Messverfahren wieder 
eingeschaltet wird. Heißt, nach dem zweiten Messverfahren bleibt 
ADC12MEM1 auf einen einzigen Wert

- Durch dieses Verschieben im digital-filter kann ich das schwer sagen. 
Mir ist gerad eingefallen wie ich das testen kann. Indem ich zähle, wie 
oft der ADC Interrupt auftritt. Wenn ich mich nicht täusche, dann tritt 
es immer an derselben stelle auf. Kann ich morgen erst testen. An 
variabel kann es nicht liegen, weil Mittelwert und avg volatile unsigned 
long Datentypen sind.

Testweise habe ich das Messfenster auf 500 statt 32 vergrößert, um zu 
schauen, wann immer gleiche Werte rauskommen. Hier kann ich nicht so 
genau sagen, wie oft schon verschoben worden ist, aber dann sieht das 
ungefähr so aus:

avgsum1[450]= 36
avgsum1[451]= 40
avgsum1[452]= 25
avgsum1[453]= 32
avgsum1[454]= 41
avgsum1[455]= 35
avgsum1[456]= 35
avgsum1[457]= 35
avgsum1[458]= 35
avgsum1[459]= 35
avgsum1[460]= 35 usw.

von colin (Gast)


Lesenswert?

Hat niemand eine Idee? Stoppe ich die conversation überhaupt richtig?

von Jörg S. (joerg-s)


Lesenswert?

Bist du sicher das es am ADC liegt und nicht an der Berechnung von 
avgsum1[]?

Das einzige was mir noch auffällt ist
  ADC12CTL0 ^= ADC12SC;
  ADC12CTL0 ^= ENC;
Normalerweise setzt man die beim einschalten immer zusammen. ("ADC12SC 
and ENC may be set together with one instruction")

von source reader (Gast)


Lesenswert?

colin schrieb:
> Hat niemand eine Idee?

Du zeigst uns nur einen Teil der Quelle. Soll das ein Ratespiel werden?

Beschreibe einmal was du überhaupt machen willst, wie dein gedachter 
Programmfluss ist und hänge das vollständige Programm an.

Du bekommst dann Tipps zur Optimierung der Problemlösung und Tipps zur 
Programmierung.

Die Profis hier helfen gerne, machen aber nicht deinen Job. ;-P

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
Noch kein Account? Hier anmelden.