# SparkFun Forums

### a/d conversion on a0 for pic16f877a

Have a good idea for a new product for SFE or Olimex? Let us know!

### a/d conversion on a0 for pic16f877a#386

By josh_wolf
#386
Hi, I have code to hook a gameboy camera to a pic 16f877a that I would like to submit for anyone to work with and improve on. But to know it works I need to take the cameras output signal in. Does anyone know where I can find a a/d conversion function in cc5x? So far I get the read signal back from the camera saying its ready to have its picture it took clocked out and the analog data read.

### #396

By sparky
#396
Heck yea - no problem.

A/D is not too bad if you read the datasheet 2 or 3 times. In your case it sounds like you will only need to be reading analog level on one pin using Vdd and GND as the reference points. What I do is poll the GO flag - you set it to start the conversion, hardware clears GO when the A/D is done.

Watch out for AN channel mixups - I know that on some PICs, pin RA0 is analog channel AN0, but RA5 is AN4. That caused me a little pain.

The last thing you need to know is that the 10bit number that is found during an A/D conversion is a number that is in ratio to the voltage level. Huh? You've got 10 bit A/D module - 1024 separate steps (2^10). If you are powering the PIC with 5V, and you are using Vdd and GND as references, then you have 1024 little steps between 0-5V or 4.88mV per step. So if the 10bit A/D returns the number 867 (or 0x363 in hex) then you must do the ratio:

5V/1024 = X/867 where X is the voltage the A/D module just found and 867 is the number the A/D returned.

867 * 5 / 1024 = 4.23 V.

Hope this helps...

This code will take a number of coversions to get an average.

//Read Channel 1 - RA1 for X_ANALOG - using Vrefs+/- as inputs
PORTA = 0b.0000.0000;
TRISA = 0b.0000.1111; //0 = Output, 1 = Input

ADCON1 = 0b.1100.1000; //Setup ADC for right justified with Vref+/- and RA4, RA0,RA1 as Analog

ADCON0 = 0b.0100.1001; //Select Fosc/16 for 8mhz, and channel RA1/AN1, A/D on

for(x = 0 ; x < AVG_AMT ; x++)
{
delay_us(10);

GO = 1; //Convert RA1 to digital

while(GO == 1);