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.
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 )
ADCON0 REGISTER ( ADDRESS 1FH )
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:
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
Windowed EEPROM version: PIC12C671-04/JW
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:
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:
ADCON1 = 00000000:
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:
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.
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:
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:
Configure the A/D interrupt (if desired):
Wait the required acquisition time.
Wait for A/D conversion to complete, by either:
Read the A/D result register (ADRES), clear bit ADIF if required.
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
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:
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.