Guides‎ > ‎

Analog to digital converter on PIC18

posted Dec 28, 2010, 6:36 AM by Danny Ng   [ updated Feb 8, 2011, 6:41 PM ]
The gadget spec URL could not be found

The analog to digital converter (ADC) is a commonly required in most of the projects. Analog voltage measurement can be done using the ADC hardware built in together in a PIC. The picture below show a simple setup for measuring the voltage through the adjustment of the potentiometer. PIC used in this example come with a 10 bit ADC. In the picture the hex value shown is the ADC value acquired from the hardware. After a simple conversion the voltage can be obtain from this value.
A simple circuit is constructed to test the ADC. The potentiometer is use to vary the voltage level on the AN0 pin.

The next step would be to configure the register on the PIC for the ADC to operate. ADCON0 sets the refrence voltage to Vdd and Vss and select AN0 as the input for the ADC. ADCON1 configure the PIN as analog input. Only PIN AN0 is selected as analog input in this example. ADCON2 sets the required time for acquisition. The value for TAD is choose based on the calculation in the datasheet (pic18f2455, page 298-299). ADC module is turn on for it to function.

ADCON0bits.ADON = 1;

A routine for reading of ADC value is created. The acquisition is started by setting the GO bit in ADCON0. Conversion is done when the done bits turn 0. The high and low byte of the ADC results are joined in to a 16 bit data and pass back from the function.

unsigned int ReadADC(void){
unsigned int temp;
ADCON0bits.GO = 1;
temp = ADRESH;
temp = ((temp << 8)| ADRESL );
return temp;

A simple formula can be use to calculate the voltage from the ADC result. The result is multiply by the max value of reference voltage and divided by 1024. Doing this will obtain the voltage on the pin AN0.

    fADCValue = ADCValue * 5;
    fADCValue /= (1024);

To display the floating point number conversion to string must be done. The function sprintf is use to format the output so that it can be showed on the LCD. The sprintf function provided by C18 can't be used directly on a floating point number, so the number must 1st be breakup in to the digits left and right of the decimal point. The sprintf is used to join up the 2 parts and the floating point number is display out on the 2x16 lcd.

void Displayfloat(float data){
char LCDOut[16];
long multiplier = 10000;
long lWhole=0; // Stores digits left of decimal
unsigned long ulPart=0; // Stores digits right of decimal
sprintf(LCDOut,"Dec: %ld.%04liV", lWhole, ulPart);

For this example an average of 200 data is taken before the ADC value is shown out on the LCD display. Attached is the project file for this guide.

Danny Ng,
Dec 28, 2010, 7:03 AM