EmbeddedRelated.com
Forums

Timer A and Interrupt Problem

Started by projecttamim January 7, 2005
Hi,
I am trying to write a program that will take 450 analog signals from 
pin 6. I want the program to take the signal when at a specific rate 
so iam using TimerA interrupts to start the A/D conversions. But for 
some reason when the ISR is called the program keeps looping inside 
the ISR. However it doesnt stay inside the ISR all the time. Does 
any1 Know what the problem is? Thank You!

Tamim

#include  <io430x14x.h>
#include  <intrinsics.h>
#define   AE_Samples   450

int i;

static unsigned int AE_results[AE_Samples];     

void main(void)
{
  __disable_interrupt();
   WDTCTL = WDTPW+WDTHOLD;               // Stop watchdog timer

   P6SEL |= 0x01;                        // Enable A/D channel A0
   CCTL0 = CM_0;                         // No Captures, enable  
compare mode
   ADC12CTL0 = ADC12ON+SHT0_2;           // Turn on ADC12, set 
sampling time
   ADC12MCTL0 = SREF_2;                  // The voltage reference is 
applied externally through Pin Vr+
   ADC12CTL1 = SHP;                      // Use sampling timer

   TACTL = TASSEL_1+MC_1+TAIE;                // Timer_A setup, UP 
mode,Crystal,Enable Time_A interrupt
   
    __enable_interrupt();  // Re-enable interrupts

 for(i=0;i<AE_Samples;i++)
 {

   TACCTL0_bit.CCIFG = 0;  // I must explicity clear CCIFG so that 
other things wont cause interrupts
   TACCTL0 = CCIE;                       //Enable interupts
   TACCR0 = 0xFF;                      // Compare value (Depends on 
the Crystal used),Enable CCIFG at this value
                                       //The value depends on number 
of clock cycles passed and crystal used
 }
 
}

  #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A0_ISR(void)      // The set delay has 
passed i.e. the timer has counted
   {
        ADC12CTL0 |= ENC;                        // Enable conversions
        ADC12CTL0 |= ADC12SC;                   // Start conversion

        ADC12CTL0 &= ~ENC;                     // Clear ENC bit, SET 
BREAKPOINT HERE
        while ((ADC12CTL1 & ADC12BUSY) == 1); // ADC12BUSY?
        AE_results[i] = ADC12MEM0;            // Move results, IFG is 
cleared
        TACCTL0_bit.CCIFG = 0;
   

    }





Beginning Microcontrollers with the MSP430

projecttamim wrote:

>   #pragma vector=TIMERA0_VECTOR
>     __interrupt void Timer_A0_ISR(void)      // The set delay has 
> passed i.e. the timer has counted
>    {
>         ADC12CTL0 |= ENC;                        // Enable conversions
>         ADC12CTL0 |= ADC12SC;                   // Start conversion
> 
>         ADC12CTL0 &= ~ENC;                     // Clear ENC bit, SET 
> BREAKPOINT HERE
>         while ((ADC12CTL1 & ADC12BUSY) == 1); // ADC12BUSY?
>         AE_results[i] = ADC12MEM0;            // Move results, IFG is 
> cleared
>         TACCTL0_bit.CCIFG = 0;
>    
> 
>     }

It is good programming practice to include a return(); statement, even 
in functions that do not or cannot return a value. This might prove 
helpful in your case...

~Dave

Tamin,

in your code I didn't see the clock initialization routine, which is 
very important! Take a look at chapter 4 of the user's guide. Have you 
checked what clock sources are you using for timer A and ADC? Are they 
according to your hardware?

Regards,
Adriano.

