View previous topic :: View next topic |
Author |
Message |
Lobobranco
Joined: 26 Jul 2010 Posts: 10
|
How does this ADC works? |
Posted: Thu Aug 25, 2011 10:23 am |
|
|
Hello guys,
I've a question about this program that I found here.
Code: |
#include <16F877A.h>
#device adc=8
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=4000000)
//================================
void main()
{
int8 value;
setup_ccp1(CCP_PWM);
// Set the PWM frequency for 244 Hz (with a 4 MHz crystal)
setup_timer_2(T2_DIV_BY_16, 255, 1);
setup_port_a(AN0);
setup_adc(ADC_CLOCK_DIV_8); // Divisor for 4 MHz crystal
set_adc_channel(0);
delay_us(20);
while(1)
{
value = read_adc();
set_pwm1_duty(value);
}
}
|
What is the value stored at the variable value, since this was declared as int8?
For example, if I put 3V at the ADC port, what is the real value of the variable value(int8)? |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Thu Aug 25, 2011 11:02 am |
|
|
Since the code uses the line:
#device adc=8
We know the read_adc() function will return a value from 0 to 0XFF (255), with 0 representing 0 volts and 0XFF representing full scale or the ADC reference voltage. If the PIC is powered from 5.0V then for a 3.0V input the read_adc() function returns:
3.0V/5.0V * 255 = 153
If the PIC were powered from 3.3V the value returned would be:
3.0V/3.3V * 255 = 232
If the ADC was running in 10 bit mode from 3.3V the result would be:
3.0V/3.3V * 1023 = 930 _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Aug 25, 2011 11:39 am |
|
|
Sorry, but not quite:eek: SherpaDoug wrote: |
We know the read_adc() function will return a value from 0 to 0XFF (255), with 0 representing 0 volts... |
OK so far.
Quote: | and 0XFF representing full scale or the ADC reference voltage.
|
0xFF represents one bit's worth LESS than the reference.
Quote: | If the PIC is powered from 5.0V then for a 3.0V input the read_adc() function returns:
3.0V/5.0V * 255 = 153
|
that should be 3.0V/5.0V * 256 = 153 or 154... or both one after another as noise will be present.
Quote: | If the ADC was running in 10 bit mode from 3.3V the result would be:
3.0V/3.3V * 1023 = 930 |
Most probably 931 as its /102*4*. This error is not great, but it's there and will contribute to incorrect results. |
|
|
Lobobranco
Joined: 26 Jul 2010 Posts: 10
|
|
Posted: Fri Aug 26, 2011 11:10 am |
|
|
Thank you guys!
Only one more question.
What if the result is a float value?
For example : 3.3V/5*255=168,3? Will this be rounded? |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Fri Aug 26, 2011 11:27 am |
|
|
It will be truncated (rounded down). 168.3 becomes 168. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Aug 29, 2011 1:01 pm |
|
|
you have set up the timer2 params to give you 10 bit resolution
on your pwm signal.
i wrote a piece of code earlier this year that included something similar.
you might consider these changes to improve resolution.
Code: |
#device adc=10
unsigned int16 value=0;
|
and BTW: with a 4 mhz clock thats a might low frequency
PWM fixed rate you have going there - ie 3.9 khz ....... |
|
|
Lobobranco
Joined: 26 Jul 2010 Posts: 10
|
|
Posted: Mon Aug 29, 2011 1:19 pm |
|
|
Thank you for all guys =) |
|
|
|