Internal ADC of PIC18F4520

Internal ADC Interfacing with PIC18F4520

 PIC18F4520 contains 8-13 analog inputs. They enable the microcontroller to recognize, not only whether a pin is driven to logic zero or one (0 or +5V), but to precisely measure its voltage and convert it into a numerical value, i.e. digital format. The whole procedure takes place in the A/D converter module which has the following features:

Features of internal ADC

  • The converter generates a 10-bit binary result using the method of successive approximation
  • stores the conversion results into the ADC registers (ADRESL and ADRESH)
  • Result can be stored in Right Justified(RJF)(BY default) and Left Justified format(LJF)
  • There are 8-13 separate analog inputs channels
  • ADCON0, ADCON1, ADCON2 are the control registers associated
  • The A/D converter allows conversion of an analog input signal to a 10-bit binary representation of that signal
  • By selecting voltage references Vref-(Gnd) and Vref+(5V), the minimal resolution or quality of conversion may be adjusted to various needs.

ADC Mode and Registers

Even though the use of A/D converter seems to be very complicated, it is basically very simple, simpler than using timers and serial communication module, anyway.



ADC Mode and Registers
The module is under the control of the bits of four registers:

  • ADRESH – Contains high byte of conversion result;
  • ADRESL – Contains low byte of conversion result;
  • ADCON0 – Analog Digital Control register 0; 
  • ADCON1 -Analog Digital Control register 1
  • ADCON2 -Analog Digital Control register 2
ADRESH and ADRESL Registers

When converting an analog value into a digital one, the result of the 10-bit A/D conversion will be stored in these two registers. In order to deal with this value easier, it can appear in two formats- left justified and right justified. The ADFM bit of the ADCON1 register determines the format of conversion result (see figure 7-2). In the event that A/D converter is not used, these registers may be used as general-purpose registers.

ad result register


Fig. ADRESH and ADRESL Registers

A/D Acquisition Requirements

For the ADC to meet its specified accuracy, it is necessary to provide a certain time delay between selecting specific analog input and measurement itself. This time is called “acquisition time” and mainly depends on the source impedance. There is an equation used for accurately calculating this time, which in the worst case amounts to approximately 20uS. Briefly, after selecting (or changing) the analog input and before starting conversion it is necessary to provide at least 20uS time delay to enable the ACD maximal conversion accuracy.

ADC Clock Period

Time needed to complete a one-bit conversion is defined as TAD. The required TAD must be at least 1,6 uS. One full 10-bit A/D conversion is a bit longer than expected and amounts to 11 TAD periods. However, since both the conversion clock frequency and source are determined by software, one of the available combination of bits ADCS1 and ADCS0 should be selected before voltage measurement on some analog input starts. These bits are stored in the ADCON0 register.

20 Mhz8 Mhz4 Mhz1 Mhz
Fosc/200100 nS250 nS500 nS2 uS
Fosc/801400 nS1 uS2 uS8 uS
Fosc/32101.6 uS4 uS8 uS32 uS
Frc112 – 6 uS2 – 6 uS2 – 6 uS2 – 6 uS

Table 7ADC Clock Period

Any change in the system clock frequency will affect the ADC clock frequency, which may adversely affect the ADC result. Device frequency characteristics are shown in the table above. The values in the shaded cells are outside of recommended range.

How to Use A/D Converter?

In order to enable the A/D converter to run without problems as well as to avoid unexpected results, it is necessary to consider the following:

  • A/D converter does not differ between digital and analog voltages. In order to avoid errors in measurement or chip damage, the pins should be configured as analog inputs before conversion starts. The bits used for this purpose are stored in the TRIS and ANSELH registers;
  • When the port with analog inputs marked as CH0-CH13 is read, the corresponding bits will be driven to logic zero (0); and
  • Roughly speaking, voltage measurement in the converter is based on comparing input voltage with internal scale which has 1024 marks (210=1024). The lowest scale mark stands for the Vref- voltage, whilst the highest mark stands for the Vref+ voltage. Figure 7-3 below shows selectable referent voltages and their minimum and maximum values as well.

adconver diagram

Fig. How to Use The A/D Converter

ADCON0 Register


                                                                 Fig. 7-4 ADCON0 Register

CHS3-CHS0 – Analog Channel Select bits select a pin or an analog channel for conversion, i.e. voltage measurement:


Table 7-3 Analog Channel Status Bits

GO/DONE – A/D Conversion Status bit determines current status of conversion:

  • 1 – A/D conversion is in progress; and
  • 0 – A/D conversion is complete. This bit is automatically cleared by hardware when the A/D conversion is completed.

ADON – A/D On bit enables A/D converter.

  • 1 – A/D converter is enabled; and
  • 0 – A/D converter is disabled.

ADCON1 Register


Fig. 7-5 ADCON1 Register


1 = VREF- (AN2)

0 = VSS

VCFG0 – Voltage Reference bit selects positive voltage reference source needed for A/D converter operating.

1 = VREF+ (AN3)
0 = VDD 