projecttamim wrote:
> 
> Hi,
> I am trying to write a program that will take 450 analog signals from 
> pin 6. I want the program to take the signal when at a specific rate 
> so iam using TimerA interrupts to start the A/D conversions. But for 
> some reason when the ISR is called the program keeps looping inside 
> the ISR. However it doesnt stay inside the ISR all the time. Does 
> any1 Know what the problem is? Thank You!
> 
> Tamim
> 
> #include  <io430x14x.h>
> #include  <intrinsics.h>
> #define   AE_Samples   450
> 
> int i;
> 
> static unsigned int AE_results[AE_Samples];     
> 
> void main(void)
> {
>   __disable_interrupt();
>    WDTCTL = WDTPW+WDTHOLD;               // Stop watchdog timer
> 
>    P6SEL |= 0x01;                        // Enable A/D channel A0
>    CCTL0 = CM_0;                         // No Captures, enable  
> compare mode
>    ADC12CTL0 = ADC12ON+SHT0_2;           // Turn on ADC12, set 
> sampling time
>    ADC12MCTL0 = SREF_2;                  // The voltage reference is 
> applied externally through Pin Vr+
>    ADC12CTL1 = SHP;                      // Use sampling timer
> 
>    TACTL = TASSEL_1+MC_1+TAIE;                // Timer_A setup, UP 
> mode,Crystal,Enable Time_A interrupt
>    
>     __enable_interrupt();  // Re-enable interrupts
> 
>  for(i=0;i<AE_Samples;i++)
>  {
> 
>    TACCTL0_bit.CCIFG = 0;  // I must explicity clear CCIFG so that 
> other things wont cause interrupts
>    TACCTL0 = CCIE;                       //Enable interupts
>    TACCR0 = 0xFF;                      // Compare value (Depends on 
> the Crystal used),Enable CCIFG at this value
>                                        //The value depends on number 
> of clock cycles passed and crystal used
>  }
>  
> }
> 
>   #pragma vector=TIMERA0_VECTOR
>     __interrupt void Timer_A0_ISR(void)      // The set delay has 
> passed i.e. the timer has counted
>    {
>         ADC12CTL0 |= ENC;                        // Enable conversions
>         ADC12CTL0 |= ADC12SC;                   // Start conversion
> 
>         ADC12CTL0 &= ~ENC;                     // Clear ENC bit, SET 
> BREAKPOINT HERE
>         while ((ADC12CTL1 & ADC12BUSY) == 1); // ADC12BUSY?
>         AE_results[i] = ADC12MEM0;            // Move results, IFG is 
> cleared
>         TACCTL0_bit.CCIFG = 0;
>    
> 
>     }
> 
> 
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 

Arggh! Why are you still trying to run your A/D sample from within the 
TimerA ISR? In my last response I pojn ted out to you thagt there is a 
timer trigger mode that enables A/D samples to be directly triggered by 
the timer without all the bit polling and other half assed stuff. In 
your first post you didin't mention wanting to run 450 samples, but 
adding a counter to the timer compare ISR is simple. You need to study 
the timer triggered mode of the ADC. It is clearly explained in the user 
Guide, and I, and others have desfribed it and posted sample code in the 
past.

Al

projecttamim wrote:

> 
> Hi,
> I am trying to write a program that will take 450 analog signals from 
> pin 6. I want the program to take the signal when at a specific rate 
> so iam using TimerA interrupts to start the A/D conversions. But for 
> some reason when the ISR is called the program keeps looping inside 
> the ISR. However it doesnt stay inside the ISR all the time. Does 
> any1 Know what the problem is? Thank You!
> 
> Tamim
> 
> #include  <io430x14x.h>
> #include  <intrinsics.h>
> #define   AE_Samples   450
> 
> int i;
> 
> static unsigned int AE_results[AE_Samples];     
> 
> void main(void)
> {
>   __disable_interrupt();
>    WDTCTL = WDTPW+WDTHOLD;               // Stop watchdog timer
> 
>    P6SEL |= 0x01;                        // Enable A/D channel A0
>    CCTL0 = CM_0;                         // No Captures, enable  
> compare mode
>    ADC12CTL0 = ADC12ON+SHT0_2;           // Turn on ADC12, set 
> sampling time
>    ADC12MCTL0 = SREF_2;                  // The voltage reference is 
> applied externally through Pin Vr+
>    ADC12CTL1 = SHP;                      // Use sampling timer
> 
>    TACTL = TASSEL_1+MC_1+TAIE;                // Timer_A setup, UP 
> mode,Crystal,Enable Time_A interrupt
>    
>     __enable_interrupt();  // Re-enable interrupts
> 
>  for(i=0;i<AE_Samples;i++)
>  {
> 
>    TACCTL0_bit.CCIFG = 0;  // I must explicity clear CCIFG so that 
> other things wont cause interrupts
>    TACCTL0 = CCIE;                       //Enable interupts
>    TACCR0 = 0xFF;                      // Compare value (Depends on 
> the Crystal used),Enable CCIFG at this value
>                                        //The value depends on number 
> of clock cycles passed and crystal used
>  }
>  
> }
> 
>   #pragma vector=TIMERA0_VECTOR
>     __interrupt void Timer_A0_ISR(void)      // The set delay has 
> passed i.e. the timer has counted
>    {
>         ADC12CTL0 |= ENC;                        // Enable conversions
>         ADC12CTL0 |= ADC12SC;                   // Start conversion
> 
>         ADC12CTL0 &= ~ENC;                     // Clear ENC bit, SET 
> BREAKPOINT HERE
>         while ((ADC12CTL1 & ADC12BUSY) == 1); // ADC12BUSY?
>         AE_results[i] = ADC12MEM0;            // Move results, IFG is 
> cleared
>         TACCTL0_bit.CCIFG = 0;
>    
> 
>     }
> 
> 
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
> 


