You are on page 1of 4

PIC Microcontrollers have 10 BIT ADC's .That means the range is from 0-1023 or 0(2^10 - 1).

If we set the reference voltage at 5 volts then 0 - 5 volts can be represented as 0 - 1023 in the digital format .ie 5 v would represent 1023 2.5 v would represent 512(rounded).That is the microcontroller would understand 2.5 v as 50% of 2.5 . The formula to calculate the digital value is x= (Vin/Vfullscale )(2^n-1) following this formula x=(2.5/5)*1023 =511.5 (512 approx) Then the next question arises about the a2d resolution .To put it simply what is the minimum voltage that the microcontroller would be sensitive .The resolution of 10 bit microcontroller with 5 v as reference is 5/1023 =4.88 mv . The microcontroller would measure a minimum change of 4.8 mv below which it will be insensitive . The general formula for resolution would be V res = V Fullscale /2^n-1 Vfullscake = What you set as reference n= No of bits (10 bit in PIC16F877A) I assume that you might have understood the basics of A2D and move on to the next step. The next tutorial is gonna be about the A2D Registers in PIC16F877A . There are totally four registers for A2d conversion in PIC16f877 and PIC16f877A .They are the following . (NOTE : Almost all the PIC series of IC's have this same register configuration .So knowing this is enough to program all the PIC series IC's )
registers for analogue inputs. Bit 5 Bit 4 Bit 3 Bit 2 A2D Result Register - High Byte A2D Result Register - Low Byte CHS2 CHS1 CHS0 GO/DONE PCFG3 PCFG2

Name ADRESH ADRESL ADCON0 ADCON1

Bit 7

Bit 6

Bit 1

Bit 0

ADCS1 ADFM

ADCS0 -

PCFG1

ADON PCFG0

ADCON0 Configuration Since PIC has 10 bit A2D and its a 8 bit microcontroller it needs an extra register to store the extra 2 bits resulting in the A2D conversion .Thats the job the first two registers ADRESH and ADRESL name itself is self explanatory . ADRESH:Stores the higher 8 bits .

ADRESL:Stores the lower 8 bits . So now we are done with the first two registers . The next register that we are gonna see in PIC16F877A is ADCONO . The first two bits ADCS1 and ADCS0 is required to select the A2D clock .The table for clock selection is given below .If I am using 5 MHZ I will select 01 thats fosc/8 . ADCS1 ADCS0 0 0 1 1 0 1 0 1 A/D Conversion Clock Select bits. Fosc/2 Fosc/8 FOsc/32 Frc (Internal A2D RC Osc.) Max. Clock Freq. 1.25MHz 5MHz 20MHz Typ. 4uS

The next set of bits are channel select .You can select the appropriate channels by selecting the appropriate bits .So now I am using 5 MHZ and selecting RA2 for example , now bit selection will be 01010xxx .The bits that are named as X are still to be selected . The next bit is GO/DONE .Setting this bit high starts A2D conversion and it is automatically cleared when it is complete .So monitoring the status of this bit can tell us about the status of Analog to digital conversion .So we have to set it high to start conversion .So now our bit configuration will be 010101xx . If you look at the first table you will see bit1 is useless .So put a zero there .So now our bit configuration becomes 0101010x . The last bit is ADON .When the bit is set it turns on the A2D when cleared it turns off.So we are setting 1 there .Now it becomes 01010101 .This is the bit configuration to select 5 MHZ clock channel AN2 .The next three bits are useless . CHS2 0 0 0 0 1 1 1 1 CHS1 0 0 1 1 0 0 1 1 CHS0 0 1 0 1 0 1 0 1 Channel Channel0 Channel1 Channel2 Channel3 Channel4 Channel5 Channel6 Channel7 Pin RA0/AN0 RA1/AN1 RA2/AN2 RA3/AN3 RA5/AN4 RE0/AN5 RE1/AN6 RE2/AN7

ADCON1 Configuration

The next channel is ADCON1 . The bit7 ADFM(Analog to digital conversion format ) is used to select the format .Setting this bit high makes it 10 bit converter .And clearing it makes it 8 bit ie the result only appears in ADRESH and ADRESL is ignored . Now we are entering the most complicated part of the register selection .Please look at the following table to select the configuration you need . PCFG3: AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 Vref+ VrefPCFG0 RE2 RE1 RE0 RA5 RA3 RA2 RA1 RA0 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 A A D D D D D D A D D D D D D D A A D D D D D D A D D D D D D D A A D D D D D D A A A A D D D D A A D D D A A A A D D A A A A A D D D D A A A A A A A A D D A A A A A A A A D D A A A A A A A A Vdd RA3 Vdd RA3 Vdd RA3 Vdd Vdd RA3 Vdd RA3 RA3 RA3 RA3 Vdd RA3 Vss Vss Vss Vss Vss Vss Vss Vss RA2 Vss Vss RA2 RA2 RA2 Vss RA2 A Vref+ A Vref+ D Vref+

A Vref+ Vref- A A Vref+

A Vref+ Vref- A A Vref+ Vref- A D Vref+ Vref- A D D D D D Vref+ Vref- D

PIC C programming is just like normal C programming that you do for you computer. The differences being you have to declare the ports set the registers and there is no printf and scanf of course. Here is the small program that I teach you in the video .It simply reads the value from the 2 nd ADC channel and outputs it to the PORTB .And also I've configured the ADC ports as 8 bits and all analog inputs . So look at the table and configure ADCON1 . unsigned short adc_val ; void main () { ADCON1 = 0x00; TRISA = 0xff ; TRISB = 0x00 ;

while (1) { adc_val = adc_read(2) ; portb =adc_val ; } } After setting ADCON1 .The TRIS registers have to be set .The TRIS registers configures the port as either input or output .Just suffix the TRIS register with the PORT name . TRISA is the register for PORTA ,TRISB is the register for PORTB .Here we are going to use PORTA so I've to set the TRISA register as inputs .So how do we do this ? I am going to use hexadecimal to configure the registers and ports .You can also use binary to configure the ports which is good and easy for beginners . So to use hexadecimal you've to add the suffix 0x (0xFF) and to use the binary you've to use the suffix ob (0b11111111) . Looking at my program I've used TRISA = 0xFF which can also be written as TRISA = 0b11111111 in biinary . The next thing is setting the port as input and outputs .Let us take PORTB as example . TRISB = 0x00 ; TRISB = 0b00000000 ; configures the port b as outputs . So I guess you must have learnt how to set a port as input or output by now . TRISX = 0x00 makes the port as inputs and TRISX = 0xff makes the port as inputs . (Substitute the port name in the place of X ) A combination of input and output can also be done . for ex TRISB = 0xF0 TRISB=0x11110000 sets half of the upper ports as input and the other half as outputs . After setting the ports we shall get into the main program . You must have noticed an unsatisfied while loop .Yes there must be at least one unsatisfied loop inside your program ,because your microcontroller doesn't have a operating system there has to be atleast one unsatisfied loop inside the program to make it run continuously. MikroC has lots of inbuilt libraries . For reading the analog inputs adc_read(unsigned int channel number ) is used . Getting back to my program what I do is I get the input from the channel and output it to the PORT B .

You might also like