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.
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