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.

MSP430FR2355: MSP430FR2355 MULTIPLE CHANNEL ADC SAMPLING WITHOUT USING SEQUENCE OF CHANNELS

Part Number: MSP430FR2355

Hello All,

I'am using a MSP430FR2355 LAUNCHPAD. I want to sample 3 channels of data but I cannot use A2 because it is used as a SAC input pin(OA-).

How can I use A3,A1& A0 without using sequence of channels setting?

Iam using TimerB1.1 to trigger the ADC with a sampling rate of 1000HZ.

  • Hi Sumit, Thanks for your question!

    The sequence begins with the channel selected by the ADCINCHx bits and decrements to channel A0. Hence, Please don't adopt Sequence-of-Channels Mode. you can assign ADC channels during TimerB1.1 trigger the ADC.

  • Hello ,

    Thanks for replying. I didn't understood meaning of assigning ADC Channels during TimerB1.1 trigger the ADC.

    I have not written any ISR for TimerB1.1  interrupt.

    I have used TIMER1_B0_ISR to toggle GPIO to Check the sampling rate but have not written TimerB1.1  ISR.

     I have also used ADC Conversion Interrupt in which Iam reading my results.

    Can you help me with a small example?

  • Hello,

    I tried assigning ADC Channels during Timer Interrupt by using below code.

             

    Inside The Timer interrupt which ticks every 1 ms, I'am writing this code. But I'am getting the same ADC values in the channels. I stored the ADC results of the channels to check and found that they are copy of each other.

    My complete code  of ADC, Timer initialization & their interrupt

     // Configure ADC
        ADCCTL0 |= ADCSHT_4|ADCON|ADCMSC ;                 //ADCON | ADCMSC;
        ADCCTL1 |=  ADCSHP|ADCSHS_2|ADCCONSEQ_0|ADCSSEL_0;//ADCSHS_2 | ADCCONSEQ_3|ADCSSEL_0;    // repeat single channel; TB1.1 trig sample start
       // ADCCTL1 |=  ADCSHP|ADCSSEL_0; // temperory change
        ADCCTL2 &= ~ADCRES;                                       // clear ADCRES in ADCCTL
        ADCCTL2 |= ADCRES_2;                                      // 12-bit conversion results
        ADCMCTL0 |= ADCSREF_1;                        // A1 ADC input select; Vref=2.5V
       // ADCMCTL0 |=  ADCSREF_1;  // temperory change
        ADCIE |= ADCIE0;                                          // Enable ADC conv complete interrupt
    
    
        ADCCTL0 |= ADCENC| ADCSC;                                         // ADC Enable
    
    
    
        // ADC conversion trigger signal - TimerB0
       // TB1CCTL0 = CCIE;                              // CCR0 interrupt enabled
               TB1CTL |= TBSSEL__ACLK | TBCLR;                         // ACLK, clear TBR
              TB1CCTL1 |= OUTMOD_2;
                 TB1CCTL0 |= CCIE;
               TB1CCR0 =  31; //SAMPLING RATE 500   
               TB1CCR1 = 10;
               TB1CTL |= MC_1;   
    
    // Timer B1 interrupt service routine
    #pragma vector=TIMER1_B0_VECTOR
    __interrupt void TIMER1_B0_ISR(void)
    
    {
    
       // __delay_cycles(100);
    
         //while(ADCCTL1 & ADCBUSY);
           //  ADCCTL0 |= ADCENC | ADCSC;
    
     if((SAC1OA & SACEN)) 
    
     {
        // P2OUT &= ~BIT0; 
         SAC1OA &= ~SACEN; 
         SAC1DAC &= ~DACEN; 
         P2OUT |= BIT2; 
         SAC3OA |= SACEN; 
         SAC3DAC |= DACEN;
         SAC3DAT =  vs_LED_level;
         SAC2DAT = vs_dc_offset;
         //SAC0DAT = vs_sample; 
         P2OUT &= ~BIT0; 
    
    
         is_IR = 0;                         
    
        // __delay_cycles(100);
                ADCMCTL0 |= ADCINCH_3;
    
                  // ADCCTL0 |= ADCENC | ADCSC;
                   while(ADCCTL1 & ADCBUSY); 
    
                   ADCMCTL0 |= ADCINCH_1;
    
                  // ADCCTL0 |= ADCENC | ADCSC;
                   while(ADCCTL1 & ADCBUSY);                                // Wait if ADC core is active
    
                   ADCMCTL0 |= ADCINCH_0;
    
                          //  ADCCTL0 |= ADCENC | ADCSC;
                    while(ADCCTL1 & ADCBUSY);
    
         ir_sample = ADC_Result[1];              
         i = ADC_Result[0];
         SAMPLE = ADC_Result[2];
          newsample =1;
    
          ADCCTL0 &= ~ADCENC;
    
          ADCCTL0 |= ADCENC;
    
        
    
          if (receive =='a')
                                   {
              if(i<4095){
    
                                               while(!(UCA1IFG & UCTXIFG));
    
                                                  UCA1TXBUF = 'I';
    
                                   while(!(UCA1IFG & UCTXIFG));
    
                                         UCA1TXBUF = i & 0x00FF;                   // Load data onto buffer
    
                                         while(!(UCA1IFG & UCTXIFG));
    
                                        UCA1TXBUF = (i & 0xFF00) >>8; //MSB                   // Load data onto buffer
    
                                        while(!(UCA1IFG & UCTXIFG));
    
                                        UCA1TXBUF = SAMPLE & 0x00FF;                   // Load data onto buffer
    
                                        while(!(UCA1IFG & UCTXIFG));
    
                                        UCA1TXBUF = (SAMPLE & 0xFF00) >>8; //MSB                   // Load data onto buffer
              }
                                   }
           
    
     }
    
    
    
     else
     {
             // P2OUT &= ~BIT2; 
              SAC3OA &= ~SACEN; 
              SAC3DAC &= ~DACEN; 
              P2OUT |= BIT0; 
              SAC1OA |= SACEN; 
              SAC1DAC |= DACEN;
              SAC1DAT =  ir_LED_level;
              SAC2DAT = ir_dc_offset;
            // SAC0DAT = ir_sample;
              P2OUT &= ~BIT2; 
    
    
              is_IR = 1;                          
    
    
    
          //   __delay_cycles(100);
                ADCMCTL0 |= ADCINCH_3;
             
             while(ADCCTL1 & ADCBUSY);  
    
             ADCMCTL0 |= ADCINCH_1;
            
             while(ADCCTL1 & ADCBUSY);  
                                 
              ADCMCTL0 |= ADCINCH_0;
                      
                       while(ADCCTL1 & ADCBUSY);                               // Wait if ADC core is active
    
    
    
    
                 vs_sample = ADC_Result[1];              //Read the visible LED results
                 i = ADC_Result[0];
               SAMPLE = ADC_Result[2];
                 newsample =1;
                                                     //Enable the next conversion sequence.
                                                   //The sequence is started by TB1
                 ADCCTL0 &= ~ADCENC;
              //   while(ADCCTL1 & ADCBUSY);
                 ADCCTL0 |= ADCENC;                                    // Sampling and conversion start
                
                 if (receive =='a')
                                                {
    if(i<4095){
                                                    while(!(UCA1IFG & UCTXIFG));
    
                                                   UCA1TXBUF = 'V';                   // Load data onto buffer
    
                                                while(!(UCA1IFG & UCTXIFG));
    
                                                      UCA1TXBUF = i & 0x00FF;                   // Load data onto buffer
    
                                                      while(!(UCA1IFG & UCTXIFG));
    
                                                     UCA1TXBUF = (i & 0xFF00) >>8; //MSB                   // Load data onto buffer
    
                                                 //   while(!(UCA1IFG & UCTXIFG));
    
                                                  //   UCA1TXBUF = SAMPLE & 0x00FF;                   // Load data onto buffer
    
                                                   //   while(!(UCA1IFG & UCTXIFG));
    
                                                    //  UCA1TXBUF = (SAMPLE & 0xFF00) >>8; //MSB                   // Load data onto buffer
    }
                                                }
    
    
               
    
     }
    
     TB0CCTL0 &= ~CCIFG;
    }
    
    // ADC interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC_VECTOR
    __interrupt void ADC_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
        {
            case ADCIV_NONE:
                break;
            case ADCIV_ADCOVIFG:
                break;
            case ADCIV_ADCTOVIFG:
                break;
            case ADCIV_ADCHIIFG:
                break;
            case ADCIV_ADCLOIFG:
                break;
            case ADCIV_ADCINIFG:
                break;
            case ADCIV_ADCIFG:
                ADC_Result[s] = ADCMEM0;
    
                                                               if(s == 0)
                                                               {
                                                                   s=2;
    
                                                                   SAC1DAT = 0; //TURN OFF BOTH LED'S
                                                                    SAC3DAT = 0;//
                                                                    
                                                                    if(is_IR==1)  // 
                                                                    {
                                                                     P2OUT |= BIT2;
                                                                      P2OUT &= ~BIT0;
                                                                    }
                                                                     else
                                                                     {                            
                                                                      P2OUT |= BIT0;
                                                                       P2OUT &= ~BIT2;// P2.0 = 1
                                                                     }
                                                                   __bic_SR_register_on_exit(LPM0_bits);
    
    
                                                               }
                                                               else
                                                                          {
                                                                              s--;
                                                                          }
    
    
    
                                                             //  P6OUT ^= BIT3;
    
                                                 ADCIFG = 0;
    
                               break;                                           // Clear CPUOFF bit from 0(SR)
                                                          // Clear CPUOFF bit from 0(SR)
            default:
                break;
        }
    }
    
                 

    is below

  • > ADCMCTL0 |= ADCINCH_3;

    "|=" can only set bits, not clear them.. After this, you will always sample INCH=3. Also, you can only change INCH when ENC=0.

    ADCSHS_2 specifies a timer trigger, and you're using ADCSC, so use ADCSHS_0.

    I suggest the following. Repeat it 3 times, with different values of "i" (channel number):

                i = 3;                  // INCH_3 and ADC_Result index
                ADCCTL0 &= ~ADCENC;     // Disable
                ADCMCTL0 = (ADCMCTL0 & ~ADCINCH) | i;  // We "know" INCH is the LSb-s
                ADCCTL0 |= ADCENC | ADCSC;      // Re-Enable and start another
                while (ADCCTL1 & ADCBUSY) /*EMPTY*/; // Wait for it to complete
                ADC_Result[i] = ADCMEM0;        // Save away result           
    

  • BRILLIANT!!! ABSOLUTELY BRILLIANT SUGGESTION! 

    I could have never figured out this solution. I Hope your answer will help others too!!

    Thank you once again. keep up the good work!

**Attention** This is a public forum