Forum: Mikrocontroller und Digitale Elektronik Problem mit ADC12 (MSP430) und Window Comparator


von Simon H. (simon12)


Lesenswert?

Hallo,
ich versuche gerade etwas verzweifelt den ADC12_B auf meinem 
MSP430FR5969 zum laufen zu kriegen. Habe den selben Code zunächst auf 
dem MSP430G2553 mit dem ADC10 programmiert. Dort lief alles problemlos. 
Jetzt wollte ich das ganze für den ADC12 anpassen und zusätzlich die 
"Window Comparator"-Funktion nutzen. Aktuell gibt es wohl 2 Probleme: 
Zum einen scheint der Window Comparator nur den ersten Wert den der ADC 
sampled auszuwerten, danach ändert sich in den Registern nichts mehr 
obwohl die Flags resetet werden. Zum anderen funktioniert der ADC nur 
wenn die Intervalle zwischen Start "sampling" und Start "conversion" 
sprich die Zeit in der TA0CCR1 high ist ensprechend lang ist. Wenn ich 
beispielsweise TA0CCR0 auf 2000 setze und TA0CCR1 auf 1000 funktioniert 
alles wunderbar, wenn ich allerdings TA0CCR0 auf 4 und TA0CCR1 auf 1 
setze geht gar nichts. Mit dem ADC10 hat das problemlos funktioniert. 
Und noch eine abschließende Frage: Wozu muss ich denn im Register 
ADC12CTL0 eine Sample und Hold Dauer festlegen, ich dachte wenn ich das 
extern mit dem Timer_A trigger ist die Sample und Hold Dauer die Zeit 
die das SHI-Signal high ist. Oder heißt das nur, dass ab dann gesampelt 
werden kann? Hat sich mir im Datenblatt irgendwie nicht erschlossen :-/

