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.

how does the ADCIE register work in MSP430f



Hello all,

               can anyone please explain me the significance of ADCIE register in msp430f2xxx? i was going through the example codes, and found that the value of ADCIE depends on the number of ADC channels we want to sample; like if we want to sample 3 channels, the value of ADCIE is 0x03. is it correct?

what would be the value of ADCIE if i were to sample all the 8channles on MSP430f2xxx

please help

  • Each bit in ACIE register corresponds to one bit in ADCIFG register. If both corresponding bits are set, the ADC interrupt vector is called. The ADCIFG bits are set when the ADC12 (MSPs with ADC10 do not have these registers!) completes a conversion and ahs written the result to the corresponding ADC12MEMx register.

    The bits correspond to the ADC12MEMx/ADC12MCTLx pair, not to the selected signal input channel.

  • OK, so,is my declaration below for the ADC module correct? At times, I get an ADC Timing Overflow Interrupt. its not often, but sometimes I do get it.  i am trying to save the ADC data to an external NAND flash. i am saving 1024bytes at a time, the ADC is being sampld @ 2048hz. Could writting to memory be a reason for this interrupt ( i mean time taken to write to memory loop).

     

       /*ADC input channels; Vr+=AVcc=3.3V & Vr-=AVss=0V*/
      ADC12MCTL0 = 0x0Bu;       //INCH=(Avcc-Avss)/2; it is NOT stored in the external flash
      ADC12MCTL1 = 0x00u;       //INCH=A0_D1_1S2
      ADC12MCTL2 = 0x01u;       //INCH=A1_D2_2S2
      ADC12MCTL3 = 0x02u;       //INCH=A2_D3_3S2
      ADC12MCTL4 = 0x03u;       //INCH=A3
      ADC12MCTL5 = 0x04u;       //INCH=A4
      ADC12MCTL6 = 0x05u;       //INCH=A5
      ADC12MCTL7 = 0x06u;       //INCH=A6
      ADC12MCTL8 = 0x07u;       //INCH=A7
      ADC12MCTL9 = 0x08u;       //INCH=A8/Veref+
      ADC12MCTL10 = 0x09u;      //INCH=A9/Vref-/Veref- 
      ADC12MCTL11 = 0x00u;      //INCH=A0_D1_1S1
      ADC12MCTL12 = 0x01u;      //INCH=A1_D2_2S1
      ADC12MCTL13 = 0x82u;      //INCH=A2_D3_3S1=0.5AxVcc AND End-of Sequence (EOS)

     ADC12IE = BIT3 | BITD;        //enable ADC interrupt

    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12ISR (void)
    {
     
      switch(__even_in_range(ADC12IV,34))
      {
      case  0: break;                          // Vector  0:  No interrupt
      case  2:                                 // Vector  2:  ADC overflow
        _NOP();
      case  4:                                 // Vector  4:  ADC timing overflow
      flag='t';
       _NOP();
      break;             

      
      case 0x08:      // ADC12MEM1 was loaded (ADC12IFG.1)
        ADC_Temp_Buff[0] = ADC12MEM1;              // save A1
        break;
     
      case 0x0A:     // ADC12MEM2 was loaded (ADC12IFG.2)
        ADC_Temp_Buff[1] = ADC12MEM2;              // save A2
        break;
     
      case 0x0C:     // ADC12MEM3 was loaded (ADC12IFG.3)
        ADC_Temp_Buff[2] = ADC12MEM3;              // save A3
        break;
     
      case 0x0E:     // ADC12MEM4 was loaded (ADC12IFG.4)
        ADC_Temp_Buff[3] = ADC12MEM4;              // save A4
        break;
     
      case 0x10:     // ADC12MEM5 was loaded (ADC12IFG.5)
        ADC_Temp_Buff[4] = ADC12MEM5;              // save A5
        break;
     
      case 0x12:     // ADC12MEM6 was loaded (ADC12IFG.6)
        ADC_Temp_Buff[5] = ADC12MEM6;              // save A6
        break;
     
      case 0x14:     // ADC12MEM7 was loaded (ADC12IFG.7)
        ADC_Temp_Buff[6] = ADC12MEM7;              // save A7
        break;
     
      case 0x16:     // ADC12MEM8 was loaded (ADC12IFG.8)
        ADC_Temp_Buff[7] = ADC12MEM8;              // save A8
        break;
     
      case 0x18:     // ADC12MEM9 was loaded (ADC12IFG.9)
        ADC_Temp_Buff[8] = ADC12MEM9;              // save A9
        break;
     
      case 0x1A:     // ADC12MEM10 was loaded (ADC12IFG.10)
        ADC_Temp_Buff[9] = ADC12MEM10;             // save A10
        break;
     
      case 0x1C:     // ADC12MEM11 was loaded (ADC12IFG.11)
        ADC_Temp_Buff[10] = ADC12MEM11;            // save A11
        break; 
                 
      case 0x1E:     // ADC12MEM12 was loaded (ADC12IFG.12)
         ADC_Temp_Buff[11] = ADC12MEM12;            // save A12
         break;
      default: break;
      }

  • Funny1234 Guy said:
    ADC12IE = BIT3 | BITD;        //enable ADC interrupt

    This means that the ADC will trigger an interrupt after it has completed teh conversion into ADC12MEM3 and ADC12MEM13.

    In your ISR, ADC12IFG13 is not checked. So the interrupt is not handled. and the result never saved. The only thing that is copied is ADC12MEM3.

    If you don't need the other conversion, don't put them into the chain at all. Just program ADC12MEM0+1 and sample the two channels you want.
    IF you want to keep them, but do not want to call teh ISR for each read, you must put the read instructions for these channels into th ecase where you enabled the interrupt for.

    So in case 0x0c (which is executed when ADC12MEM3 is written), copy ADC12mem3, but also ADC12MEM0..2, as they must have been completed before 3 (the sequence started with 0).

    The overflow you get is because you never read any of the other ADC12MEM registers (except 3), so as soon as you call the sequence the second time, you'll get this error. because ADC12MEMx is written to before you did read the last result.

    The error is cleared when ADC12MEM3 is written (I think) but as soon as th next ADC12MEM4 conversion is done, it is set again. If for some reason execution of the ISR was delayed (e.g. GIE was clear for some critical operation, e.g. multiplication) and the next conversion is done before you check the overflow flagg, it will be set.

  • Hello, i understood your point. I did make changes in my code and added the case logic for ADC12MEM13, but inspite of that, i am getting the ADC TIMING OVERFLOW interrupt. Even if i get this interrupt, I am able to save the values at that instant to my buffer. i also tried to save the data in ADCMEMx pointer ( to save the iteration cycles; the user manual for MSP430F2xxx mentions the address locations of the ADCMEMx pointers;) but still I am getting the timing overflow interrupt.

    how critical is this interrupt if I would like to save the data at the ADC to an external flash? Would I be loosing any data at 'THAT' particular instant when the ADC interrupt happens?

    Also, I observe that sometimes, the ADC interrupt routine runs just few times and later on, the program waits at a place at a code, where it is not supposed to go(basically it waits at INIT() function... below is the modified version of the code

     

    /*32 sample clocks for mem[0-15], automatic muliple sampling requiring trigger, rest disabled*/
      ADC12CTL0 = SHT0_3 | SHT1_3  | MSC;
     
      /*Sequence from starting from mem1, source=MCLK
      Timer A.1 triggered*/
       ADC12CTL1 = 0x1612u;

    /*ADC input channels; Vr+=AVcc=3.3V & Vr-=AVss=0V*/
      ADC12MCTL0 = 0x0Bu;       //INCH=(Avcc-Avss)/2; it is NOT stored in the external flash
      ADC12MCTL1 = 0x00u;       //INCH=A0_D1_1S2
      ADC12MCTL2 = 0x01u;       //INCH=A1_D2_2S2
      ADC12MCTL3 = 0x02u;       //INCH=A2_D3_3S2
      ADC12MCTL4 = 0x03u;       //INCH=A3
      ADC12MCTL5 = 0x04u;       //INCH=A4
      ADC12MCTL6 = 0x05u;       //INCH=A5
      ADC12MCTL7 = 0x06u;       //INCH=A6
      ADC12MCTL8 = 0x07u;       //INCH=A7
      ADC12MCTL9 = 0x08u;       //INCH=A8/Veref+
      ADC12MCTL10 = 0x09u;      //INCH=A9/Vref-/Veref- 
      ADC12MCTL11 = 0x00u;      //INCH=A0_D1_1S1
      ADC12MCTL12 = 0x01u;      //INCH=A1_D2_2S1
      ADC12MCTL13 = 0x82u;      //INCH=A2_D3_3S1=0.5AxVcc AND End-of Sequence (EOS)

     ADC12IE = BIT3 | BITD;        //enable ADC interrupt

    #pragma vector=ADC12_VECTOR
    __interrupt void ADC12ISR (void)
    {
     
      switch(__even_in_range(ADC12IV,34))
      {
      case  0: break;                          // Vector  0:  No interrupt
      case  2:                                 // Vector  2:  ADC overflow
        _NOP();
      case  4:                                 // Vector  4:  ADC timing overflow
      flag='t';
       _NOP();
      break;             

      
      case 0x08:      // ADC12MEM1 was loaded (ADC12IFG.1)
        ADC_Temp_Buff[0] = ADC12MEM1;              // save A1
       
     
      case 0x0A:     // ADC12MEM2 was loaded (ADC12IFG.2)
        ADC_Temp_Buff[1] = ADC12MEM2;              // save A2
     
     
      case 0x0C:     // ADC12MEM3 was loaded (ADC12IFG.3)
        ADC_Temp_Buff[2] = ADC12MEM3;              // save A3
     
     
      case 0x0E:     // ADC12MEM4 was loaded (ADC12IFG.4)
        ADC_Temp_Buff[3] = ADC12MEM4;              // save A4
       
     
      case 0x10:     // ADC12MEM5 was loaded (ADC12IFG.5)
        ADC_Temp_Buff[4] = ADC12MEM5;              // save A5
      
     
      case 0x12:     // ADC12MEM6 was loaded (ADC12IFG.6)
        ADC_Temp_Buff[5] = ADC12MEM6;              // save A6
       
     
      case 0x14:     // ADC12MEM7 was loaded (ADC12IFG.7)
        ADC_Temp_Buff[6] = ADC12MEM7;              // save A7
     
     
      case 0x16:     // ADC12MEM8 was loaded (ADC12IFG.8)
        ADC_Temp_Buff[7] = ADC12MEM8;              // save A8
      
     
      case 0x18:     // ADC12MEM9 was loaded (ADC12IFG.9)
        ADC_Temp_Buff[8] = ADC12MEM9;              // save A9
      
     
      case 0x1A:     // ADC12MEM10 was loaded (ADC12IFG.10)
        ADC_Temp_Buff[9] = ADC12MEM10;             // save A10
      
     
      case 0x1C:     // ADC12MEM11 was loaded (ADC12IFG.11)
        ADC_Temp_Buff[10] = ADC12MEM11;            // save A11
       
                 
      case 0x1E:     // ADC12MEM12 was loaded (ADC12IFG.12)
         ADC_Temp_Buff[11] = ADC12MEM12;            // save A12

    case 0x20:                                 // Vector 32:  ADC12IFG13
        ADC_Temp_Buff[12] = ADC12MEM13;            // save A13

        ADC12IFG = 0x0000u;
        ADC12CTL0 |=ENC; // re-enable the ADC sample and conversion cycle

      default: break;
      }

    //save the ADC_Temp_Buff data to flash memory here

    }

    EDITED:::  //save the ADC_Temp_Buff data to flash memory here

    when I include the fucntion to save data to flash memory, i get the overflow error, or else i do not get any interrupt... how can i solve this?

     

  • You only get the overflow interrupt if you enabled set its IE bit. And it is clear why you're getting it: you only read teh 3rd and 13th result. But you leave the other results unread. And when your sequence converts one of these for the second time, you'll get the interrupt. Basically, teh overflow interupt flag is set whenever a new value is written to any one of the ADC12MEMx registers and its corresponding IFG flag is still set (meaning that the previous result was not read). However, I don't know whether manually clearing the IFG bits will have teh desired effect of suppressing the overflow interrupt. Maybe there must be have been a real read.

    If in your ISR, you move all the reads from 4 to 12 into the last 8and from 0 to 2 into the 3rd) case, so you'll really read all the memory registers in two blocks, the overflwo should go away. Unless yoU're really too slow.

**Attention** This is a public forum