You are on page 1of 6

Microprocessors & Computer Interfacing

Lab 5:

ADC of 16f877A uC

ADC of 16f877A uC.

Objectives:
1. Learn to use the ADC module on the 16f877A uC.

Introduction:
An analog-to-digital converter (A/D) is another important peripheral component of a
microcontroller. The A/D converts an analog input voltage into a digital number so it
can be processed by a microcontroller or any other digital system.
The PIC 16F877A microcontroller contain a 8-channel 10-bit ADC. If the chosen
voltage refrence is +5V, the voltage step (resolution) value is:

Therefore, for example, if the input voltage is 1.0V the converter will generate a
digital output of 1.0/0.00489 = 205 decimal. Similarly, if the input voltage is 3.0V,
the converter will generate 3.0/0.00489 = 613.
The ADC used by the PIC 16F877A microcontroller has eight channels, named AN0AN7, which are shared by the PORTA and PORTE pins.
The ADC module has four registers. These registers are:
ADC Result High Register (ADRESH)
ADC Result Low Register (ADRESL)
ADC Control Register 0 (ADCON0)
ADC Control Register 1 (ADCON1)
In this experiment only the ADC Control Register 1 (ADCON1) is used to control the
channels of the converter.

Microprocessors & Computer Interfacing

ADC of 16f877A uC

ADCON1 Register:
The ADCON1 register configures the functions of the port pins. The port pins can be
configured as analog inputs (RA3 can also be the voltage reference) or as digital I/O.

Bits 0 to 3 i.e. PCFG0-PCFG3 are the ADC port configuration control bits. Figure 6.1
shows all possible settings for these bits.

Figure 6.1

MikroC PRO ADC Library:


MikroC PRO provides an easy to use library functions that simplifies configuring the
ADC module and reading the analogue channels.
Below is a detailed description of the ADC_Read function.

Microprocessors & Computer Interfacing

ADC of 16f877A uC

Prototype : unsigned ADC_Read(unsigned short channel).


Returns
: 10 or 12-bit unsigned value read from the specified
channel.
Example
:
unsigned tmp;

...

tmp = ADC_Read(2);

// Read analog value from channel 2

Example 1:
Connect the circuit shown in Figure 6.2 in Proteus and compile the program of
example 1 given below.

unsigned int adc_value;


void main() {
ADCON1 = 0x00;
TRISA = 0xFF;
TRISC = 0;
TRISB = 0;
do {
adc_value = ADC_Read(0);

//
//
//
//

Set all PORTA and PORTE as analoug.


PORTA is input
PORTC is output
PORTB is output

// Get 10-bit results of AD conversion

Microprocessors & Computer Interfacing


PORTB = adc_value;
PORTC = adc_value >> 8;

ADC of 16f877A uC

// Send lower 8 bits to PORTB


//Send 2 most significant bits to RC1,

RC0
} while(1);
}
Exercise 1:
1. What are the digital values for the following analog DC voltages at AN0:
Analog
Voltage
0.25 V

Digital Value
0000110011

1.49 V

0100110000

2.48 V

0111111010

3.47 V

1011000101

4.94 V

1111110101

Example 2:
Connect the circuit shown in Figure 6.3 in Proteus and compile the program of
example 2 given below.

Microprocessors & Computer Interfacing

ADC of 16f877A uC

Figure 6.3

// LCD module connections


sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections
unsigned long Vin, mV;
unsigned char op1[12],op2[12];
unsigned char i,j, raw[5], analog_val[5];
void main() {
ADCON1 = 0x00;

// Set all PORTA and PORTE as analoug.

Microprocessors & Computer Interfacing

ADC of 16f877A uC

TRISA = 0xFF;
Lcd_Init();
Lcd_Cmd(_LCD_CURSOR_OFF);

// PORTA is input
// Initialize LCD
// Cursor off

while(1)
{
Lcd_Cmd(_LCD_CLEAR);
Vin = Adc_Read(0);
mV = (Vin * 5000) >> 10;
LongToStr(Vin,op1);
LongToStr(mV,op2);

//
//
//
//

Read from channel


mv = Vin x 5000 /
Convert to string
Convert to string

// Remove leading blanks in op1


j=0;
for(i=0;i<=11;i++)
{
if(op1[i] !=' ') // If a blank
{
raw[j]=op1[i];
j++;
}
}
// Remove leading blanks in op2
j=0;
for(i=0;i<=11;i++)
{
if(op2[i] !=' ') // If a blank
{
analog_val[j]=op2[i];
j++;
}
}
//Display the results on LCD
Lcd_Out(1,1,"Raw = ");
Lcd_Out_Cp(raw);
Lcd_Out(2,1,"mV = ");
Lcd_Out_Cp(analog_val);
Delay_ms(1000);
}
}

0 (AN0)
1024
in "op1"
in "op2"

You might also like