EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

MSP430F149 Sampling Rate

Started by AmyLe August 27, 2007
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

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


The 2024 Embedded Online Conference