Using the Onboard  8-Bit A/D Converter of the PIC12C67X

Before we get deep into how to use the A/D converter, let's find out how to configure the PIC12C67X I/O-pins using the A/D configuration registers.  The PIC12C67X series has two configuration registers for the analog port-pins.

bullet

The ADCON0 register is used to control the operation of the A/D module.

bullet

The ADCON1 register is used to configure the functions of the A/D port-pins.

The following code shows how to configure the A/D pins for use as digital I/O-pins.  Take note here that we only need to configure ADCON1 to setup our I/O-pins as digital.  This is because ADCON0 is used only to configure the A/D operation.  ADCON1 is used to configure the functions of the port-pins thereby setting them up as A/D inputs, or digital I/O-pins.

The PicBasic Pro instruction: ADCON1 = 7  loads the ADCON1 register with decimal number 7.  This value  tells the PIC12C67X that we want to use the A/D-pins as digital I/O.  Refer to the ADCON1 register data below, and you'll see why this works.

Note:  The ADCON1 and TRIS registers control the operation of the A/D port pins.  To be used as analog inputs, the TRIS bits must be set to inputs.

Notice from the chart below showing the ADCON1 register that on power-up reset the PIC12C67X first starts up with all the analog port-pins configured as [analog inputs].  If you plan to use [all] the PIC12C67X series A/D port-pins as general purpose I/O-pins, you MUST first set the ADCON1 register to 7, or %00000111 for binary number 7.  Since the ADCON1 register only has 3-bits that are actually used to configure the port-pins, the extra bits are simply ignored.

Another important point to remember is that you can configure some of these I/O-pins as A/D inputs, and the others as digital I/O-pins.  Take your time looking at the configuration registers (shown below), and you'll see the various options & how to easily configure the PIC12C67X A/D pins as either digital I/O, or analog inputs.

Example:  You decide that you would like to use port-pin GP0 as an A/D input, but you want to use the remaining port-pins as digital I/O.  Be referring to the chart below, you can see that you'll need to put the value 110 into ADCON1.  The following PicBasic single-line of code will take care of configuring your port-pins.  ADCON1 = %00000110 or ADCON1 = 6.  Remember, the three least significant-bits are the only ones actually used. Bit-7, 6, 5, 4, and 3 are never used and you can simply ignore them.

ADCON1 REGISTER ( ADDRESS 9FH )
U-0 U-0 U-0 U-0 U-0 R/W-0 U-0 U-0
--- --- --- --- --- PCFG2 PCFG1 PCFG0-
BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
  BIT 7-3: Unimplemented: read as '0'    R = Readable bit
  W = Writable bit
   U = Unimplemented bit, read as '0'
  -n = Value at POR ( Power-On Reset )
  BIT 2-0: PCFG2 : PCFG0: A/D Port Configuration Control Bits 
           
PCFG2:PCFG0 GP4 GP2 GP1 GP0 Vref
000 * A A A A Vdd NOTE: After a Power-On reset, the values  shown by each register will be the default value for that register-bit.

A = Analog Input
D = Digital I/O

001 A A Vref A GP1
010 D A A A Vdd
011 D A Vref A GP1
100 D D A A Vdd
101 D D Vref A GP1
110 D D D A Vdd
111 D D D D ---
  * NOTE 1: Value on reset.  NOTE: Any instruction that reads a pin configured as an analog input will read a '0'.

ADCON0 REGISTER ( ADDRESS 1FH )
R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
ADCS1 ADCS0 r CHS1 CHS0 GO/DONE r ADON
BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
  BIT 7-6: ADCS1: ADCS0: A/D Conversion Clock Select Bits.    R = Readable bit
  W = Writable bit
   U = Unimplemented bit, read as '0'
  -n = Value at POR ( Power-On Reset )
    r = Resereved
  00 = Fosc/2
  01 = Fosc/8
  10 = Fosc/32
  11 = Frc (Clock derived from an RC oscillator)
  BIT 5: Reserved
  BIT 4-3: CHS1: CHS0: Analog Channel Select bits
  00 = Channel 0, (GP0/AN0) NOTE: After a Power-On reset, the values shown by each register will be the default value for that register-bit.
  01 = Channel 1, (GP1/AN1)
  10 = Channel 2, (GP2/AN2)
  11 = Channel 3, (GP4/AN3)
  BIT 2: GO/DONE: A/D Conversion Status Bit
  If ADON = 1
  1 = A/D Conversion in progress (Setting this bit starts the conversion)
  0 = A/D Conversion not in progress (This bit is automatically cleared by hardware when the A/D conversion is complete)
  BIT 1: Reserved
  BIT 0: ADON: A/D On Bit
  1 = A/D converter module is operating
  0 = A/D converter module is shut off and consuming no current
 

At first it may seem a little confusing, but once you become familiar with setting the configuration registers, you'll be well on your way to taking full advantage of the PIC12C67X, 8-pin microcontrollers.

PicBasic has the ability to load specific registers with certain values by simply referring to the register by name, followed by the value you want to load into the register.  For example:

ADCON1 = 7

