gfleming1992 1 Posted February 3, 2016 Share Posted February 3, 2016 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 Quote Link to post Share on other sites
USWaterRockets 57 Posted February 3, 2016 Share Posted February 3, 2016 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. Quote Link to post Share on other sites
gfleming1992 1 Posted February 3, 2016 Author Share Posted February 3, 2016 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 Quote Link to post Share on other sites
USWaterRockets 57 Posted February 3, 2016 Share Posted February 3, 2016 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. bluehash, gfleming1992 and energia 3 Quote Link to post Share on other sites
jazz 209 Posted February 4, 2016 Share Posted February 4, 2016 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 You can try this without going down with clock speed. I am running MSP430F550X on 24 MHz at 1.8 V and default VCore. energia 1 Quote Link to post Share on other sites
energia 485 Posted February 4, 2016 Share Posted February 4, 2016 The minimum power supply for the MSP430 is 1.8 volts. Most power supplies have a +/- 10% tolerance over temperature. In the minus case you could end up with 1.782 which would be below spec. The MSP430 could still work that voltage but it's not guaranteed though. Quote Link to post Share on other sites
gfleming1992 1 Posted February 4, 2016 Author Share Posted February 4, 2016 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 energia 1 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.