This may be elegant(and it is) but now you depend on TA  ISR being enabled.

What about a situation where initial calibration involves a number of  A/D 
conversions before any timer in enabled.
Karl,

>From: onestone <onestone@ones...>
>Reply-To: msp430@msp4...
>To: msp430@msp4...
>Subject: Re: [msp430] Timer A and Interrupt Problem
>Date: Thu, 13 Jan 2005 22:00:37 +1030
>
>
>Arggh! Why are you still trying to run your A/D sample from within the
>TimerA ISR? In my last response I pojn ted out to you thagt there is a
>timer trigger mode that enables A/D samples to be directly triggered by
>the timer without all the bit polling and other half assed stuff. In
>your first post you didin't mention wanting to run 450 samples, but
>adding a counter to the timer compare ISR is simple. You need to study
>the timer triggered mode of the ADC. It is clearly explained in the user
>Guide, and I, and others have desfribed it and posted sample code in the
>past.
>
>Al
>
>projecttamim wrote:
>
> >
> > Hi,
> > I am trying to write a program that will take 450 analog signals from
> > pin 6. I want the program to take the signal when at a specific rate
> > so iam using TimerA interrupts to start the A/D conversions. But for
> > some reason when the ISR is called the program keeps looping inside
> > the ISR. However it doesnt stay inside the ISR all the time. Does
> > any1 Know what the problem is? Thank You!
> >
> > Tamim
> >
> > #include  <io430x14x.h>
> > #include  <intrinsics.h>
> > #define   AE_Samples   450
> >
> > int i;
> >
> > static unsigned int AE_results[AE_Samples];
> >
> > void main(void)
> > {
> >   __disable_interrupt();
> >    WDTCTL = WDTPW+WDTHOLD;               // Stop watchdog timer
> >
> >    P6SEL |= 0x01;                        // Enable A/D channel A0
> >    CCTL0 = CM_0;                         // No Captures, enable
> > compare mode
> >    ADC12CTL0 = ADC12ON+SHT0_2;           // Turn on ADC12, set
> > sampling time
> >    ADC12MCTL0 = SREF_2;                  // The voltage reference is
> > applied externally through Pin Vr+
> >    ADC12CTL1 = SHP;                      // Use sampling timer
> >
> >    TACTL = TASSEL_1+MC_1+TAIE;                // Timer_A
setup, UP
> > mode,Crystal,Enable Time_A interrupt
> >
> >     __enable_interrupt();  // Re-enable interrupts
> >
> >  for(i=0;i<AE_Samples;i++)
> >  {
> >
> >    TACCTL0_bit.CCIFG = 0;  // I must explicity clear CCIFG so that
> > other things wont cause interrupts
> >    TACCTL0 = CCIE;                       //Enable interupts
> >    TACCR0 = 0xFF;                      // Compare value (Depends on
> > the Crystal used),Enable CCIFG at this value
> >                                        //The value depends on number
> > of clock cycles passed and crystal used
> >  }
> >
> > }
> >
> >   #pragma vector=TIMERA0_VECTOR
> >     __interrupt void Timer_A0_ISR(void)      // The set delay has
> > passed i.e. the timer has counted
> >    {
> >         ADC12CTL0 |= ENC;                        // Enable conversions
> >         ADC12CTL0 |= ADC12SC;                   // Start conversion
> >
> >         ADC12CTL0 &= ~ENC;                     // Clear ENC bit,
SET
> > BREAKPOINT HERE
> >         while ((ADC12CTL1 & ADC12BUSY) == 1); // ADC12BUSY?
> >         AE_results[i] = ADC12MEM0;            // Move results, IFG is
> > cleared
> >         TACCTL0_bit.CCIFG = 0;
> >
> >
> >     }
> >
> >
> >
> >
> >
> >
> > .
> >
> >
> > Yahoo! Groups Links
> >
> >
> >
> >
> >
> >
> >
> >
>
>
>
>.
>
>
>Yahoo! Groups Links
>
>
>
>
>
>
>

_________________________________________________________________
Dont just search. Find. Check out the new MSN Search! 
http://search.msn.click-url.com/go/onm00200636ave/direct/01/


Karl Adler wrote:

> This may be elegant(and it is) but now you depend
on TA  ISR being enabled. 
> What about a situation where initial calibration involves a number of  A/D 
> conversions before any timer in enabled.
> Karl,

Sorry Karl, I don't get this. The designer is free to enable and disable 
the Timer ISR at will. Therefore he/she is free to enable it just to 
accomplish this 'calibration period', then free to disable it until 
required later. The timer is running anyway, the AD is ON, therefore it 
isn't a question of power consumption. In fact examining the code 
suggests it is simply a case of poor understanding of how to do this 
task efficiently. Why would you NOT want to enable the TIMER ISR? since 
you have very fine control over its application?

Al

> 
> 
>>From: onestone <onestone@ones...>
>>Reply-To: msp430@msp4...
>>To: msp430@msp4...
>>Subject: Re: [msp430] Timer A and Interrupt Problem
>>Date: Thu, 13 Jan 2005 22:00:37 +1030
>>
>>
>>Arggh! Why are you still trying to run your A/D sample from within the
>>TimerA ISR? In my last response I pojn ted out to you thagt there is a
>>timer trigger mode that enables A/D samples to be directly triggered by
>>the timer without all the bit polling and other half assed stuff. In
>>your first post you didin't mention wanting to run 450 samples, but
>>adding a counter to the timer compare ISR is simple. You need to study
>>the timer triggered mode of the ADC. It is clearly explained in the user
>>Guide, and I, and others have desfribed it and posted sample code in the
>>past.
>>
>>Al
>>
>>projecttamim wrote:
>>
>>
>>>Hi,
>>>I am trying to write a program that will take 450 analog signals
from
>>>pin 6. I want the program to take the signal when at a specific rate
>>>so iam using TimerA interrupts to start the A/D conversions. But for
>>>some reason when the ISR is called the program keeps looping inside
>>>the ISR. However it doesnt stay inside the ISR all the time. Does
>>>any1 Know what the problem is? Thank You!
>>>
>>>Tamim
>>>
>>>#include  <io430x14x.h>
>>>#include  <intrinsics.h>
>>>#define   AE_Samples   450
>>>
>>>int i;
>>>
>>>static unsigned int AE_results[AE_Samples];
>>>
>>>void main(void)
>>>{
>>>  __disable_interrupt();
>>>   WDTCTL = WDTPW+WDTHOLD;               // Stop watchdog timer
>>>
>>>   P6SEL |= 0x01;                        // Enable A/D channel A0
>>>   CCTL0 = CM_0;                         // No Captures, enable
>>>compare mode
>>>   ADC12CTL0 = ADC12ON+SHT0_2;           // Turn on ADC12, set
>>>sampling time
>>>   ADC12MCTL0 = SREF_2;                  // The voltage reference is
>>>applied externally through Pin Vr+
>>>   ADC12CTL1 = SHP;                      // Use sampling timer
>>>
>>>   TACTL = TASSEL_1+MC_1+TAIE;                // Timer_A
setup, UP
>>>mode,Crystal,Enable Time_A interrupt
>>>
>>>    __enable_interrupt();  // Re-enable interrupts
>>>
>>> for(i=0;i<AE_Samples;i++)
>>> {
>>>
>>>   TACCTL0_bit.CCIFG = 0;  // I must explicity clear CCIFG so that
>>>other things wont cause interrupts
>>>   TACCTL0 = CCIE;                       //Enable interupts
>>>   TACCR0 = 0xFF;                      // Compare value (Depends on
>>>the Crystal used),Enable CCIFG at this value
>>>                                       //The value depends on number
>>>of clock cycles passed and crystal used
>>> }
>>>
>>>}
>>>
>>>  #pragma vector=TIMERA0_VECTOR
>>>    __interrupt void Timer_A0_ISR(void)      // The set delay has
>>>passed i.e. the timer has counted
>>>   {
>>>        ADC12CTL0 |= ENC;                        // Enable
conversions
>>>        ADC12CTL0 |= ADC12SC;                   // Start conversion
>>>
>>>        ADC12CTL0 &= ~ENC;                     // Clear ENC bit,
SET
>>>BREAKPOINT HERE
>>>        while ((ADC12CTL1 & ADC12BUSY) == 1); // ADC12BUSY?
>>>        AE_results[i] = ADC12MEM0;            // Move results, IFG
is
>>>cleared
>>>        TACCTL0_bit.CCIFG = 0;
>>>
>>>
>>>    }
>>>
>>>
>>>
>>>
>>>
>>>
>>>.
>>>
>>>
>>>Yahoo! Groups Links
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>>.
>>
>>
>>Yahoo! Groups Links
>>
>>
>>
>>
>>
>>
>>
> 
> 
> _________________________________________________________________
> Dont just search. Find. Check out the new MSN Search! 
> http://search.msn.click-url.com/go/onm00200636ave/direct/01/
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 
>