This is handy, but you still need to know the name of the registers you're working with.  When using PicBasic, it's important that you do the following:
 
bulletResearch the Microchip web site for a PIC that meets your specific applications requirements.
bulletDownload the datasheet for the PIC you plan to use from the Microchip web site.
bulletBecome familiar with the configuration registers.

Microchip has such an incredible selection of different PIC microcontrollers to select from, that you'll spend a good amount of time during the selection process.  Of course, there's always the hobbyist way of selecting a PIC as well.  If it's the cheapest one, I can find them quickly, and it works, "USE IT..!"

The PIC12C671, and PIC12C672 are very affordable even if you buy them in single quantities.  They drop to only $1.97 each in quantities of 25.  You can buy them online from Digi-Key at: http://www.digikey.com

Part numbers:

Windowed EEPROM version: PIC12C671-04/JW
OTP (One time programmable): PIC12C671-04/P

If you want the PIC12C672, simply replace the number 1 in the last digit with a 2.  For the 10MHz versions, just replace the 04 with 10.

Using the A/D Converter:


PIC12C671 & PIC12C672 Pin Diagram

We can see by the default register values after POR, (power-on-reset) that the PIC12C671 always powers-up with the A/D-pins configured as analog inputs.  The value of 00000000 loaded by default into the ADCON0 register after a power-on-reset causes the PIC12C671 to be in the following mode when power is first applied, or after a reset:

ADCON0 = 00000000:

bulletThe A/D conversion clock select is set to: Fosc/2.
bulletThe Analog channel select is set to: GP0 = A/D input.
bulletThe A/D Conversion-bit is set to: A/D conversion not in progress.
bulletThe A/D On bit is set to: Converter module is shutoff and consumes no operating current.

ADCON1 = 00000000:

bulletAll the I/O-pins are setup to be: A/D inputs.
bulletVref is set to: Vdd = Vref.

This means the PIC12C671 is set to operate with all the A/D-pins as analog inputs with channel 0, (GP0) as the analog input-pin selected.  The default power-on reset values "assume" you're going to use channel 0, (GP0) as the analog input.  These values also "assume" the device operating frequency will be at 1.25MHz or 333.33KHz.

The datasheet states that Fosc/2 will only work with operating frequencies of 1.25MHz, or 333.33KHz.  If you're using a 4MHz ceramic oscillator, crystal, or the internal 4MHz oscillator, this can screw you up big-time because you violate the Tad requirements.  Here's why..!

About Tad & Selecting the A/D Conversion Clock:

The A/D conversion time per bit is defined as Tad.  The A/D conversion requires 9.5 Tad per 8-bit conversion.  The source of the A/D conversion clock is software selected.  The four possible options for Tad are:

bullet2Tosc.
bullet8Tosc.
bullet32Tosc.
bulletPrecision internal 4 MHz oscillator.

Important Note:  For correct A/D conversions, the A/D conversion clock (Tad) must be selected

The datasheet shows the Tad vs. Device Operating Frequencies in the chart below.  Using this chart it's easy to select the correct bit-values to configure the A/D conversion clock required for the oscillator value you're planning to use.  I got a little lazy and decided to use a screen capture from the datasheet instead of creating a table.  Here's how to use it:

The following table shows the resultant Tad times derived from the device operating frequencies and the A/D clock source selected.


Tad vs. Device Operating Frequencies

As shown above, if you're using the internal ADC RC oscillator, you need to set the ADCON0 bits ADCS1, ADCS0 to 11.  Using the internal ADC clock is only desirable when running the PIC at low clock frequencies to conserve power.  If you're using a 4MHz ceramic resonator, crystal or other clock source, you'll need to set these bits to either 01, or 10.

Let's dive right into some sample code to configure the A/D inputs and acquire an analog value.  We will take this analog value and send it to the PC serial port using one of the I/O-pins as a serial output.  This example will assume the following parameters:

bullet

We are using the internal precision 4MHz oscillator to conserve I/O-pins.

bullet

We want to use GP0 as our analog input pin (A/D channel-0).

bullet

We want to use GP1 as our serial output-pin to the PC.

Following along with the datasheet for the PIC12C671, we'll need to perform the following sequence to achieve our goals:

The following steps should be followed when doing an A/D conversion:

  1. Configure the A/D module:
    bullet

    Configure analog pins / voltage reference / and digital I/O (ADCON1).

    bullet

    Select A/D input channel (ADCON0).

    bullet

    Select A/D conversion clock (ADCON0).

    bullet

    Turn on A/D module (ADCON0).

  2. Configure the A/D interrupt (if desired):
    bullet

    Clear ADIF bit.

    bullet

    Set ADIE bit.

    bullet

    Set GIE bit.

  3. Wait the required acquisition time.

  4. Start conversion.
    bullet

    Set GO/DONE bit (ADCON0).

  5. Wait for A/D conversion to complete, by either:
    bullet

    Polling for the GO/DONE bit to be cleared.

    bullet

    Waiting for the A/D interrupt.

  6. Read the A/D result register (ADRES), clear bit ADIF if required.

  7. For the next conversion, go to step 1 or step 2 as required.  The A/D conversion time per bit is defined as Tad.  A minimum wait of 2Tad is required before the next acquisition starts.

