PIC18 Explorer Board Tutorial: Analog to Digital Conversion With the Potentiometer

by Miguel on June 6, 2011

in PIC,PIC18 Explorer Board

pic18 explorer board potentiometer

The potentiometer in a PIC18 Explorer Board

The Program We’ll Be Writing

We will write a program that will read the voltage at the potentiometer and we will display that voltage using the LEDs in port D.

The Potentiometer

The potentiometer is the wheel to the left of the LCD, it is connected to RA0. Turning the potentiometer to the right increases the voltage at RA0, turning it left decreases the voltage.

potentiometer labels

turning it right increases input voltage, turning it left decreases it

The Data We’ll Receive

The data we are reading is a binary representation of the voltage at the pot (RA0), more precisely it is a 10 bit binary number, actually split into two (uneven) sections: the most significant and least significant bits. We will only be using the most significant bits which will be eight ( the least significant bits are 2)

If all the bits are 1 we have the highest possible voltage ( ideally 5.0V) all bits zero will mean 0.0V (ideally).

// example
0b00000000; // will be least voltage
0b11111111; // will be max voltage

any other binary number in between is a voltage between 0V and 5V.

Configure The Ports

Since the pot is located at port A we will make port A an input; port D will be an output.

	TRISA=0xff; // port A input
	TRISD=0x00; // port D output

Configuring The A/D Module

There are three bit sets you need to configure ADCON0, ADCON1 and ADCON2, each bit set has eight bits.

ADCON0 Configuration

The first two most significant bits (from left to write) are unimplemented so we can leave them as zeros.

	ADCON0=0b00

The next four let you choose the channel want to use, since the potentiometer is connected to AN0 we will make all the four bits zeros.

	ADCON0=0b000000

The next bit let’s you start the analog to digital conversion, in other words when ever you give it a value of 1 it will start reading the voltage, we are not there yet so make a zero.

	ADCON0=0b0000000

Lastly we want to turn on the analog to digital module

	ADCON0=0b00000001;

You can read page 270 of the datasheet to see all the available options.

ADCON1 Configuration

Similarly for ADCON1 one we have (from left to right) the first two bits which are unimplemented.

ADCON1=0b00

The next two represent your reference voltage. I’ll be using AVDD and AVSS so my bits are all zeros

ADCON1=0b0000

The next four bits let you select which ports you want to be analog and which digital. We can use several codes since we need AN0 to be analog and we are not worried about the rest, so I’ll be using all zeros

ADCON1=0b00000000;

Check page 271 of the datasheet to see all options that are available.

ADCON2 Configuration

This is the last bit set we need to configure before we start the conversion.

The first bit lets you select the justification of your result (left of right), we want left so ours is 0;

ADCON2=0b0

The next bit is unimplemented so make it zero as well

ADCON2=0b00

Next three bits are to set the time acquisition delay, there are several options (check page 272 of the datasheet) we want to go with 0 TAD so we have all zeros.

ADCON2=0b00000

The last three bits set the oscillator, we are going with FOSC/32 so we need a two (in binary)

ADCON2=0b00000010;

Starting The Conversion and Reading the Result

Setting the GO_DONE bit of ADCON0 to 1 will start the conversion, GO_DONE will change to zero when the conversion is finished. The result of the conversion is store in ADRESH and ADRESL, most significant and least significant bits respectively.

So here is what we need

ADCON0bits.GO_DONE=1; // starts conversion
while(ADCON0bits.GO_DONE==1); // wait, it's converting
PORTD=ADRESH; // turn on lights, this is outside of the while loop

The Complete Code

Putting everything together we end up with this program.

#include <p18f8722.h>

#pragma config OSC=HS // high speed oscillator
#pragma config WDT=OFF // watch dog off

void main()
{ 

	TRISA=0xff; // port A input
	TRISD=0x00; // port D output
	PORTD=0x00; // port lights off
	PORTA=0x00;
	
	MEMCONbits.EBDIS=1; // make port d digital
	
	ADCON0=0b00000001; 
	// (00) unimplemented (0000) channel AN0 (0)don't start yet (1) turn on analog to digital module, see page 270
	
	ADCON1=0b00000000; 
	// (00) unimplemented (00) using AVDD and AVSS (0000) A/D port bits, see page 271
	
	ADCON2=0b00000010;
	 // (0) left justified (0) unimplemented (000) 0 TAD (010) FOSC/32, see page 272
		
	while(1)
	{
		ADCON0bits.GO_DONE=1; // starts conversion
		while(ADCON0bits.GO_DONE==1); // wait, it's converting
		
		PORTD=ADRESH; // this is outise of the while loop
	
	}
}

Previous post:

Next post: