ADC In (Low Level Version)

The analog-to-digital converters on the 18Fxx2, 16F87x, and 16F81x series PICs (and others) are of 10-bit resolution. This means that when they measure an incoming voltage, they compare that voltage to a reference voltage, and give you the comparison represented as a 10-bit number (0-1023).

To use the analog-to-digital converters on a PIC through picBasic Pro without using ADCIN, you need to know something about the special memory registers on the PIC related to the ADC. The registers you need are as follows (for more on these registers, see the data sheet):

  • ADCON0 – ADC configuration register 0
  • ADCON1 – ADC configuration register 1
  • TRISA/TRISE – input/output state register for port A (TRISE is for port E, on the 40-pin PICs only)
  • ADRESH – ADC conversion result register, high byte
  • ADRESL – ADC conversion result register, low byte

The bits of the ADCON0 and ADCON1 registers are used to set the various parameters of the A-to-D converter. You set the various bits high or low to configure the parameters connected to them, as follows:

ADCON0 bits:

  • 7-6: AD Clock select. Lets you choose whether the ADC’s clock is determined by the PIC’s oscillator or by an internal RC oscillator.
  • 5-3: AD Channel Select. Lets you choose which A-to-D input you’re listening to
  • 2 – AD conversion status: Set this bit high to start an A-to-D conversion. This bit automatically goes low when the conversion is done, so you can use it to tell when to read the result registers.
  • 1 – not used
  • 0 – AD on/off. Turns on or off the ADC.

ADCON1 bits:

7 – result format: There are 16 bits in the two result registers. The ADC conversion takes 10 bits. Therefore, 6 bits are not used. The result format bit lets you determine whether the first 6 bits of the high register are not used (right justified), or the six last bits of the low register are not used (left justified). The following diagram makes this clearer. The number 1023 (in binary, 1111111111) is the result in both cases:

Justification: ADRESH ADRESL
Right justified X X X X X X 1 1 1 1 1 1 1 1 1 1
Left justified 1 1 1 1 1 1 1 1 1 1 X X X X X X

6-4: not used

3-0: AD port configuration control. sets which pins of the AD port are used as analog inputs, which are used as digital inputs, and which is used as the reference voltage.

For all configuration registers, consult the data sheet for your individual pic to determine the actual values needed. The values used in this example are for the 16F87x PICs.


These are the bits that determine if each pin on a given port are inputs or outputs. Set the appropriate ones high or low, as needed. Set any pins you plan to use as analog inputs to be inputs. For example:

TRISA = %11111111 sets all pins of port A to input
TRISA = %00000001 sets portA pin 0 as input, all others output.
TRISA = %00000011 sets portA, pins 0 and 1 to inputs, all others output.

Once you’ve set the configuration registers, you’re ready to read the A-to-D converter. To do this, you set the AD start bit high, wait until it goes low, then read the AD result registers. The following example shows how to read an analog input on port A pin 0 into a word variable called adVar:

adVar  var word     'Create advar to store result 
TRISA = %11111111   ' Set PORTA to all input     
ADCON1 = %10000010  ' Set PORTA to analog and RIGHT justify result 
ADCON0 = %11000001  ' Configure and turn on A/D Module 
Pause 500           ' Wait half a second 
     ADCON0.2 = 1          'set start bit high to start conversion
     ' do nothing until conversion is done
     while ADCON0.2 = 1
         pause 5
     adVar.highbyte = ADRESH 'move high byte of result to adVar 
     adVar.lowbyte = ADRESL  'move LOW byte of result to adVar
     SEROUT2 PORTC.6, 16468, [DEC adVar, 10, 13]
     pause 10                'Wait .01 second        
Goto main