Looks pretty complicated doesn't it..?  It's really not.  Here's how we do it with PicBasic:


'-------------------------------------------------------------------------
' PIC12C671 A/D SAMPLE ROUTINE FOR TESTING
'-------------------------------------------------------------------------
' PIN  NAME     USE/CONNECTION
'  1   Vdd      +5VDC
'  2   GPIO.5   N/C (NO CONNECTION)
'  3   GPIO.4   N/C
'  4   GPIO.3   N/C
'  5   GPIO.2   N/C
'  6   GPIO.1   SERIAL OUTPUT TO PC
'  7   GPIO.0   1K RESISTOR TO CENTER OF 5K POT
'  8   VSS      GROUND
'-------------------------------------------------------------------------
DEFINE OSCCAL_1k 1      'SET OSCCAL FOR PIC12C671
RESULT VAR BYTE		'A/D CONVERSION RESULT STORAGE BYTE
ADCON1 = 6		'SET GP.0 TO ANALOG INPUT, Vref = Vdd, ALL ELSE = DIGITAL I/O

MAIN:
GOSUB GETVAL		'SETUP A/D
PAUSE 1000		'PAUSE FOR 1 SECOND
SEROUT GPIO.1,N2400,[RESULT] 'SEND A/D CONVERSION RESULT TO THE PC SERIAL PORT
PAUSE 1000		'PAUSE FOR 1 SECOND
GOTO MAIN

GETRESULT:
PAUSEUS 50		'WAIT FOR A/D CHANNEL SETUP (50 uS)
ADCON0.2 = 1		'START CONVERSION BY SETTING GO/DONE-BIT (HIGH)

LOOP:                   'WAIT FOR GO/DONE BIT TO BE CLEARED
 IF ADCON0.2=1 THEN     'CHECK GO/DONE BIT (0=DONE)
   GOTO LOOP            'NOT FINISHED CONVERTING, THEN LOOP UNTIL DONE
 ENDIF			'IF STATEMENT SATISFIED, ADCON0.2 = 0 (DONE)
RETURN			'FINISHED CONVERSION, RETURN TO GETVAL ROUTINE

GETVAL:
ADCON0=%10000001	'SET A/D Fosc/32,[4MHz], CHANNEL-0 = ON
GOSUB GETRESULT		'START THE CONVERSION
RESULT = ADRES		'STORE THE A/D CONVERSION VALUE IN RESULT
RETURN			'RETURN TO MAIN ROUTINE, START OVER

END			'END PROGRAM


A/D Results


Here's the simple schematic to use for this experiment:

We setup channel-0 as the A/D input, read the analog value present on channel-0, and sent the analog value to the PC serial port through pin GP1.  Using PicBasic we can easily access & use the onboard A/D converter of the PIC12C671.  Using the onboard 4 MHz oscillator to free-up the two extra I/O-pins is simple with the command DEFINE OSCCAL_1K 1.

This whole application looks pretty mundane until you realize what you can do with the A/D converter.  There are several very useful projects we can create using this small 8-pin PIC.  Here are just a few ideas:

 
bulletA light-following Robot.  Using up to 5 photo resistors, we can create a Robot that follows light by turning towards the largest value returned from each A/D conversion.  This could easily be integrated with another PIC, or even the BASIC Stamp by sending the A/D conversion values serially to the other PIC, or Stamp.
bulletWe could do just the opposite, and create a Robot that avoids the light, and seeks darkness by turning towards the lowest A/D value based on input from up to 5 photo resistors..
bulletA plant positioning system that controls a servo motor based on the input from the A/D conversion.  The servo motor is turned to face the plant towards the highest value, thus positioning the plant where it always has the brightest sunshine directly on it.
bulletA voltage monitoring system that warns us when the voltage drops below, or goes above, pre-determined limits.
bulletA simple on/off switch based on the amount of light striking a CDS-Cell.
bulletA serial voltage meter that displays the voltage on your PC screen.
bulletA watering system for the yard that cuts-off the water during peak sunlight, and turns in back on during low light levels.
bulletA circuit that activates a back-up power supply when low voltage is sensed.
bulletLow-voltage, battery operated, low-battery warning systems.
bulletMovement detection systems based on light-beam interference.  Have you ever seen a toy that started talking when you approached it..?  Food for thought..!

These are only a few ideas, but the applications are virtually endless.

That's it for using the PIC12C671 A/D converter.  This example showed how to use A/D channel-0 (GP0), but it should help you understand how to configure the ADCON0, ADCON1 A/D configurations registers, and take advantage of the 8-pin, PIC12C67X series microcontrollers.  These are powerful little microcontrollers and understanding how to set them up by configuring the internal registers makes integrating them into your projects simple & fun.  The first article in this series shows how to configure the onboard oscillator, and gives details of how it works.  Click HERE to see the first article in this series.

 
bullet

Click HERE to purchase PicBasic Compilers - and hardware.

bullet

Click HERE to learn more about the PicBasic compiler.

bullet

Click HERE to return to the PicBasic projects page.