Forums

MSP430 and the ADC12 - Interrupt

Started by adelgald September 14, 2007
Hi - Ive got a problem with a programmend ADC-12 Interrupt. Im new at
the MSP430 uC and dont know much about special registers to set for a
special Timing.

When I started my Program everything is OK, till the moment the first
ADC-Interrupt came. Since then - the ISR - is never leaved. So for
that, how can I set the frequency how often the ISR is fired?

Ive configured it following way:
>> void init_adc() {
>> P6SEL = 0x0F;
>> ADC12CTL0 = ADC12ON + MSC + SHT0_2; // Turn on ADC12, set
sampling time
>> ADC12CTL1 = SHP + CONSEQ_1; // Use sampling timer,
single sequ
>> ADC12MCTL0 = INCH_0; // ref+=AVcc, channel = A0
>> ADC12MCTL1 = INCH_1; // ref+=AVcc, channel = A1
>> ADC12MCTL2 = INCH_2; // ref+=AVcc, channel = A2
>> ADC12MCTL3 = INCH_3 + EOS; // ref+=AVcc, channel = A3,
end seq
>> ADC12IE = 0x08; // Enable interrupt
>> ADC12CTL0 |= ENC; // Conversion enabled
>> }

Maybe the ISR is too long, to return to the main loop - so for that,
here is the ISR:

>> __interrupt void ADC_ISR (void);
>> ADC12_ISR(ADC_ISR)
>> __interrupt void ADC_ISR (void) {
>> printUART("ADC-IR\r\n",sizeof("ADC-IR\r\n"));
>> _BIC_SR_IRQ(CPUOFF);
>> _NOP();
>> }

and the Main-Loop starting the conversion for the first time:
>> while (true){
>> P2OUT ^= 0x02;
>> DC12CTL0 |= ADC12SC;
>> for (i = 0; i < 20000; i++);
>> }

not to forget, Ive got following init-call to initialize the whole
system:

>> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
>> FLL_CTL0 |= XCAP18PF; // Set LoadCap
>> init_adc();
>> _BIS_SR(CPUOFF + GIE);

Now, Its your turn! What do you think about it? Can you possibly tell
me, what the problem could be?

Maybe, do you have some solutions - or something I should try?
Any Ideas?

Thanks for Help
Andreas

Beginning Microcontrollers with the MSP430

Did you initialize the Stack Pointer?

Emmett Redd Ph.D. mailto:E...@missouristate.edu
Professor (417)836-5221
Department of Physics, Astronomy, and Materials Science
Missouri State University Fax (417)836-6226
901 SOUTH NATIONAL Dept (417)836-5131
SPRINGFIELD, MO 65897 USA

A bad day doing research is better than a good day doing something else.

________________________________

From: m... [mailto:m...] On
Behalf Of adelgald
Sent: Friday, September 14, 2007 7:03 AM
To: m...
Subject: [msp430] MSP430 and the ADC12 - Interrupt

Hi - Ive got a problem with a programmend ADC-12 Interrupt. Im
new at
the MSP430 uC and dont know much about special registers to set
for a
special Timing.

When I started my Program everything is OK, till the moment the
first
ADC-Interrupt came. Since then - the ISR - is never leaved. So
for
that, how can I set the frequency how often the ISR is fired?

Ive configured it following way:
>> void init_adc() {
>> P6SEL = 0x0F;
>> ADC12CTL0 = ADC12ON + MSC + SHT0_2; // Turn on ADC12, set
sampling time
>> ADC12CTL1 = SHP + CONSEQ_1; // Use sampling timer,
single sequ
>> ADC12MCTL0 = INCH_0; // ref+=AVcc, channel = A0
>> ADC12MCTL1 = INCH_1; // ref+=AVcc, channel = A1
>> ADC12MCTL2 = INCH_2; // ref+=AVcc, channel = A2
>> ADC12MCTL3 = INCH_3 + EOS; // ref+=AVcc, channel = A3,
end seq
>> ADC12IE = 0x08; // Enable interrupt
>> ADC12CTL0 |= ENC; // Conversion enabled
>> }

Maybe the ISR is too long, to return to the main loop - so for
that,
here is the ISR:

>> __interrupt void ADC_ISR (void);
>> ADC12_ISR(ADC_ISR)
>> __interrupt void ADC_ISR (void) {
>> printUART("ADC-IR\r\n",sizeof("ADC-IR\r\n"));
>> _BIC_SR_IRQ(CPUOFF);
>> _NOP();
>> }

and the Main-Loop starting the conversion for the first time:
>> while (true){
>> P2OUT ^= 0x02;
>> DC12CTL0 |= ADC12SC;
>> for (i = 0; i < 20000; i++);
>> }

