PIC Analog to Digital Converter C Programming




The PIC16F690 microcontroller is one of Microchip midrange 8-bit microcontroller that has a build in 10-bit resolution of Analog to Digital Converter (ADC) peripheral. The ADC is one of the important features that enable us to digitize our analog world. Usually we use the electronic sensor to convert the analog value to the voltage level value. Some of the basic sensor such as LDR (Light Dependent Resistor) is used for measuring the light intensity or NTC (Negative Temperature Coefficient) a special resistor for measuring the temperature.PIC Analog to Digital Converter C Programming

Today many manufactures produce sophisticated sensors for specific task such as sharp GP2D120X is use for distance measurement, National Semiconductor LM35 for precision centigrade temperature sensor, HS12 humidity sensor from GE, TGS2442 carbon monoxide gas sensor from Figaro and many more. Therefore before we can use all of these cool sensors we have to learn the basic of how to use ADC peripheral inside the PIC 16F690 microcontroller.

On this tutorial we will learn how to program the Microchip PIC microcontroller for reading the analog signal using HITECT PICC-Lite C compiler. We will use the PICJazz 16F690 learning board (PICJazz 16F690 schema) from ermicro as our learning platform and let’s start the fun by pasting this following code to your Microchip MPLAB IDE:

// ***************************************************************************
//  File Name    : adc.c
//  Version      : 1.0
//  Description  : Analog to Digital Converter
//  Author(s)    : RWB
//  Target(s)    : PICJazz 16F690 Board
//  Compiler     : HITECT PICC-Lite Version 9.60PL1
//  IDE          : Microchip MPLAB IDE v8.00
//  Programmer   : PICKit2
//  Last Updated : 28 Dec 2008
// ***************************************************************************
#include <pic.h>
/*   PIC Configuration Bit:
**   INTIO     - Using Internal RC No Clock
**   WDTDIS    - Wacthdog Timer Disable
**   PWRTEN    - Power Up Timer Enable
**   MCLREN    - Master Clear Enable
**   UNPROTECT - Code Un-Protect
**   UNPROTECT - Data EEPROM Read Un-Protect
**   BORDIS    - Borwn Out Detect Disable
**   IESODIS   - Internal External Switch Over Mode Disable
**   FCMDIS    - Monitor Clock Fail Safe Disable
*/
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLREN & UNPROTECT & UNPROTECT \
  & BORDIS & IESODIS & FCMDIS);
// Using Internal Clock of 8 Mhz
#define FOSC 8000000L
// Delay Function
#define _delay_us(x) { unsigned char us; \
	  	       us = (x)/(12000000/FOSC)|1; \
		       while(--us != 0) continue; }
void _delay_ms(unsigned int ms)
{
  unsigned char i;
  do {
    i = 4;
    do {
      _delay_us(164);
    } while(--i);
  } while(--ms);
}
void main(void)
{
  unsigned char chSign,chEye,iType;
  unsigned int iDelay;
  OSCCON=0x70;         // Select 8 Mhz internal clock
  TRISC = 0x00;        // Set All on PORTC as Output
  TRISA = 0x03;        // Input for RA0 and RA1
  ANSEL = 0b00000001;  // Set PORT AN0 to analog input AN1 to AN7 digital I/O
  ANSELH = 0;          // Set PORT AN8 to AN11 as Digital I/O
  /* Init ADC */
  ADCON0=0b10000000;   // select right justify result. ADC port channel 0
  ADCON1=0b00110000;   // Select the FRC for 8 Mhz
  ADON=1;	       // turn on the A2D conversion module
  chEye=0x01;          // Initial Eye Variables with 0000 0001
  chSign=0;
  iDelay=200;
  iType=0;
  for(;;) {
    GODONE=1;	             // initiate conversion on the channel 0
    while(GODONE) continue;  // Wait conversion done
    iDelay=ADRESL;           // Get the 8 bit LSB result
    iDelay += (ADRESH << 8); // Get the 2 bit MSB result
    // Display the LED
    if (RA1 == 0) {          // Read the Switch attached to RA1
      iType=~iType;
      chSign=0;
    }
    if (iType == 0 ) {
      if (chSign == 0) {
	PORTC=chEye;
	_delay_ms(iDelay);         // Call Delay function
	chEye=chEye << 1;
  	if (chEye > 0x04) chSign=1;
      } else {
        PORTC=chEye;
        _delay_ms(iDelay);         // Call Delay function
        chEye=chEye >> 1;
	if (chEye <= 0x01) chSign=0;
      }
    } else {
       PORTC=0x0F;
       _delay_ms(iDelay);          // Call Delay function
       PORTC=0x00;
       _delay_ms(iDelay);          // Call Delay function
    }
  }
}
/* EOF: adc.c */

Board PIC Analog to Digital Converter C Programming

The C Code

This program basically works by displaying the running LED attached to RC0, RC1, RC2 and RC3 ports on the PIC16F690 microcontroller; the speed of the running LED is controlled by the voltage value reads from the user’s trimport on the port RA0. This voltage value will be converted by the PIC ADC peripheral and passing the converted numeric value as the delay argument on the _delay_ms() function inside the loop.

The user’s trimport basically work as the voltage divider circuit and provide voltage input level to the microcontroller analog port (AN0); therefore by changing the trimmer means we change the voltage level input and this also will change the running LEDs speed.

The user’s switch is works as a toggle switch, by pressing this switch once the running LEDs will be switched to the blinking LEDs; pressing once again will switch back to the running LEDs.

For the ADC peripheral programming on the Microchip PIC16F690 microcontroller we will focus on these 2 important registers, is that all… yes you are right; again only 2 registers (if you curious of how this ADC setup being done in AVR microcontroller family, you can take a look at the similar project Analog to Digital Converter AVR C Programming posted in this blog):

For more detail: PIC Analog to Digital Converter C Programming




Leave a Comment

*
= 4 + 3

Read previous post:
Shift left – shift right value For CSS Compiler

#include <16F877.h> #device adc=8 #FUSES NOWDT ,XT #use delay(clock=4000000) int8 x,k; void main() { setup_adc_ports(NO_ANALOGS); setup_adc(ADC_OFF); setup_psp(PSP_DISABLED); setup_spi(SPI_SS_DISABLED); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED);...

Close
Scroll to top