In PIC16F877 has 8 channels are available for adc input ie AN0 to AN7.Any one can be use ,we can select the the channel by selecting channel selection bit.
The Whole project Can be download at the Bottom of the post .
In ADC the Vref voltage is important in accuracy of the ADC conversion.Low Vref gets more accuracy . But This PIC has a 10 bit result ion so it is enough As follows some example
If Vref = 4.096 volt
Bit resolution = 8 ie 2^8 =256
then 4.096/256 = 16Millvolt Per Bit
3.88/256 = 15mv/bit
2.56/256 = 10mv/bit
giving vcc as vref (5Volt) in 10 bit Resolution
Vref =5 v
Bit resolution = 10 bit ,ie 2^10 = 1024
so
5/1024 = 4.8828 millivolt /Bit
Here taking 5 volt as vref
For getting ADC value the following steps are needed
* Initialization of ADC
* Reading ADC value
Initialization of ADC
Initialization of ADC mean that
Configure the ADC PORT for that PIC has 4 registers they are
* ADCON 0
* ADCON 1
* ADRESH
*ADRESL
ADCON0 :- it is an 8 bit register it decide how the ADC worrks in accordance with the following bit have to set .
Lasr(msb bit) two bit decide the clock of the ADC ie the conversion speed.if we select the the main PIC crystal frequency as 20MHz
then I will select the First tw register value is 10
ie 10 = Fosc/32
after calculating the clock speed there must be a time 1.6 micro second for one bit conversion these time is called TAD . So to convert 10 bit need 10x1.6 microsecond .,Look Data sheet page No .133 Section 11-2.
I am selecting the ADC clock selection bit is 10
ADCS1 = 1
ADCS0 = 0
ie fosc/32 Look Datasheet Page No. 130 section 11.2
Calculation
20Mhz/32 = 625000Hz ie 1.6Microsecond
For one TAD is 1.6 is correct .(Look Data sheet page No .133 Section 11-2)
Then ,
The the 3rd,4the and 5th bit is the analog channel selection Bit from the Port AN0 to AN7.
The second bit(GO/DONE) is used to Start the conversion of analog value to digital when its value is one .And automatically reset (become zero) whenever the completion take place
GO/DONE: A/D Conversion Status bit
When ADON = 1:
1 = A/D conversion in progress (setting this bit starts the A/D conversion which is automatically
cleared by hardware when the A/D conversion is complete)
0 = A/D conversion not in progress
The Second Bit is not used Leave it as Zero
The First Bit is the Bit to Turn On the ADC .(powering on the ADC).
So the ADCON0 value is 10000001 in Hex a 0x81;
ADCON1 :-
The Bit From Bit 0 to Bit 3 are used decide to How act the Analog PIN . How the Vref and GND voltage are given. I am selecting the first one
0000 becuase the 8 bit of AN is selected as Analog (denoted above as "A")
And the Vref is taken as VDD ie 5volt (VCC)
* channel selected
So the ADCON1 value is 10000000 in hex format = 0x80;
The Last Bit of ADCON1 is ADFM is used to alignment the result of adc (ie the value )
If its value is One The 10 bit adc value is right alimented
If its value is zero The 10 bit is left aligned
ADRESH :- is the Register (8bit) the result of ADC saved here . Our result is 10 bit if we use 10 bit resolution. But the ADRESH register is 8 bit So the 8 bit of the 10 bit adc result is saved in ADRESH the balance 2 bit is saved in ADRESL .
The Whole project Can be download at the Bottom of the post .
In ADC the Vref voltage is important in accuracy of the ADC conversion.Low Vref gets more accuracy . But This PIC has a 10 bit result ion so it is enough As follows some example
If Vref = 4.096 volt
Bit resolution = 8 ie 2^8 =256
then 4.096/256 = 16Millvolt Per Bit
3.88/256 = 15mv/bit
2.56/256 = 10mv/bit
giving vcc as vref (5Volt) in 10 bit Resolution
Vref =5 v
Bit resolution = 10 bit ,ie 2^10 = 1024
so
5/1024 = 4.8828 millivolt /Bit
Here taking 5 volt as vref
For getting ADC value the following steps are needed
* Initialization of ADC
* Reading ADC value
Initialization of ADC
Initialization of ADC mean that
Configure the ADC PORT for that PIC has 4 registers they are
* ADCON 0
* ADCON 1
* ADRESH
*ADRESL
ADCON0 :- it is an 8 bit register it decide how the ADC worrks in accordance with the following bit have to set .
Lasr(msb bit) two bit decide the clock of the ADC ie the conversion speed.if we select the the main PIC crystal frequency as 20MHz
then I will select the First tw register value is 10
ie 10 = Fosc/32
after calculating the clock speed there must be a time 1.6 micro second for one bit conversion these time is called TAD . So to convert 10 bit need 10x1.6 microsecond .,Look Data sheet page No .133 Section 11-2.
I am selecting the ADC clock selection bit is 10
ADCS1 = 1
ADCS0 = 0
ie fosc/32 Look Datasheet Page No. 130 section 11.2
Calculation
20Mhz/32 = 625000Hz ie 1.6Microsecond
For one TAD is 1.6 is correct .(Look Data sheet page No .133 Section 11-2)
Then ,
The the 3rd,4the and 5th bit is the analog channel selection Bit from the Port AN0 to AN7.
The second bit(GO/DONE) is used to Start the conversion of analog value to digital when its value is one .And automatically reset (become zero) whenever the completion take place
GO/DONE: A/D Conversion Status bit
When ADON = 1:
1 = A/D conversion in progress (setting this bit starts the A/D conversion which is automatically
cleared by hardware when the A/D conversion is complete)
0 = A/D conversion not in progress
The Second Bit is not used Leave it as Zero
The First Bit is the Bit to Turn On the ADC .(powering on the ADC).
So the ADCON0 value is 10000001 in Hex a 0x81;
ADCON1 :-
The Bit From Bit 0 to Bit 3 are used decide to How act the Analog PIN . How the Vref and GND voltage are given. I am selecting the first one
0000 becuase the 8 bit of AN is selected as Analog (denoted above as "A")
And the Vref is taken as VDD ie 5volt (VCC)
* channel selected
So the ADCON1 value is 10000000 in hex format = 0x80;
The Last Bit of ADCON1 is ADFM is used to alignment the result of adc (ie the value )
If its value is One The 10 bit adc value is right alimented
If its value is zero The 10 bit is left aligned
ADRESH :- is the Register (8bit) the result of ADC saved here . Our result is 10 bit if we use 10 bit resolution. But the ADRESH register is 8 bit So the 8 bit of the 10 bit adc result is saved in ADRESH the balance 2 bit is saved in ADRESL .
Circuit diagram
Main Programm
/* * File: adc_main.c * Author: gElectron/Gireesh * * Created on September 27, 2015, 6:24 AM */ // PIC16F877 Configuration Bit Settings // 'C' source line config statements #includeADC file#include"lcd.h" #include"adc.h" #include #define _XTAL_FREQ 20000000 // 20Mh // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. // CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config CP = OFF // FLASH Program Memory Code Protection bits (Code protection off) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low Voltage In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EE Memory Code Protection (Code Protection off) #pragma config WRT = OFF // FLASH Program Memory Write Enable (Unprotected program memory may not be written to by EECON control) void main() { TRISB = 0X00; // output for the 8 bit TRISA =0XFF; int adc_value=0x00,ch_sec = 0; unsigned char digits[5]; lcd_init(); // lcd initialization adc_init(); // adc initialization adc_value = read_adc(ch_sec); // reading adc value string("gElectron "); LINE2; digits[0] = adc_value / 1000 + 48; digits[1] = (adc_value / 100) % 10 + 48; digits[2] = (adc_value / 10) % 10 + 48; digits[3] = adc_value % 10 + 48; digits[4] = '\0'; string(digits); while(1); // endless loop }
/* * File: adc.c * Author: Krishna * * Created on September 27, 2015, 7:14 AM */ #include#include"adc.h" //#define _XTAL_FREQ 20000000 void adc_init() { ADCON0 = 0x81;// 10000001 TAD is fosci/32 and last bit is adc poweron ADCON1 = 0x80; //all port selected as output ,vref= vcc, TRISA = 0x2f; //ENANLING AS ANALOG INPUT TRISE = 0X07; // ENANLING AS ANALOG INPUT } unsigned int read_adc(unsigned char ch_selection) { if(ch_selection>7) // checking is channel greater than 7 return 0; // yes return zero __delay_us(50); //adc acquisition time as 19.72 ?s as datasheet GO_nDONE = 1; while(GO_nDONE); // after conversion GO_nDONE value become 0 autmatically. return((ADRESH<<8)+ADRESL); }