AVR ADC prescaler and ADC clock frequency.

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

Can somebody tell me a clear explanation of ADC clock frequency for 10-bit operation?

What are its functions in the analog to digital conversion ? How to choose a proper clock frequency and set the prescalar ?

Lastly, how do I configure the ADC prescalar using codewizardAVR in Codevision ? I didn't see a prescalar tab there.

Thank you.

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

You select a prescaler to divide the MCU system clock to ADC clock which is used to clock the ADC converter. The datasheet says what is a safe range for ADC clock and how to set the prescaler.

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

Quote:

Lastly, how do I configure the ADC prescalar using codewizardAVR in Codevision ? I didn't see a prescalar tab there.


In both 2.05.* and 2.60, select the ADC/Analog to Digital Converter. Enable it. Then a "Clock:" drop-down list appears, with the values in kHz allowed by the system clock speed setting and available prescaler values.

Quote:

What are its functions in the analog to digital conversion ? How to choose a proper clock frequency and set the prescalar ?


What part of the datasheet discussion is unclear?

Quote:
23.4 Prescaling and Conversion Timing

[Figure 23-3. ADC Prescaler]

By default, the successive approximation circuitry requires an input clock frequency between 50 kHz and 200 kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200 kHz to get a higher sample rate.

The ADC module contains a prescaler, which generates an acceptable ADC clock frequency
from any CPU frequency above 100 kHz. The prescaling is set by the ADPS bits in ADCSRA.
The prescaler starts counting from the moment the ADC is switched on by setting the ADEN bit in ADCSRA. The prescaler keeps running for as long as the ADEN bit is set, and is continuously reset when ADEN is low.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

As most people presumably want to run the ADC as fast as possible but remain in the specified 50..200kHz window the idea would be to get as close to 200kHz as possible. So, say the CPU is clocked at 12MHz then do 12M/200k. The result is 60 so in a perfect world you'd set the ADC prescaler to be 60 and hit 200k exactly. The only thing is your prescaler choices are more limited and must be a binary divisor (/32, /64, /128 etc.). Well that /64 is pretty close to the 60 we really wanted and it's on the right side: being a slightly bigger divisor than /60 it means the ADC will be clocked just slightly slower than 200kHz so will be in the 50..200 acceptable window. In fact 12M/64=187.5kHz.

So that's the general idea. Take F_CPU (12MHz or whatever) and divide by 200,000 then pick the next multiple of 2 above this as a prescaler.

Note something interesting: if F_CPU is 8MHz (say) then 8M/200k=40 this is above /32 so you have to pick /64 as the prescaler to use but 8M/64=125kHz which is miles away from the optimal 200kHz. Now look what happens if you slow the CPU down to 6.4MHz: 6.4M/200k=32 so you can use a /32 prescaler and achieve 200kHz instead of just 125kHz by actually slowing the CPU down from 8MHz to 6.4MHz.

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

Thank you everybody for the explanation. I use XTAL 12MHz and decided to use prescaler of 64 so my ADC clock is 187.5 kHz.

Well, I want to ask again, what speed is affected by this frequency ? the conversion speed or anything else ?

Either near to 50 kHz or near to 200 kHz, is the speed different very significant ?

Actually I've tried to display ADC on the LCD. I use LDR and the ADC is always changing very very fast. I can only see the first digit while the rest of the digits are changing fast. Is ADC clock can affect the display ? or any other suggestions maybe ?

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

Quote:

Well, I want to ask again, what speed is affected by this frequency ? the conversion speed or anything else ?

Only the conversion speed. After the first conversion each ADC conversion takes 13 of these clock pulses. So your conversion rate is effectively 187.5/13kHz = 14.42kHz or to look at it another way that is a conversion every 69.33us

There's no point updating an LCD at anything more than about 10 times a second or it's just look like a "blur" to the user if the digits are changing every time. If you get a conversion every 69.33us you might as well make 1,000 readings at a time, average them and update the display every ~70ms. IN fact even that may be too fact and look a bit blurry. Maybe consider 1,500 or 2,000 readings at a time before you average/display.

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

LDR? "Light-Dependent Resistor"? In an ambient, I'd expect that to be fairly stable. But indeed, if a hand-held light meter or an "eye" on a moving robot--it would be jumpy.

Also describe the circuit. In particular, the driving impedance of the signal.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:
make 1,000 readings at a time, average them and update the display every ~70ms. IN fact even that may be too fact and look a bit blurry. Maybe consider 1,500 or 2,000 readings at a time before you average/display.

Eemm sorry, how do I do that ? I just follow the Codevision setting and make no change.

Quote:
LDR?

Yes, Light-Dependent Resistor.

I attach my circuit. I've rebuilt it many times and never get a stable result.

Attachment(s): 

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

Quote:

Eemm sorry, how do I do that ?

Well you must have a routine that makes one ADC reading? If so call it 1,000 times. Something like:

uint32_t total = 0;
uint16_t i;

for (i=0; i < 1000; i++) {
  total += ADC_read();
}
total /= 1000;

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

Quote:
you must have a routine that makes one ADC reading?

Yes, off course.

Thank you very much clawson. I will try it.

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

Quote:

Well you must have a routine that makes one ADC reading? If so call it 1,000 times. Something like:

I'm partial to a count of 50 or 60 or 64, as that fits into a uint16_t. And at ~5 conversions/millisecond it is fast enough to capture a slowly-moving signal well.

I'd have to see some code to comment further. Unless the light source is a flickering candle, I'd expect fairly stable results. But look at the circuit, too--no filtering, no bypass caps. My guess would be a lot of ripple somewhere.

Photoresistors can be at hundreds of kohms. (Didn't I ask for that info earlier?) High-impedance signal picks up noise easily. A small cap near the input will help with filtering, as well as provide a source for the ADC to sip from.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:
Well you must have a routine that makes one ADC reading? If so call it 1,000 times. Something like:

I've tried it but the ADC still changing.

Quote:
A small cap near the input will help with filtering

I tried to add 100 uF to the input and ADC changing but very slow, I can see the value now. The problem is ADC start from small value like 100 then increases till it reach the real value of the LDR. It still changing but not so fast. Is there any other suggestions?

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

Quote:

I've tried it but the ADC still changing.

So what? Rather than 1000 consider an example when there are just five readings of 407, 413, 404, 409, 410. Add them up, divide by 5 and you get 408.6 which probably rounds up to display as 409. As I said don't try to update the display too fast (which is why I suggested 1000, 1500 or even 2000) and maybe you see it just flickering between 408,409, 410. No problem with that I guess. If you want to slow the changes down even further then maybe employ a Kalman filter.

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

Quote:

A small cap near the input will help with filtering

Quote:

I tried to add 100 uF to the input and ADC changing but very slow

100uF is not a "small cap" in this context. The "best" value will depend on a variety of things. Try a few nF.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.