Jump to content
43oh

faster adc sampling at 1 MHz clock speed


Recommended Posts

Hi guys,

 

I am working on a university design project and I am running into an ADC10 sampling limit on MSP430G2553. For a number of reasons, I need to be able to sample and process an input signal at 51 KHz. I can do this with my current setup with a clock speed of 4 MHz. I would, however, like to bring this speed down to 1 MHz so I could run the uC at a lower voltage level. The following is my current code:

 

 

#include <ctype.h>
#include "msp430g2553.h"
 
short value=0;
long  magnitude0 = 0, magnitude1 = 0;
short q0=0,q1=0,q2=0;
unsigned int sum = 0;
char state0 = 0;
char state1 = 0;
char trigger = 0;
 
 
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // stop the WDT
P2DIR = 0xFF;
P2OUT = 0x00;
P3DIR = 0xFF;
P3OUT = 0x00;
BCSCTL1  = CALBC1_8MHZ; // 8MHz calibration for basic clock system
DCOCTL = CALDCO_8MHZ; // 8MHz calibration for digitally controlled oscillator
BCSCTL2=DIVM0; //down to 4 MHz
ADC10CTL0 = ADC10SHT_0 + ADC10ON + ADC10IE; // ADC10ON, interrupt enabled
ADC10CTL1 = INCH_4; // A4 Input
ADC10AE0 |= 0x80;
// enable interrupts
_bis_SR_register(GIE);
.
.
.
.
.
unsigned char i;
for(i = 255;i!=0; i--)
{
_delay_cycles (1);
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit
value = ADC10MEM - 510;
q0=-q1-q2+value;
q2=q1;
q1=q0;
}
.
.
.
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}

 

 

The beginning segment is the setup. The middle segment is a loop that samples 255 samples at 51 KHz, and the last segment is the adc interrupt vector.

 

Is there a way I can drop down to 1 MHz and accomplish the same calculations at 51 KHz within the loop with clever coding techniques??

 

Regards,

George

Link to post
Share on other sites

How do you currently insure that the ADC is sampling at 51KHz when the clock is at 4MHz? I don't see any configuration to set the sampling rate or even a software delay that would approximate that rate. If you are taking 255 samples in a row like that, you are going to get them at the conversion frequency of the ADC10, plus a little overhead and the delay_cycles(1) you've inserted.

 

If you can't get the exact sampling frequency you want from the ADC10, then the next best thing is to set up a 51KHz timer interrupt to start the conversion and use the end of conversion interrupt to handle the reading of the result.

Link to post
Share on other sites

How do you currently insure that the ADC is sampling at 51KHz when the clock is at 4MHz? I don't see any configuration to set the sampling rate or even a software delay that would approximate that rate. If you are taking 255 samples in a row like that, you are going to get them at the conversion frequency of the ADC10, plus a little overhead and the delay_cycles(1) you've inserted.

 

If you can't get the exact sampling frequency you want from the ADC10, then the next best thing is to set up a 51KHz timer interrupt to start the conversion and use the end of conversion interrupt to handle the reading of the result.

 

 

Hi water rockets,

 

I am able to approximate the 51 kHz frequency based on mathematical operations I am conducting in another portion of the code. Is there a way I can complete the mathematical operations for the previous sample while the next sample is being prepared in the ADC unit? If I use the method above, when I slow the clock frequency to 1 Mhz, my sampling frequency drops to ~30kHz.

 

Thanks,

George

Link to post
Share on other sites
gfleming1992, on 03 Feb 2016 - 5:29 PM, said:

Hi water rockets,

 

I am able to approximate the 51 kHz frequency based on mathematical operations I am conducting in another portion of the code. Is there a way I can complete the mathematical operations for the previous sample while the next sample is being prepared in the ADC unit? If I use the method above, when I slow the clock frequency to 1 Mhz, my sampling frequency drops to ~30kHz.

 

Thanks,

George

 

Yes, the ADC will run by itself, and would be off doing a sample while the CPU is waiting for the interrupt to signal the conversion is complete. If you take out the code that makes the CPU wait for the interrupt, you can use the CPU to do anything you like, while the ADC is busy. You could possibly get rid of the interrupts completely, and just start the ADC from your main loop, do your math on the previous reading, and then poll the ADC status bits to find out when the conversion was complete, then go back and start the next conversion and repeat this process.

 

Another different idea you could try is to save the samples in memory instead of trying to process them in real time, and once you have 255 samples accumulated, you then process the stored conversions. From your code it looks like you only take 255 samples at a time, so this would potentially let you run the CPU much slower because the  CPU clock speed could be very slow and still manage to convert/store 255 samples at 51KHz.

Link to post
Share on other sites

Yes, the ADC will run by itself, and would be off doing a sample while the CPU is waiting for the interrupt to signal the conversion is complete. If you take out the code that makes the CPU wait for the interrupt, you can use the CPU to do anything you like, while the ADC is busy. You could possibly get rid of the interrupts completely, and just start the ADC from your main loop, do your math on the previous reading, and then poll the ADC status bits to find out when the conversion was complete, then go back and start the next conversion and repeat this process.

 

Another different idea you could try is to save the samples in memory instead of trying to process them in real time, and once you have 255 samples accumulated, you then process the stored conversions. From your code it looks like you only take 255 samples at a time, so this would potentially let you run the CPU much slower because the  CPU clock speed could be very slow and still manage to convert/store 255 samples at 51KHz.

 

Water Rockets,

 

Thanks for the help! By removing the ISR and optimizing the inner loop, I was able to maintain a sampling frequency of 51 KHz at 1 MHz clock speed:

 

for(i =255;i!=0; i--)
{
//_delay_cycles (1); // delay program execution for 335 cycles
//__bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit
//q0=-q1-q2+value;
q0 = ADC10MEM;
ADC10CTL0 |= ADC10SC;
q0+=-(q1+q2);
q2=q1;
q1=q0;
}
Regards,
George
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...