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.

Reading multi-channel conversion in msp430f5247

Other Parts Discussed in Thread: MSP430F5247

hi,

I have been working on msp430f5247 and trying to explore its ADC10 features. I want to scan 8 channel in multi-channel conversion mode . I am using external reference of 2.048 V . I am using following code to achieve this task . Suggest me if I am doing anything incorrectly.

void adc_init(void)
{
	// Initialize ADC10_A
	// Turn on ADC10, set sampling time
	ADC10CTL0 = ADC10ON+ADC10MSC+ADC10SHT_15;

	// Use sampling timer, repeat sequence
	ADC10CTL1 = ADC10SHP+ADC10CONSEQ_3 + ADC10SSEL_3;

	// ref+=AVcc, channel = A7..A0
	ADC10MCTL0 = ADC10INCH_7 + ADC10SREF_7;

	// Enable ADC12IFG.8
	ADC10IE = ADC10IE0;

	// Enable conversions
	ADC10CTL0 |= ADC10ENC;

	// Start convn - software trigger
	ADC10CTL0 |= ADC10SC;
}

#pragma vector=ADC10_VECTOR
__interrupt void ADC10ISR(void)
{
	uint8_t scanned_channel = 7;

	switch(__even_in_range(ADC10IV,16))
	{
		case  0:    // Vector  0:  No interrupt
			break;
		case  2:    // Vector  2:  ADC10_A overflow
			break;
		case  4:    // Vector  4:  ADC10_A timing overflow
			break;
		case  6:    // Vector  6:  ADC10_A window comparator high Interrupt
			break;
		case  8:    // Vector  8:  ADC10_A window comparator low Interrupt
			break;
		case 10:    // Vector 10:  ADC10_A window comparator in Interrupt
			break;
		case 12:
			scanned_channel = ADC10MCTL0 & 0x0F;

			if( scanned_channel == 7 )
				scanned_channel = 0;
			else
				scanned_channel += 1;

			switch( scanned_channel )
			{
				case 0:
					adc_results[scanned_channel] = ( ADC10MEM0  );
					break;
				case 1:
					adc_results[scanned_channel] = ( ADC10MEM0 );
					break;
				case 2:
					adc_results[scanned_channel] = ( ADC10MEM0 );
					break;
				case 3:
					adc_results[scanned_channel] = ( ADC10MEM0 );
					break;
				case 4:
					adc_results[scanned_channel] = ( ADC10MEM0 );
					break;
				case 5:
					adc_results[scanned_channel] = ( ADC10MEM0 );
					break;
				case 6:
					adc_results[scanned_channel] = ( ADC10MEM0 );
					break;
				case 7:
					adc_results[scanned_channel] = ( ADC10MEM0  );
					break;
				default:
					break;
			}
			break;
		default:
			break;
	}
}

MSP430F5247 doesn't support direct transfer and each channel conversion has to be transferred in interrupt. How can I be sure that I am reading correct channel. I came across several thread which deals with same but they have direct memory transfer to store each scanned channel result while in this case its different. Appreciate your help . 

 

  • Hi Dhruvalkumar,

    Checking the ADC10INCHx bits inside of ADC10MCTL0 will not work. If you want to avoid using the DMA then you have to manually log and count each interrupt with its respective channel. Therefore the first interrupt would store ADC10MEM0 as channel 7, the second as channel 6, and so on until after the eighth interrupt/channel 0 you would restart the next interrupt at channel 7. You would need to utilize the ADC10(T)OVIFGs to make sure that no overflow conditions occur during this time, but since you are sourcing the ADC10 with ACLK (I assume at 32 kHz) your conversions might be slow enough to not cause any issue. I recommend increasing your core frequency to help compensate. Because of the ADC10's nature it really is recommended to use the DMA.

    Regards,
    Ryan
  • Thanks a lot for the help.

    I went through reference manual of msp430f5xx and it dosen't seem to have DMA capability. Can give me a pointer to a document which does that.

  • The DMA is explained in both the device datasheet (SLAS897) and User's Guide (SLAU208)

    www.ti.com/.../msp430f5247.pdf
    www.ti.com/.../slau208o.pdf

    Regards,
    Ryan

**Attention** This is a public forum