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.

Multiple channel ADC

Other Parts Discussed in Thread: MSP430F2274

Hi, I'm working on the msp430f2274 and I need help regarding multiple analog channels. I'm using channels A0,A1,A2,A3,A4 and DTC to store the value in an array. But the values of each channel doesn't store in the array[#] correctly. For example in my code, value at A0 is suppose to be at samples[4], but it will appear on other samples[#] . There's a picture at the end to show what I meant. From the picture at the end. The top shows value(200+) of channel A0 on samples[4], then the next moment(bottom pic) shows value(200+) of channel A0 at samples[3].

#include  <msp430.h>
#define BIT0                (0x0001)
#define BIT1                (0x0002)
#define BIT2                (0x0004)
#define BIT3                (0x0008)
#define BIT4                (0x0010)
#define BIT5                (0x0020)
#define BIT6                (0x0040)
#define BIT7                (0x0080)
#define BIT8                (0x0100)
#define BIT9                (0x0200)
#define BITA                (0x0400)
#define BITB                (0x0800)
#define BITC                (0x1000)
#define BITD                (0x2000)
#define BITE                (0x4000)
#define BITF                (0x8000)

// Global variables
unsigned int samples[5];
// Function prototypes
void ConfigureAdc(void);

void main(void)
{
	{
		WDTCTL = WDTPW + WDTHOLD;		// Stop WDT
		BCSCTL1 = CALBC1_1MHZ;			// Set range   DCOCTL = CALDCO_1MHZ;
		BCSCTL2 &= ~(DIVS_3);			// SMCLK = DCO = 1MHz
		P2SEL |= BIT4 + BIT3 + BIT2 + BIT1 + BIT0;	// ADC input pin P2.4
		P1REN = 0;		// Pull-Up/Pull-down Resistors Disabled on P1 ports
		P1SEL = 0;		// Clear any previous settings
		P1DIR = 0;		// Clear any previous settings
		P1OUT = 0;		// Initialize port outputs to low state
		P3REN = 0;		// Pull-Up/Pull-down Resistors Disabled on P3 ports
		P3SEL = 0;		// Clear any previous settings
		P3DIR = 0;		// Clear any previous settings
		P3OUT = 0;		// Initialize port outputs to low state
		P4REN = 0;		// Pull-Up/Pull-down Resistors Disabled on P4 ports
		P4SEL = 0;		// Clear any previous settings
		P4DIR = 0;		// Clear any previous settings
		P4OUT = 0;		// Initialize port outputs to low state
		ConfigureAdc();		// ADC set-up function call
		__enable_interrupt();	// Enable interrupts.

		while(1)
		{
			__delay_cycles(1000);			// Wait for ADC Ref to settle
			ADC10SA = (unsigned int)samples;
			ADC10CTL0 |= ENC + ADC10SC;		// Sampling and conversion start
			__bis_SR_register(CPUOFF + GIE);      // Low Power Mode 0 with interrupts enabled
	
		}

	}
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
	__bic_SR_register_on_exit(CPUOFF);        // Return to active mode }
}

// Function containing ADC set-up
void ConfigureAdc(void)
{

	ADC10CTL1 = INCH_4 + ADC10DIV_0 + CONSEQ_3 + SHS_0;         // Channel 4, ADC10CLK/3
	ADC10CTL0 &= ~(ENC);
	ADC10CTL0 = SREF_0 + ADC10SHT_3 + MSC + ADC10ON + ADC10IE;            // Vcc & Vss as reference, Sample and hold for 64 Clock cycles, ADC on, ADC interrupt enable
	ADC10AE0 |= BIT4 + BIT3 + BIT2 + BIT1 + BIT0;               // ADC input enable P2.4,P2.3,P2.2,P2.1,P2.0
	ADC10DTC1 = 5;
}





  • Yu,


    All I can think of at the moment is to verify that ADC10TB is reset and try adding volatile to your global definition of samples.  This may not be necessary, but generally tells compilers to not optimize the defined variable due to it having the potential to change value outside of normal program execution.

    I don't know what your ADC is connected to, but a good debugging approach would be to tie channels A0-A4 to preset accurate/verified DC voltages.  Calculate the expected samples to be 100% positive what each channel's value should be and see if that lends any more insight.

    Rob

  • Where do you look at the values?
    You configured the ADC for repeated sequence. That means the ADC is sampling the sequence over and over as fast as its clock and the SHT setting allow.
    But when the debugger stops the CPU for reading the values into your memory view, the DTC cannot do its job, while the ADC continues. So you start skipping results.

    Perhaps you can ‘fix’ this by using SMCLK or MCLK as ADC clock rather than the ADCOSC/MODOSC. Depending on the MSP and the debugger settings, the debugger will stop SMCLK when it accesses the memory, and the ADC will therefore stop running too. It will, however, affect the conversion results (charge depletion if stopped during the conversion process).

     Sometimes, the debugger is the bugger.

    BTW: using volatile on all global variables that are read or written in an ISR is a good advice. But not on others (only used in main), as it makes optimization less effective.

**Attention** This is a public forum