bit 3-0 PCFG<3:0>: A/D Port Configuration Control bits


A = Analog input      D = Digital I/O 



ADFM – A/D Result Format Select bit

  • 1 – Conversion result right justified. Six most significant bits of the ADRESLH are not used; and
  • 0 – Conversion result left justified. Six least significant bits of the ADRESL are not used.
ACQT<2:0>: A/D Acquisition Time Select bits
111 = 20 TAD
110 = 16 TAD
101 = 12 TAD
100 = 8 TAD
011 = 6 TAD
010 = 4 TAD
001 = 2 TAD
000 = 0 TAD

ADCS2,ADCS1, ADCS0 – A/D Conversion Clock Select bits select clock frequency used for internal synchronization of A/D converter. It also affects duration of conversion.

 ADCS<2:0>: A/D Conversion Clock Select bits 
111 = FRC (clock derived from A/D RC oscillator)
110 = FOSC/64
101 = FOSC/16
100 = FOSC/4
011 = FRC (clock derived from A/D RC oscillator)
010 = FOSC/32
001 = FOSC/8
000 = FOSC/2

Table 7-2 A/D Conversion Select Bits

* Clock is generated by internal oscillator which is built in converter.

In Short:

In order to measure voltage on an input pin by A/D converter the following should be done:

Step 1 – Configuring port:

  • Write logic one (1) to the corresponding bit of the TRIS register to configure it as input; and
  • Write logic one (1) to the corresponding bit of the ANSEL register to configure it as analog input.

Step 2 – Configuring ADC module:

  • Configure voltage reference in the ADCON1 register;
  • Select ADC conversion clock in the ADCON0 register;
  • Select one of input channels CH0-CH13 of the ADCON0 register;
  • Select data format using the ADFM bit of the ADCON1 register; and
  • Enable A/D converter by setting the ADON bit of the ADCON0 register.

Step 3 – Configuring ADC interrupt (optionally):

  • Clear the ADIF bit; and
  • Set the ADIE, PEIE and GIE bits.

Step 4 – Wait for the required acquisition time (approximately 20uS) to pass.

Step 5 – Start conversion by setting the GO/DONE bit of the ADCON0 register.

Step 6 – Wait for ADC conversion to complete.

  • It is necessary to check in program loop whether the GO/DONE pin is cleared or wait for an A/D interrupt (must be previously enabled).

Step 7 – Read ADC results:

  • Read the ADRESH and ADRESL registers.

Interfacing Diagram


Video lecture on ADC

Video Proteus Simulation

Embedded C program


#pragma config OSC=HS
#pragma config PWRT=OFF
#pragma config WDT=OFF
#pragma config DEBUG=OFF, LVP=OFF

void lcdcmd(unsigned char value);
void lcddata(unsigned char value);
void msdelay(unsigned int itime);

#define ldata PORTD
#define rs PORTEbits.RE0
#define rw PORTEbits.RE1
#define en PORTEbits.RE2
void main(void)
unsigned int i, d;
unsigned char val,
ADCON0 = 0X01;//ADC ON, CHANNEL0 is selected, NO Start of conversion
ADCON1 = 0X0E;//AN0 i.e. channel0 RA0 as analog pin, rest pins as Digital I/O
ADCON2=0X8A;//ADFM=1 i.e.RJF, Acquisation time = 2TAD, A/D Clock freq= Fosc / 32
lcdcmd(0x38); // 16x2 LCD in 8 bit mode
lcdcmd(0x0E);//Display On, Cursor blinking
lcdcmd(0x01); //CLear Display Screen
lcdcmd(0x06); //Increment cursor shift right
lcdcmd(0x81); // force LCD Cursor to blink at first row second position
ADCON0bits.GO = 1; // Issue SOC command
while(ADCON0bits.DONE ==1); // Monitor DONE# bit, if = 0, A to D Conversion is Complete and 10-bit Result is present in ADRESL:ADRESLH
temp[0]= (ADRESH & 0x0F);//
temp[1]= (ADRESL & 0xF0)>>4;
temp[2]= (ADRESL & 0x0F);

for(d=0; d<3; d++)
if (temp[d] < 10)
temp[d] = temp[d]+0x30; //Convert the digit in ASCII Value
temp[d] = temp[d]+0x37; //Convert the digit in ASCII Value
lcddata(temp[d]); // send ASCII value for display
void lcdcmd (unsigned char value)
ldata=value;//Command value to PORTD which is connected to Data lines of LCD
rs=0; // FOR Command register selection of LCD
rw=0; // WRITE mode
en=1; // generate high to low pulse on ENABLE PIN
void lcddata (unsigned char value)
ldata=value;//Data value to PORTD which is connected to Data lines of LCD
rs=1;// FOR Data register selection of LCD
en=1;// generate high to low pulse on ENABLE PIN
void msdelay (unsigned int itime)
int i,j;


  • Edited, Created and Notes by Prof. Sujit Wagh, SKNCOE, Pune
  • WikiNote Foundation

Last modified: Tuesday, 17 September 2019, 2:33 PM