I've beening testing the response from an A/D input RA0. By putting the results directly onto an LCD display. but it does not seem to be as linear as I expected . Here are the results that I've achieved.
Tested using DC bench supply.
1.0V = 192
2.0V = 384
2.5V = 480
3.0V = 527
4.0V = 704
5.0V = 824
I assumed that @ 2.5V the digital response would be around 412 counts but it seems to be a long way out. It also seems to jump periodically in larger increment when you increment slowly from 0-5V. I've added filtering caps and resistors to the input but this does not seem to make any difference.
I've tried adding an external reference to AN3 (After changing adcon settings) which give the following results
1V = 240
2V = 480
2.5V = 574 expect to see 511 counts ?
3V = 655
4V = 896
5v = 1023
but the result is still not a linear response.
Here is the code which I have been using can anyone see what I'm doing wrong
Code: Select all
#include<system.h>
#include"AD channels.h"
unsigned char ADCRESL@0x9e; // control reg for A/D
unsigned char ADCRESH@0x1e;
int ad_delay(int loop)// Allow A/D to settle
{
int t;
for(t=0;t<loop;t++);
}
unsigned int display1_value (unsigned int value,char position)
{
// first get the digits
unsigned int thou,hunds, tens, units;
// first get the digits
units= value % 10;
value= value/10;
tens= value % 10;
value= value/10;
hunds= value % 10;
value= value / 10;
thou = value % 10;
lcd_cursor(position,1); // Result position upon on display
lcd_print_ch ('0' + thou);
lcd_print_ch ( '0' + hunds );
lcd_print_ch ( '0' + tens );
lcd_print_ch ( '0' + units );
}
int read_adc0 (char adcon_0 ) // Main A/D conversion sub
{
unsigned char h, l =0;
int result=0;
adcon0 = adcon_0 & 0xFb; /* Switch ADC channel*/
ad_delay(15);
adcon0 = adcon0 + 0x04; //start conversion
while ( adcon0 & 0x04 );//spin while the conversion runs
h = ADCRESH;
l = ADCRESL;
result = (256 * h) + l; // Add high byte-to-low
return result;
}
unsigned char ad_Channel_0() //Channel_0 of A/D PORT RA0 Set for forward power readback
{
unsigned CH0_adcon0=0x05; // Select channel 1
unsigned int result;
result= read_adc0(CH0_adcon0); // analog conversion result
display1_value(result,4); // Display result and position on screen correctly
}