6th July 2010

Tutorial 5 – A/D Conversion in C

posted in Uncategorized |

Tutorial Goal: Implement A/D conversion as seen in Tutorial 3 in C

This document builds on Tutorial 3 and Tutorial 4. The purpose of this tutorial is to familiarize the reader with the A/D functionality of a PIC18F4550 microcontroller using the C18 compiler.

There are functions available to simplify the use of A/D (documented in the PIC18F Peripheral Library Help Document.chm, likely found in C:\MCC18\doc). However, this tutorial will focus on setting everything up manually, since the use of these functions is trivial once the underlying process is understood.

For this tutorial, I will be working with:

Remember that you may need to update your include and lib paths after updating your MPLAB IDE (see here for more details).

Tutorial 5 Setup - A/D conversion in C on the PIC18F microcontroller
The starting point will be the hardware from Tutorial 3 and the code from the previous tutorial, which blinked an LED at a specified interval. The following code is explained in more detail in Tutorial 4:

#pragma config FOSC = INTOSCIO_EC //Internal oscillator, port function on RA6, EC used by USB
#pragma config WDT = OFF //Disable watchdog timer

#define LEDPin LATDbits.LATD1 //Define LEDPin as PORT D Pin 1
#define LEDTris TRISDbits.TRISD1 //Define LEDTris as TRISD Pin 1

We do not need to #define the A/D pin since we will not directly address it.

The A/D settings are explained in detail in Tutorial 3, so please look through it before continuing with this tutorial.

To set up the A/D module, the ADCON registers must be set:

	ADCON1 = 0b00001110;//VSS,VDD ref. AN0 analog only
	ADCON0 = 0x00;//clear ADCON0 to select channel 0 (AN0)
	ADCON2 = 0b00001000;//ADCON2 setup: Left justified, Tacq=2Tad, Tad=2*Tosc (or Fosc/2)
	ADCON0bits.ADON = 0x01;//Enable A/D module

Once the A/D module is set up and enabled, we can use it to gather data:

	while(1)
	{
		ADCON0bits.GO_DONE = 1;//Start A/D Conversion

		while(ADCON0bits.GO_DONE != 0);//Loop here until A/D conversion completes
		delay = ADRESH;//Set the delay to the 8 MSB

		LEDPin = ~LEDPin;//Toggle LED Pin
		if (delay > 0)
			Delay1KTCYx(delay);//Delay (argument of 250 will delay 1 second at 1MHz since each instruction takes 4 cycles)
	}

Setting the GO_DONE bit starts the conversion. It is possible to receive the result via an interrupt, but to keep this tutorial simple, a while loop will poll the GO_DONE pin until it goes low (meaning the A/D conversion is finished). The amount of time it takes to go low depends on the ADCON2 settings above (consult Tutorial 3 for more information). Once the conversion is finished, we set the delay variable to the 8 Most Significant Bits of the result. It would be possible to get all 10 bits using

delay = (((unsigned int)ADRESH)<<8)|(ADRESL);

but the Delay1KTCYx function only takes values of 1-255, so the extra 2 bits are unnecessary for this application. After toggling the pin, we should check if the delay is 0. This is important because executing Delay1KTCYx with a value of 0 will cause a delay of 256,000 cycles instead of the intended 0 cycles.

This is everything that is necessary to perform a conversion and retrieve the result. An obvious improvement would be to replace the while loop with an interrupt, so that the main loop would not need to actively wait for the conversion.

The result is visually the same as the video in Tutorial 3:

Check the FAQ (in progress) or ask a question below if you are having problems.

Files:
C file:main.c
Project:tutorial5.zip

This entry was posted on Tuesday, July 6th, 2010 at 3:02 pm and is filed under Uncategorized. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

  • Sponsored Links

  •  

  • July 2010
    M T W T F S S
    « Nov    
     1234
    567891011
    12131415161718
    19202122232425
    262728293031  
  • Donate