Hi, i have two strange problems with the ADC12 in the MSP430F149: - When i set MCLK = SMCLK = ACLK = LFXT1 (2768 Hz ) with BCSCTL2 SELM1 + SELM0; i get a hangup independent from the ADC12 core clock (tested with ACLK and ADC12OSC). With switched of ADC12 the low cpu clock is no problem. - Setting ADC12IFG = 0 at the end of the ADC12 ISR does not clear the interrupt flags; i get approx. 14.000 ADC12 irqs per second! When i set volatile unsigned int trash = ADC12IV + ADC12MEM0 + ... + ADC12MEM15; the interrupt flags are cleared and i do get the usual 721 ADC12 irqs per second. I'm using IAR 1.26 and a repeated sequence of channels mode which works fine with internal temperature measurement and others. What might be the reasons of these strange bugs? Regards Rolf F.
strange ADC12 problems
Started by ●February 26, 2004
Reply by ●February 26, 20042004-02-26
Rolf F. wrote: > Hi, > > i have two strange problems with the ADC12 in the MSP430F149: > > - When i set MCLK = SMCLK = ACLK = LFXT1 (2768 Hz ) with BCSCTL2 > SELM1 + SELM0; Lets examine this first. BSCTL2 = SELM0+SEM1 sets MCLK = LFXT1CLK DIVMx = 0 so MCLK = /1 ACLK = LFXT1CLK by default SELS = 0 so SMCLK = DCO DIVSx = 0 so SMCLK = DCO/1 DCOR = internal resistor. Your first statement is wrong. You haven't shown any of the settings for ADC12 either i get a hangup independent from the ADC12 core clock > (tested with ACLK and ADC12OSC). With switched of ADC12 the low cpu > clock is no problem. > > - Setting ADC12IFG = 0 at the end of the ADC12 ISR does not clear the > interrupt flags; i get approx. 14.000 ADC12 irqs per second! All to do with slow MCLK vs fast ADC clock I suggest. If you select ACLK as the source for ADC12CLk then you have avery slow ADC clock that may (since we can't see your ADC config) be specifiying values that become illegal, ie conversion times too long, on the other hand ADC12OSC is nominally 5MHz, if you used this with high speed convrsion settings you could be converting faster than the slow MCLK can handle. > When i set > volatile unsigned int trash = ADC12IV + ADC12MEM0 + ... + ADC12MEM15; > the interrupt flags are cleared and i do get the usual 721 ADC12 > irqs per second. What is usual? This statement suggests that you have set up your sample and conversion rates as if the ADC12CLk was derived from MCLK, when it doesn't appear to be (although you haven;'t given the ADC config) This precisely explains the behaviour of the above. While your slow MCLK is clearing adc12IFG other interrupts are occuring, and ADC12IV is set, you have effectively cleared all of the pending ints through the back door. Cheers Al > > I'm using IAR 1.26 and a repeated sequence of channels mode which works > fine with internal temperature measurement and others. > What might be the reasons of these strange bugs? > > Regards > > Rolf F.
Reply by ●February 27, 20042004-02-27
Hi, > SELS = 0 so SMCLK = DCO thanks, that's the bug because the MSP430F149 is a three oszillator system (although with the ADC12OSC it has four oscillators) and therefore only DCOCLK or XT2CLK and not XT1CLK can be selected. > If you select ACLK > as the source for ADC12CLk then you have avery slow ADC clock that may > (since we can't see your ADC config) be specifiying values that become > illegal, ie conversion times too long, on the other hand ADC12OSC is > nominally 5MHz, if you used this with high speed convrsion settings you > could be converting faster than the slow MCLK can handle. That must be the reason. >> When i set >> volatile unsigned int trash = ADC12IV + ADC12MEM0 + ... + ADC12MEM15; >> the interrupt flags are cleared and i do get the usual 721 ADC12 >> irqs per second. > > > What is usual? This statement suggests that you have set up your sample > and conversion rates as if the ADC12CLk was derived from MCLK, when it > doesn't appear to be (although you haven;'t given the ADC config) This > precisely explains the behaviour of the above. While your slow MCLK is > clearing adc12IFG other interrupts are occuring, and ADC12IV is set, you > have effectively cleared all of the pending ints through the back door. That can't be the reason because with WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL1 = 0x87; // ACLK = LFXT1CTL, divide by 1, lowest nominal frequency, lf oscillator, oscillator on, XT2OFF WDTCTL = 0x5a1f; // WD as Timer, 512 Hz TBCTL = 0x0256; TBCCR0 = 41430; TBCCTL0 = 0x0080; //ADC12 // Sample rate approx 1.56 ms ADC12CTL0 &= ~0x0002; // Clear ENC (Stop ADC12) ADC12CTL0 = 0x00b0; // ADC12 On, REF=1.5V On, Multiple Conv On, Tsample=4xADC12CLK, ADC12CTL1 = 0x0a0e; // Repeat sequence of channel mode, ACLK, Div by 1, TimerB.Out0 ADC12MCTL0 = 0x10; // Channel=0 (Hand puls sample 1), Vref=Vref+/AVss ADC12MCTL1 = 10 + SREF_1; // temperature diode, first reference voltage ADC12MCTL2 = 10 + SREF_1; ADC12MCTL3 = 0x10; ADC12MCTL4 = 10 + SREF_1; ADC12MCTL5 = 10 + SREF_1; ADC12MCTL6 = 0x10; ADC12MCTL7 = 10 + SREF_1; ADC12MCTL8 = 10 + SREF_1; ADC12MCTL9 = 0x10; ADC12MCTL10 = 10 + SREF_1; ADC12MCTL11 = 0x80 + 10 + SREF_1; // end of cyle ( ADC12MCTL12..15 unused) ADC12IE = 0x0fb6; // ADC12 memory 1,2,4,5,7,8,9,10,11 interrupts enable (period 6.23 ms) // = Enable Temperature (Chest Puls) IRQs ADC12CTL0 |= 0x0002; // Set ENC (Start ADC12) #ifndef QuArTz BCSCTL1 |= 0x07; // set RSEL for highest possible DCO frequency BCSCTL2 = SELM0; // 0x00 or SELM0: divide by 1 for SMCLK and MCLK, internal resistor on for failsafe mode, source DCOCLK. DCOCTL = 0xff; // highest possible frequency with highest 3 bits set #else BCSCTL1 &= ~XT2OFF; // XT2on do // wait for MCLK from quartz { volatile unsigned char foo; IFG1 &= ~OFIFG; // Clear OSCFault flag for (foo=0xff; foo; foo--); // Time for flag to set } while (IFG1 & OFIFG); // OSCFault flag still set? BCSCTL2 = SELM1 + SELS; // LFXT2: use HF quartz (XT2), internal resistor on, divide by one, MCLK = SMCLK = XT2 (safe) DCOCTL = 0xe0; #endif i get 14 kHz (instead of 721 Hz) ADC12-irqs without trash= ... int ADC12-ISR or reading the data register associated with the ADC12-IRQ. The software works good with measuring temperature and analog voltages but for tests i took the software and set ADC12IFG=0 in the ADC12-ISR because i don't neet the ADC values. But that's not enough for clearing the ADC12-irqs and i don't know why. Regards Rolf F.
Reply by ●February 27, 20042004-02-27
Rolf F. wrote: > Hi, > > >>SELS = 0 so SMCLK = DCO > > > thanks, that's the bug because the MSP430F149 is a three oszillator > system (although with the ADC12OSC it has four oscillators) and > therefore only DCOCLK or XT2CLK and not XT1CLK can be selected. Glad to help, there were a few possibilities, so I gave all I could think of. > > > >>If you select ACLK >>as the source for ADC12CLk then you have avery slow ADC clock that may >>(since we can't see your ADC config) be specifiying values that become >>illegal, ie conversion times too long, on the other hand ADC12OSC is >>nominally 5MHz, if you used this with high speed convrsion settings you >>could be converting faster than the slow MCLK can handle. > > > That must be the reason. > > > >>>When i set >>>volatile unsigned int trash = ADC12IV + ADC12MEM0 + ... + ADC12MEM15; >>>the interrupt flags are cleared and i do get the usual 721 ADC12 >>>irqs per second. >> >> >>What is usual? This statement suggests that you have set up your sample >>and conversion rates as if the ADC12CLk was derived from MCLK, when it >>doesn't appear to be (although you haven;'t given the ADC config) This >>precisely explains the behaviour of the above. While your slow MCLK is >>clearing adc12IFG other interrupts are occuring, and ADC12IV is set, you >>have effectively cleared all of the pending ints through the back door. > > > > That can't be the reason because with Ah but I never saw this code, hence my suggestions were based on the little data I had. It looks like SMCLK is still DCO, that Timer B is derved from SMCLK /2, and that you still have a timing problem. Even without the divides, TB is meant to start a sequence of conversions, hence 41430 x your nominal conversion rate of 721/sec gives oscillator speed, and 41430 x 721 = 29,871,030, faster even than I've clocked an MSP. You are also only allowing 4 clocks to sample the signal. To get the most out of the in built ADC requires a very fine balance between adequate sample time/ conversion rate, and the ability of the CPU clock to process the data. Cheers Al > > > WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer > BCSCTL1 = 0x87; // ACLK = LFXT1CTL, divide by 1, lowest > nominal frequency, lf oscillator, oscillator on, XT2OFF > WDTCTL = 0x5a1f; // WD as Timer, 512 Hz > TBCTL = 0x0256; > TBCCR0 = 41430; > TBCCTL0 = 0x0080; > //ADC12 // Sample rate approx 1.56 ms > ADC12CTL0 &= ~0x0002; // Clear ENC (Stop ADC12) > ADC12CTL0 = 0x00b0; // ADC12 On, REF=1.5V On, Multiple Conv > On, Tsample=4xADC12CLK, > ADC12CTL1 = 0x0a0e; // Repeat sequence of channel mode, > ACLK, Div by 1, TimerB.Out0 > ADC12MCTL0 = 0x10; // Channel=0 (Hand puls sample 1), > Vref=Vref+/AVss > ADC12MCTL1 = 10 + SREF_1; // temperature diode, first reference > voltage > ADC12MCTL2 = 10 + SREF_1; > ADC12MCTL3 = 0x10; > ADC12MCTL4 = 10 + SREF_1; > ADC12MCTL5 = 10 + SREF_1; > ADC12MCTL6 = 0x10; > ADC12MCTL7 = 10 + SREF_1; > ADC12MCTL8 = 10 + SREF_1; > ADC12MCTL9 = 0x10; > ADC12MCTL10 = 10 + SREF_1; > ADC12MCTL11 = 0x80 + 10 + SREF_1; // end of cyle ( ADC12MCTL12..15 > unused) > ADC12IE = 0x0fb6; // ADC12 memory 1,2,4,5,7,8,9,10,11 > interrupts enable (period 6.23 ms) > // = Enable Temperature (Chest Puls) IRQs > ADC12CTL0 |= 0x0002; // Set ENC (Start ADC12) > > #ifndef QuArTz > BCSCTL1 |= 0x07; // set RSEL for highest possible DCO > frequency > BCSCTL2 = SELM0; // 0x00 or SELM0: divide by 1 for SMCLK > and MCLK, internal resistor on for failsafe mode, source DCOCLK. > DCOCTL = 0xff; // highest possible frequency with > highest 3 bits set > #else > BCSCTL1 &= ~XT2OFF; // XT2on > do // wait for MCLK from quartz > { > volatile unsigned char foo; > IFG1 &= ~OFIFG; // Clear OSCFault flag > for (foo=0xff; foo; foo--); // Time for flag to set > } > while (IFG1 & OFIFG); // OSCFault flag still set? > BCSCTL2 = SELM1 + SELS; // LFXT2: use HF quartz (XT2), internal > resistor on, divide by one, MCLK = SMCLK = XT2 (safe) > DCOCTL = 0xe0; > #endif > > > i get 14 kHz (instead of 721 Hz) ADC12-irqs without trash= ... int > ADC12-ISR or reading the data register associated with the ADC12-IRQ. > The software works good with measuring temperature and analog voltages > but for tests i took the software and set ADC12IFG=0 in the ADC12-ISR > because i don't neet the ADC values. But that's not enough for clearing > the ADC12-irqs and i don't know why. > > Regards > > Rolf F. > > > > > . > > > Yahoo! Groups Links > > > > > >
Reply by ●February 29, 20042004-02-29
Hi,
>Ah but I never saw this code, hence my suggestions
were based on the
>little data I had. It looks like SMCLK is still DCO, that Timer B is
>derved from SMCLK /2, and that you still have a timing problem. Even
>without the divides, TB is meant to start a sequence of conversions,
>hence 41430 x your nominal conversion rate of 721/sec gives oscillator
>speed, and 41430 x 721 = 29,871,030, faster even than I've clocked an
>MSP. You are also only allowing 4 clocks to sample the signal. To get
>the most out of the in built ADC requires a very fine balance between
>adequate sample time/ conversion rate, and the ability of the CPU clock
>to process the data.
With the DCO at maximum frequency the 41430 give a frequency of 60 Hz.
Because every adc sequence has 12 channels i get appox. 720 conversions/second.
But this does not affect the bug that ADC12IFG=0 does not work; i still have to
use
volatile unsigned int trash = ADC12IV + ADC12MEM0 + ... + ADC12MEM15;
By the way: Does someone has a guide for translating ANSI/ISO-C to IAR-C?
I have some software which works fine on the PC but can't be compiled with
one of the IAR compilers because they don't know e. g. the qualifier
restrict.
Regards
Rolf F.