This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

The ADC12 interrupt service routine.

I have saw some sample coding from TI website that they use the ISR for ADC12 like below:

#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{
  static unsigned int index = 0;

  switch(__even_in_range(ADC12IV,34))
  {
  case  0: break;                           // Vector  0:  No interrupt
  case  2: break;                           // Vector  2:  ADC overflow
  case  4: break;                           // Vector  4:  ADC timing overflow
  case  6: break;                           // Vector  6:  ADC12IFG0
  case  8: break;                           // Vector  8:  ADC12IFG1
  case 10: break;                           // Vector 10:  ADC12IFG2
  case 12:                                  // Vector 12:  ADC12IFG3
    A0results[index] = ADC12MEM0;           // Move A0 results, IFG is cleared
    A1results[index] = ADC12MEM1;           // Move A1 results, IFG is cleared
    A2results[index] = ADC12MEM2;           // Move A2 results, IFG is cleared
    A3results[index] = ADC12MEM3;           // Move A3 results, IFG is cleared
    index++;                                // Increment results index, modulo; Set Breakpoint1 here
   
    if (index == 8)
    {
      (index = 0);
    }
  case 14: break;                           // Vector 14:  ADC12IFG4
  case 16: break;                           // Vector 16:  ADC12IFG5
  case 18: break;                           // Vector 18:  ADC12IFG6
  case 20: break;                           // Vector 20:  ADC12IFG7
  case 22: break;                           // Vector 22:  ADC12IFG8
  case 24: break;                           // Vector 24:  ADC12IFG9
  case 26: break;                           // Vector 26:  ADC12IFG10
  case 28: break;                           // Vector 28:  ADC12IFG11
  case 30: break;                           // Vector 30:  ADC12IFG12
  case 32: break;                           // Vector 32:  ADC12IFG13
  case 34: break;                           // Vector 34:  ADC12IFG14
  default: break;
  } 
}

Is this coding the recommended way of writing the ISR for getting the ADC12 results?

Could anybody explain on the switch case function? Is it that the CPU will go down from case 0 to case 34 and set an interrupt flag for ADC12IFG0 to ADC12IFG14 along its way?

 

  • I found out that i still can get the ADC result without the switch case function like the coding shown below:

    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12ISR (void)
    {
      static unsigned int index = 0;

       A0results[index] = ADC12MEM0;           // Move A0 results, IFG is cleared
        A1results[index] = ADC12MEM1;           // Move A1 results, IFG is cleared
        A2results[index] = ADC12MEM2;           // Move A2 results, IFG is cleared
        A3results[index] = ADC12MEM3;           // Move A3 results, IFG is cleared
        index++;                                // Increment results index, modulo; Set Breakpoint1 here
       
        if (index == 8)
        {
          (index = 0);
        }

    }

    Then what's the point of using switch case in the sample coding?

  • The ADC12 interrupt is a shared interrupt. So you need to read the index to determine who generated the interrupt. If you only have one interrupt enabled, you probably don't need to use the switch/case function. But I would still use an if statement to check for the specific index you are looking for so that other interrupts or a zero index don't mess you up. 

  • Timothy Barr said:

    The ADC12 interrupt is a shared interrupt. So you need to read the index to determine who generated the interrupt. If you only have one interrupt enabled, you probably don't need to use the switch/case function. But I would still use an if statement to check for the specific index you are looking for so that other interrupts or a zero index don't mess you up. 

    Thanks for the comments.

    Is the ISR that I mentioned above a forever loop? Which means it doesn't go back to the main() routine anymore? Or it occasionally will goes back to the main() routine? Below is the main() routine for your review:

    void main(void)
    {
      WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer
      P6SEL = 0x0F;                             // Enable A/D channel inputs
      ADC12CTL0 = ADC12ON+ADC12MSC+ADC12SHT0_8; // Turn on ADC12, extend sampling time
                                                // to avoid overflow of results
      ADC12CTL1 = ADC12SHP+ADC12CONSEQ_3;       // Use sampling timer, repeated sequence
      ADC12MCTL0 = ADC12INCH_0;                 // ref+=AVcc, channel = A0
      ADC12MCTL1 = ADC12INCH_1;                 // ref+=AVcc, channel = A1
      ADC12MCTL2 = ADC12INCH_2;                 // ref+=AVcc, channel = A2
      ADC12MCTL3 = ADC12INCH_3+ADC12EOS;        // ref+=AVcc, channel = A3, end seq.
      ADC12IE = 0x08;                           // Enable ADC12IFG.3
      ADC12CTL0 |= ADC12ENC;                    // Enable conversions
      ADC12CTL0 |= ADC12SC;                     // Start convn - software trigger
     
      __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, Enable interrupts
      __no_operation();                         // For debugger
     
    }

    So, will it exit the ISR and goes back to the main() routine? Or it stays in the ISR as a forever loop?

  • That depends on how fast the interrupts are triggered, if the interrupts occur faster than you execute the ISR, then the MCU will stay in the ISR (it will exit it and reenter it immediately as there is a pending interrupt). If you can handle the ISR fast enough it will return to the code where the interrupt occurred. In your case your main method is not doing anything but the initialization and go to sleep then. So even if it enters main() again, it won't do anything you will notice.

  • Steven Gan Teck Yik said:
    I found out that i still can get the ADC result without the switch case function like the coding shown below:

    Yes and no. The switch/case structure ensure sthat exactly the values is processed that has triggered the ISR.

    In your second version, you assume that all ADC12MEMx contain a new value and the ISR was triggered by the last. Which is a totally valid, but completely different approach, which has advantages and disadvantages depending on the exact application.

**Attention** This is a public forum