ADC sampling frequency vs. system clock problem

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all!

First of all, I am a newbie to avr. In fact I am new to microcontrollers itself. Whatever I have learnt is through various entries of this forum.

I require to use ADC of avr atmega32 to convert the output of a microphone signal. My signal is less than 2Khz and consequently I want a Nyquist frequency of 4Khz. I also require 8-bit resolution.

Now i need the system clock to run at 16 Mhz because after each ADC conversion I need more than 2400 cycles for execution of digital filters that i have programed into the microcontroller. These filters have to work in real time on each sample before the next sample comes in.

Now if i use a 16Mhz system clock with a 128 prescaler I get an ADC frequency of 125Khz and for free running mode the sampling frequency comes out to be 125Khz/13= 9615 Hz.

And at this frequency the no. of clock cycles between samples comes out to be 16000000*(1/9615)= 1664, which is significantly less than my requirement.

My question is if it is possible to get a ADC sampling frequency of around 4000Hz with a system clock of 16Mhz?

Please help me. I am in a bind here.

Also, i may have posted in the wrong place. In that case please guide me to the correct place.

Thank you!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you only need 8-bit resolution you can increase the ADC clock.
I've used 1MHz for 8 bit with good results.
OTOH I sample i.e. 8 or 16 times and average the result which effectively increase the resolution.
Give it a try, you should be able to run ADC clock at 800kHz and average two samples to avoid to much flipping of lsb.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are confusing ADC sample rate and ADC clock rate. The ADC needs a clock that is not too fast and not too slow. You can go somewhat faster than the stated upper limit if you only need 8 bits.

But, I is very rare to have the ADC free-run at the desired clock rate and have it sample at the rate that you want. What is the solution? Trigger it from a timer/counter. That is really the only way to reconcile the two requirements.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I saw this picture: https://www.avrfreaks.net/index.p...
Click also on the link in that message, very interesting.

But you don't need to overclock the ADC clock. If you want 4Khz sampling rate, you should use a timer for that as ka7ehk wrote above. In that case you have enough cycles for the calculation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As others have said: set a timer to tick at 4kHz, and trigger an interrupt on each tick.

On that interrupt, start the ADC conversion. Either poll the 'finished' bit or trigger a further interrupt on it (this is easy on the AVR since all the interrupts have individual vectors) and then perform your maths.

At 4KHz ticks and 16MHz clock you'll have 250 microseconds = 4000 cycles between ticks; you'll use a couple of dozen for the interrupt handling but you should have plenty for your processing. Whether you're better doing the processing on an interrupt or polling depends rather on what else you're doing... note that it doesn't matter how long the ADC conversion takes since this takes no processor time.

You probably know this already but remember Mr Nyquist assumed you had perfect filters... if your input signal has *any* component above the Nyquist frequency you *will* get aliasing in your sampled signal. The usual way to do this is to sample at about 2.2 times the highest frequency you're interested in, and to stuff the best filter you can get between your signal and the ADC.

With an eight bit resolution you're looking for a filter output which is better than 42dB down at the sampling frequency (and ideally flat up to there!); not an easy task but switch capacitor filters could be a solution. You *can't* filter aliasing noise out digitally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you Lennart, Jim, Kun.io and Niel. I really appreciate the help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please bear with me, i am new at this.

Could you kindly guide me regarding the following points-
1. How to use interrupts to trigger adc? Which interrupt to use?
2. How to make a timer tick at 4Khz and trigger the interrupt in conjunction with it?
3. How do I poll an interrupt? And which interrupt can i use for this?

Once again, please bear with me.

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
1. How to use interrupts to trigger adc? Which interrupt to use?

You could use any ISR() that you like. Set ADSC as part of that service routine.

Quote:
2. How to make a timer tick at 4Khz and trigger the interrupt in conjunction with it?

Choose any spare timer and select CTC mode and division ratio: e.g.

TCCR0B = (1<<WGM02)|(2<<CS00);  // CTC, div8
OCR0A = F_CPU/8/4000 - 1;       // match at 4000Hz
ADCSRB = (3<<ADTS0);            // trigger on TIM0 match

Quote:
3. How do I poll an interrupt? And which interrupt can i use for this?

if (TIFR0 & (1<<OCF0A)) ...;

I suggest that you open your data sheet, and ctrl-F for the registers that I used. Personally, I print selected pages on paper. The data sheets are very well written, but do take some absorbing.

Note that my TIM0 example needs a different Fdiv prescaler for > 8MHz. You can easily get perfect times with the 16-bit TIMER1, but you often want it for something else.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you David. This is really helpful.