Vielen Dank und viele Grüße
Simon
1
#include <msp430.h>
2
3
int value;
4
5
int main(void) {
6
7
  WDTCTL = WDTPW | WDTHOLD;                 // Stop WDT
8
9
  // GPIO Setup
10
  P1OUT &= ~BIT0;                           // LED2 aus
11
  P1DIR |= BIT0;                            // P1.0/LED2 als Ausgang
12
  P4OUT &= ~BIT6;                           // LED1 aus
13
  P4DIR |= BIT6;                            // P4.6/LED1 als Ausgang
14
  P4SEL1 |= BIT2;                           // P4.2 als ADC Eingang A10
15
  P4SEL0 |= BIT2;
16
17
  PJOUT = 0;                                // Setup XT1
18
  PJSEL0 = BIT4 | BIT5;
19
  PJDIR = 0xFFFF;
20
21
  PM5CTL0 &= ~LOCKLPM5;
22
23
  // XT1 Setup
24
  CSCTL0_H = CSKEY >> 8;                          // Unlock CS registers
25
  CSCTL1 = DCOFSEL_0;                             // Set DCO to 1MHz
26
  CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
27
  CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;           // Set all dividers to 1
28
  CSCTL4 &= ~LFXTOFF;                             // Enable LFXT1
29
  do {
30
    CSCTL5 &= ~LFXTOFFG;                          // Clear XT1 fault flag
31
      SFRIFG1 &= ~OFIFG;
32
  } while (SFRIFG1&OFIFG);                        // Test oscillator fault flag
33
  CSCTL0_H = 0;                                   // Lock CS registers
34
35
  // Configure ADC12
36
  ADC12CTL0 &= ~ADC12ENC;                   // disable ADC12
37
  ADC12CTL0 = ADC12ON;                      // ADC12 on
38
  ADC12CTL1 = ADC12SHS_1;                   // TA0CCR1 als SHS
39
  ADC12CTL2 = ADC12RES_1;                   // 10-bit Auflösung + Low Power Mode
40
  ADC12MCTL0 = ADC12WINC | ADC12INCH_10;    // Window Comparator + A10 als Input
41
  ADC12HI = 0x300;                          // Oberer Threshold 3/4 VDD
42
  ADC12LO = 0x100;                          // Unterer Threshold = 1/4 VDD
43
  ADC12IER0 = ADC12IE0;                     // enable conversion complete Interrupt für ADC12MEM0
44
  ADC12IER2 = ADC12OVIE | ADC12HIIE;        // enable Interrupt für oberen und unteren Threshold des Window Comparators
45
46
  // Configure Timer_A
47
  TA0CTL = TASSEL_1 + MC_1;        // ACLK + Up-Mode
48
  TA0CCTL0 = CCIE;                 // enable Interrupt
49
  TA0CCTL1 = OUTMOD_3;             // PWM Set/Reset
50
  TA0CCR0 = 4;                     // Periode setzen -> 32768/4 = 8192 Messwerte pro Sekunde
51
  TA0CCR1 = 1;                     // Sample-and-hold Dauer 4 - 1 = 3 Takte => ca. 90µS
52
  __bis_SR_register(LPM3_bits + GIE);      // LPM3 + globale Interrupts aktiv
53
}
54
55
#pragma vector = ADC12_VECTOR
56
__interrupt void ADC12_ISR(void) {
57
  switch(__even_in_range(ADC12IV, ADC12IV_ADC12RDYIFG)) {
58
    case ADC12IV_NONE:        break;                // Vector  0:  No interrupt
59
    case ADC12IV_ADC12OVIFG:  break;                // Vector  2:  ADC12MEMx Overflow
60
    case ADC12IV_ADC12TOVIFG: break;                // Vector  4:  Conversion time overflow
61
    case ADC12IV_ADC12HIIFG:                        // Vector  6:  ADC12BHI
62
                  ADC12IFGR2 &= ~ADC12HIIFG;        // Clear Interrupt Flag
63
                  P1OUT |= BIT0;                    // LED2 on
64
                  break;
65
    case ADC12IV_ADC12LOIFG:                        // Vector  8:  ADC12BLO
66
                  ADC12IFGR2 &= ~ADC12LOIFG;        // Clear Interrupt Flag
67
                  P1OUT &= ~BIT0;                   // LED2 off
68
                  break;
69
    case ADC12IV_ADC12INIFG:  break;                // Vector 10:  ADC12BIN
70
    case ADC12IV_ADC12IFG0:   ADC12CTL0 &= ~ADC12ENC;    // Disable ADC12
71
                  P4OUT ^= BIT6;                    // Toggle LED1
72
                  value = ADC12MEM0;
73
                  break;
74
    case ADC12IV_ADC12IFG1:   break;        // Vector 14:  ADC12MEM1
75
    case ADC12IV_ADC12IFG2:   break;        // Vector 16:  ADC12MEM2
76
    case ADC12IV_ADC12IFG3:   break;        // Vector 18:  ADC12MEM3
77
    case ADC12IV_ADC12IFG4:   break;        // Vector 20:  ADC12MEM4
78
    case ADC12IV_ADC12IFG5:   break;        // Vector 22:  ADC12MEM5
79
    case ADC12IV_ADC12IFG6:   break;        // Vector 24:  ADC12MEM6
80
    case ADC12IV_ADC12IFG7:   break;        // Vector 26:  ADC12MEM7
81
    case ADC12IV_ADC12IFG8:   break;        // Vector 28:  ADC12MEM8
82
    case ADC12IV_ADC12IFG9:   break;        // Vector 30:  ADC12MEM9
83
    case ADC12IV_ADC12IFG10:  break;        // Vector 32:  ADC12MEM10
84
    case ADC12IV_ADC12IFG11:  break;        // Vector 34:  ADC12MEM11
85
    case ADC12IV_ADC12IFG12:  break;        // Vector 36:  ADC12MEM12
86
    case ADC12IV_ADC12IFG13:  break;        // Vector 38:  ADC12MEM13
87
    case ADC12IV_ADC12IFG14:  break;        // Vector 40:  ADC12MEM14
88
    case ADC12IV_ADC12IFG15:  break;        // Vector 42:  ADC12MEM15
89
    case ADC12IV_ADC12IFG16:  break;        // Vector 44:  ADC12MEM16
90
    case ADC12IV_ADC12IFG17:  break;        // Vector 46:  ADC12MEM17
91
    case ADC12IV_ADC12IFG18:  break;        // Vector 48:  ADC12MEM18
92
    case ADC12IV_ADC12IFG19:  break;        // Vector 50:  ADC12MEM19
93
    case ADC12IV_ADC12IFG20:  break;        // Vector 52:  ADC12MEM20
94
    case ADC12IV_ADC12IFG21:  break;        // Vector 54:  ADC12MEM21
95
    case ADC12IV_ADC12IFG22:  break;        // Vector 56:  ADC12MEM22
96
    case ADC12IV_ADC12IFG23:  break;        // Vector 58:  ADC12MEM23
97
    case ADC12IV_ADC12IFG24:  break;        // Vector 60:  ADC12MEM24
98
    case ADC12IV_ADC12IFG25:  break;        // Vector 62:  ADC12MEM25
99
    case ADC12IV_ADC12IFG26:  break;        // Vector 64:  ADC12MEM26
100
    case ADC12IV_ADC12IFG27:  break;        // Vector 66:  ADC12MEM27
101
    case ADC12IV_ADC12IFG28:  break;        // Vector 68:  ADC12MEM28
102
    case ADC12IV_ADC12IFG29:  break;        // Vector 70:  ADC12MEM29
103
    case ADC12IV_ADC12IFG30:  break;        // Vector 72:  ADC12MEM30
104
    case ADC12IV_ADC12IFG31:  break;        // Vector 74:  ADC12MEM31
105
    case ADC12IV_ADC12RDYIFG: break;        // Vector 76:  ADC12RDY
106
    default: break;
107
  }
108
}
109
110
// Timer A0 interrupt service routine
111
#pragma vector=TIMER0_A0_VECTOR
112
__interrupt void Timer_A(void)
113
{
114
  ADC12CTL0 |= ADC12ENC;                         // ADC10 enable set
115
}

von Family User Guide hilft (Gast)


Lesenswert?

Es gibt zwei Samplemodus. Extended und Puls. Du möchtest im Extended 
Mode samplen.

Der ADC braucht ein paar Clocks zum wandeln. Die Sample Geschwindigkeit 
musst du darauf anpassen.

von Simon H. (simon12)


Lesenswert?

Kurzes Status Update: Window Comparator arbeitet inzwischen, hatte den 
falschen Interrupt aktiviert. Beim ADC hatte ich das SAMPCON Signal 
nicht auf externen Trigger gesetzt. Jetzt komm ich immerhin schon in den 
Bereich von 2kHz Samplerate aber zu den gewünschten 6-8kHz fehlt noch 
etwas... Soweit ich das Datenblatt verstanden habe verwende ich den 
"Extended Mode", d.h. das SHI Signal wird über Timer_A gesetzt und das 
SHI Signal setzt automatisch das SAMPCON Signal. Die Clock des ADC läuft 
wohl bei 5 MHz d.h. während eines Taktes der Timer_A Clock (32kHz) 
sollte definitiv eine Konversion stattfinden können. Oder liegt das am 
Window Comparator? Können die Interrupts die Ausführung soweit 
verzögern?

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.