not to forget, Ive got following init-call to initialize the
whole
system:

>> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
>> FLL_CTL0 |= XCAP18PF; // Set LoadCap
>> init_adc();
>> _BIS_SR(CPUOFF + GIE);

Now, Its your turn! What do you think about it? Can you possibly
tell
me, what the problem could be?

Maybe, do you have some solutions - or something I should try?
Any Ideas?

Thanks for Help
Andreas
The c-startup should have done that.

--- In m..., "Redd, Emmett R" wrote:
>
> Did you initialize the Stack Pointer?
>
> Emmett Redd Ph.D. mailto:EmmettRedd@...
> Professor (417)836-5221
> Department of Physics, Astronomy, and Materials Science
> Missouri State University Fax (417)836-6226
> 901 SOUTH NATIONAL Dept (417)836-5131
> SPRINGFIELD, MO 65897 USA
>
> A bad day doing research is better than a good day doing something else.
>
> ________________________________
>
> From: m... [mailto:m...] On
> Behalf Of adelgald
> Sent: Friday, September 14, 2007 7:03 AM
> To: m...
> Subject: [msp430] MSP430 and the ADC12 - Interrupt
>
>
>
> Hi - Ive got a problem with a programmend ADC-12 Interrupt. Im
> new at
> the MSP430 uC and dont know much about special registers to set
> for a
> special Timing.
>
> When I started my Program everything is OK, till the moment the
> first
> ADC-Interrupt came. Since then - the ISR - is never leaved. So
> for
> that, how can I set the frequency how often the ISR is fired?
>
> Ive configured it following way:
> >> void init_adc() {
> >> P6SEL = 0x0F;
> >> ADC12CTL0 = ADC12ON + MSC + SHT0_2; // Turn on ADC12, set
> sampling time
> >> ADC12CTL1 = SHP + CONSEQ_1; // Use sampling timer,
> single sequ
> >> ADC12MCTL0 = INCH_0; // ref+=AVcc, channel = A0
> >> ADC12MCTL1 = INCH_1; // ref+=AVcc, channel = A1
> >> ADC12MCTL2 = INCH_2; // ref+=AVcc, channel = A2
> >> ADC12MCTL3 = INCH_3 + EOS; // ref+=AVcc, channel = A3,
> end seq
> >> ADC12IE = 0x08; // Enable interrupt
> >> ADC12CTL0 |= ENC; // Conversion enabled
> >> }
>
> Maybe the ISR is too long, to return to the main loop - so for
> that,
> here is the ISR:
>
> >> __interrupt void ADC_ISR (void);
> >> ADC12_ISR(ADC_ISR)
> >> __interrupt void ADC_ISR (void) {
> >> printUART("ADC-IR\r\n",sizeof("ADC-IR\r\n"));
> >> _BIC_SR_IRQ(CPUOFF);
> >> _NOP();
> >> }
>
> and the Main-Loop starting the conversion for the first time:
> >> while (true){
> >> P2OUT ^= 0x02;
> >> DC12CTL0 |= ADC12SC;
> >> for (i = 0; i < 20000; i++);
> >> }
>
> not to forget, Ive got following init-call to initialize the
> whole
> system:
>
> >> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> >> FLL_CTL0 |= XCAP18PF; // Set LoadCap
> >> init_adc();
> >> _BIS_SR(CPUOFF + GIE);
>
> Now, Its your turn! What do you think about it? Can you possibly
> tell
> me, what the problem could be?
>
> Maybe, do you have some solutions - or something I should try?
> Any Ideas?
>
> Thanks for Help
> Andreas
>
>
>
>
>
>
>
Hi Andreas,

I know from the MSP430x1xx series that in the ADC12 module there is a combined Interrupt Flag Vector which holds all the flags of the ADC - Overflow, Timer Overflow and 15 conversion memory registers. According to the User Manual (ADC12 - Operation), the IFG's for the 15 memory registers are NOT reset just by entering the ISR. You have to reset them by software or by reading the appropriate memory register which triggered the interrupt. From your code I see that you use conversion registers 0-3 , but in your ISR there is no reading of those memory registers or resetting of their IFG's in the ADC12IV register. What happens is that the interrupt happens again and again until all the flags are cleared. If you don't have any use of the conversion values, then you can just do: "ADC12IV = 0;".

Try to see the documentation on your MSP series, under the ADC12 chapter.
Regards,

Moshe Goren
Embedded Real-Time Programmer

Kinarot Technological Incubator
Zemach, Jordan Valley Israel 15132
Tel: +972-4-6709018, Mobile: +972-50-6869248
E-mail: m...@eltav.com
Web: www.eltav.com