MSP430F149 Sampling Rate

Aug 27, 2007 3 Replies

Hi,



I want to find out the dynamic parameters of the ADC12 embedded in the MSP430F149.



I want to know how I can maximize my sample rate. So far, I was only able to run it at 128 ksps, but the datasheet said I could run it at



200 ksps. If anyone could help me with this matter, I'd really appreciate it. Thank you.


- Amy



We do this successfully. I think you'll need your MSP430 running at full MCLK but you can test if it's possible to make the target sample rate at a lower MCLK.

Here's my setup code:

void adcInitFast(void) { #define MIN_TIMERB ((SMCLK / 200000) - 1) UINT16 timerB; int i;

// TIMERB source is SMCLK, count up to TBCCR0 TBCTL = TBSSEL_2 | MC_1;

// TIMERB OUT0 is PULSE TBCCTL0 = OUTMOD_3;

// TIMERB OUT1 is square wave TBCCTL1 = OUTMOD_3;

// Select the ADC input pin for ADC12 P6SEL |= BIT0; P6DIR &= ~BIT0;

// Disable conversion to allow changes to the ADC12 ADC12CTL0 = 0;

// Configure ADC: Conversion start address 0, TIMERB.OUT0 is sample input signal, MCLK drives ADC12, repeat single channel ADC12CTL1 = CSTARTADD_0 | SHS_2 | SHP | ADC12DIV_0 | ADC12SSEL_2 | CONSEQ_2;

// No ADC12 interrupts ADC12IE = 0;

// Configure TIMERA: SMCLK steps timer, divide by 8, halted, clear TACTL = TASSEL1 | ID1 | ID0 | TACLR;

// Compute the timer terminal value timerB = (word)(((float)(SMCLK) / gProbeTable.pyroSampleRate) + 0.5F) - 1;

// Limit the sample clock to the maximum ADC12 sample rate if(timerB < MIN_TIMERB) timerB = MIN_TIMERB;

#ifdef MAXIMUM_SAMPLE_RATE timerB = 4; #endif

// Load the sample clock terminal value TBCCR0 = timerB;

// Disable conversion to allow changes to the ADC12 ADC12CTL0 = 0;

// Select the reference voltage ADC12MCTL0 = SREF_1;

// Turn on ADC12 ADC12CTL0 = REF2_5V | REFON | ADC12ON | SHT0_1;

// Delay for reference start-up for(i = 0; i < 500; i++);

// Enable conversion ADC12CTL0 |= ENC;

// This starts the sampling i = (int)(ADC12MEM0); while(!(ADC12IFG & BIT0)); }

Here's how I read the ADC at 200KHz:

UINT16 adc;

for(;;) { // Get the next sample while(!(ADC12IFG & BIT0)); adc = ADC12MEM0; }

Keep in mind these important considerations:

  1. You won't be able to service interrupts and sustain 200KHz continuous sample rate.
  2. You won't be able to service ADC interrupts (IOW, you need to poll).
  3. There's not a lot of processing time after you read the ADC result.
  4. YMMV

JJS

We do this successfully. I think you'll need your MSP430 running at full MCLK but you can test if it's possible to make the target sample rate at a lower MCLK.

Here's my setup code:

void adcInitFast(void) { #define MIN_TIMERB ((SMCLK / 200000) - 1) UINT16 timerB; int i;

// TIMERB source is SMCLK, count up to TBCCR0 TBCTL = TBSSEL_2 | MC_1;

// TIMERB OUT0 is PULSE TBCCTL0 = OUTMOD_3;

// TIMERB OUT1 is square wave TBCCTL1 = OUTMOD_3;

// Select the ADC input pin for ADC12 P6SEL |= BIT0; P6DIR &= ~BIT0;

// Disable conversion to allow changes to the ADC12 ADC12CTL0 = 0;

// Configure ADC: Conversion start address 0, TIMERB.OUT0 is sample input signal, MCLK drives ADC12, repeat single channel ADC12CTL1 = CSTARTADD_0 | SHS_2 | SHP | ADC12DIV_0 | ADC12SSEL_2 | CONSEQ_2;

// No ADC12 interrupts ADC12IE = 0;

// Configure TIMERA: SMCLK steps timer, divide by 8, halted, clear TACTL = TASSEL1 | ID1 | ID0 | TACLR;

// Compute the timer terminal value timerB = (word)(((float)(SMCLK) / gProbeTable.pyroSampleRate) + 0.5F) - 1;

// Limit the sample clock to the maximum ADC12 sample rate if(timerB < MIN_TIMERB) timerB = MIN_TIMERB;

#ifdef MAXIMUM_SAMPLE_RATE timerB = 4; #endif

// Load the sample clock terminal value TBCCR0 = timerB;

// Disable conversion to allow changes to the ADC12 ADC12CTL0 = 0;

// Select the reference voltage ADC12MCTL0 = SREF_1;

// Turn on ADC12 ADC12CTL0 = REF2_5V | REFON | ADC12ON | SHT0_1;

// Delay for reference start-up for(i = 0; i < 500; i++);

// Enable conversion ADC12CTL0 |= ENC;

// This starts the sampling i = (int)(ADC12MEM0); while(!(ADC12IFG & BIT0)); }

Here's how I read the ADC at 200KHz:

UINT16 adc;

for(;;) { // Get the next sample while(!(ADC12IFG & BIT0)); adc = ADC12MEM0; }

Keep in mind these important considerations:

  1. You won't be able to service interrupts and sustain 200KHz continuous sample rate.
  2. You won't be able to service ADC interrupts (IOW, you need to poll).
  3. There's not a lot of processing time after you read the ADC result.
  4. YMMV

JJS

Hi John,

Thank you for your reply. We tried the polling, and it works! Thanks a lot :)

- Amy

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required