Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Modalities Of Using The ADC Module Of PIC 16F877A - Part 6

  • Author Tahmid
  • Create date
  • Updated
  • Blog entry read time 6 min read

All this while, we’ve talked about the software side of things when dealing with the ADC. Now, it’s time to talk about the hardware side of things.

We’ve considered many situations in the discussions above. But not all of them can be used in your circuits.

One such situation was the use of VREF+ = 3.5V and VREF- = 2.0V. This cannot be used in your circuits. Microchip specifies that the minimum reference voltage must be 2.0V. That means the difference between VREF+ and VREF- has to be at least 2.0V. So, if VREF+ = 3.5V, VREF- must be 1.5V or lower. If VREF- = 2.0V, VREF+ must be 4.0V or higher.

VREF+ also has minimum and maximum voltage ratings. The minimum value for VREF+ is VDD-2.5V. So, if your PIC is powered off VDD=5V, the minimum allowable value for VREF+ is 2.5V. You can not use anything lower than 2.5V for VREF+. The maximum value for VREF+ is VDD+0.3V. So, if your PIC is powered off VDD=5V, the maximum allowable value for VREF+ is 5.3V. So, for VDD=5V, VREF+ must lie between 2.5V and 5.3V.

The minimum value for VREF- is VSS-0.3V. So, as VSS = 0V, minimum value for VREF is -0.3V. But it’s better not to use a negative voltage and to just stick with 0V. The maximum voltage for VREF- is VREF+ minus 2V. This is because, as I’ve mentioned above, VREF+ minus VREF- must be at least 2.0V.

The minimum required acquisition time of 19.72µs mentioned in this article is for an input impedance of 2.5kΩ. For anything lower, minimum required acquisition time is less than 19.72µs. But you can just take it as 19.72µs. For input impedance greater than 2.5kΩ, the acquisition time is higher. Do you remember, I mentioned that Microchip recommends a maximum input impedance of 2.5kΩ? That’s what Microchip recommends. Microchip also specifies that the maximum allowable input impedance is 10kΩ, although it is not recommended. So, it’s better to stick to Microchip’s recommendation and use a voltage follower (analogue buffer) with an operational amplifier, if needed.

__________________________________________________ __________________________________________________ ________________


While using the ADC, you may sometimes notice that the result fluctuates over a small range. I’ve seen many people panicking over this and assuming it’s a problem in the code. Usually, the problem lies in the hardware. The first thing to do when designing a circuit utilizing the internal ADC module of the PIC16F877A, or for that matter, any PIC, is to ensure that the reference voltage is stable. Make sure that the PIC VDD and VSS lines are properly decoupled even if they’re not the reference. If you’re using external reference via AN2 and AN3, make sure that these are properly decoupled. If you’re using both for VREF+ and VREF-, make sure you place a 0.1µF ceramic capacitor across AN2 and AN3. Also, use a 10µF electrolytic capacitor (take care with the polarity!).

Another thing that should be done when using the PIC ADC module is to use filters at the inputs. The filters may be simple RC filters.

The values of R and C are not overly critical. For most cases, a 1kΩ resistor and a 0.1µF capacitor may be used. If you’re sampling an input with a high frequency, you should use a smaller capacitor. Use of the filter should make the ADC results more stable and is likely to be beneficial in most cases.

Another thing you should do in most cases is to protect the analogue input channel from over-voltage. The maximum voltage that may be applied to the pin without damaging the internal circuitry is about +5.5V. However, you can only read/convert/measure voltages as high as VREF+ using the ADC. In many cases, VDD will be used as VREF+ and VSS as VREF-. So, the maximum voltage that can be read is VDD. If VDD is 5.0V, the maximum voltage that can be read is 5.0V. So, you should make sure that the voltage at the analogue input pin is never higher than 5.0V. You can do this using a simple zener diode.

Something like this can be used for filtering and protecting the PIC ADC input pin from overvoltage:


Sometimes you may need to read voltages higher than 5.0V, such as 10V or even 100V. In such situations, you cannot read the input directly as it will damage the internal circuitry. In such a case, you can make use of the simple voltage divider employing resistors.

So, to summarize all the hardware-related concepts presented above, let’s consider the following example.


To sample a DC input voltage ranging from 0V to 25V, what is the hardware interface required for the ADC input?

Firstly, we’ll need a voltage divider. Then, to improve the impedance, we’ll use a voltage follower (analogue buffer). Finally, we’ll use a filter and overvoltage protection circuitry.


We can use this circuit.

In the voltage divider, you must take into account tolerance of the resistors and the errors they can cause in the measurement. Thus it may be better to use a variable resistor or potentiometer instead of R2 and adjust the resistance to obtain an accurate reading of the ADC. The rest is pretty simple: an analogue buffer (voltage follower) employing an LM358; a simple RC filter employing R3 and C1; a 5V (5.1V to be precise) zener for overvoltage protection.

__________________________________________________ __________________________________________________ ________________


A load (motor) is to be run off a variable DC power supply. The microcontroller is to control the circuit in the following way.

The DC voltage varies between 10V and 28V. The microcontroller is powered off a constant 5V. If the DC voltage is less than 15V or if the DC voltage is greater than 25V, the DC motor is to be turned off. If voltage is between 15V and 25V, the motor is to be run.

The motor is connected via a transistor whose base is connected to PORTD0.

We’ll use the circuit shown in page 24 for the ADC interfacing to input voltage.

For 28V input, ADC input = (28/6)V = 4.67V
For 15V input, ADC input = (15/6)V = 2.5V

PCFG setting of 1110 is used. VDD is used as VREF+ and VSS is used as VREF- as high accuracy is not needed and circuit simplicity is the priority here.

ADC result for 4.67V input = (4.67/5)*1023 = 955
ADC result for 2.5V input = (2.5/5)*1023 = 511

unsigned int ADCRead(unsigned char channel){ 
	unsigned char l_byte, h_byte; 
	unsigned int ADR; 
	ADCON0 = 0x81 | (channel << 3); //Change channel 
	delay_us(40); //Acquisition Delay 
	GO_DONE_bit = 1; //Set GO_DONE bit to start conversion 
	while (GO_DONE_bit == 1); //Wait for bit to be cleared 
	//If bit is cleared, this means conversion is over 
	l_byte = ADRESL; 
	h_byte = ADRESH; 
	ADR = (h_byte<<8)|l_byte; 
	return ADR; 

 void main(void){ 
	#define V28 955

	#define V15 511

	unsigned int Ch0; 

	CMCON = 7; //Disable comparator

	PORTD = 0; 
	TRISD = 0; 
	ADCON0 = 0x81; 
	ADCON1 = 0xCE; 
	while (1){ 
		Ch0 = ADCRead(0); //Gets reading from channel 0 
		if  ((Ch0 < V15)|(Ch0>V28)){
			RD0_bit = 0; //Turn off motor
			RD0_bit = 1; //Turn on motor
		delay_ms(100); //Wait for some time

__________________________________________________ __________________________________________________ ________________

Basic Hardware Connection:


__________________________________________________ __________________________________________________ ________________


The ADC module of PIC microcontroller is a very useful feature. Its use is immense in practical applications and hence, one must know its proper application if he or she wants to use that microcontroller in useful circuits. Though it may look very daunting at first, using this module is actually not so difficult if one knows all the modalities of using it properly. Learning these is actually easy if one wants to learn by heart. Here I have tried to cover all the sequential steps and intermediate settings. I hope that the tutorial that I have prepared and presented here will be of some use for those who are interested in learning and applying this module in practical applications.


Tahmid thank a lot! What an explanation u have given! Really wonderful! You have really made it simpler than I ever thought it would be! The language used is also simple and the examples used! Overall awesome! I followed the same procedure and yes I got the right output!
After PIC16f877A I have moved on to PIC18F8722 and there are more registers associated with ADC and I find the ADCON2 register confusing, especially the part where we need to select the Acquisition Time. I will be really grateful to you if you explain me the working of that register just like you did in case of PIC16F877A.

Thanks in advance
You can not use 0.5V as reference. The lowest you can use is 2.0V. I've said this above in the "PRACTICAL CONSIDERATIONS" section:

"One such situation was the use of VREF+ = 3.5V and VREF- = 2.0V. This cannot be used in your circuits. Microchip specifies that the minimum reference voltage must be 2.0V. That means the difference between VREF+ and VREF- has to be at least 2.0V. So, if VREF+ = 3.5V, VREF- must be 1.5V or lower. If VREF- = 2.0V, VREF+ must be 4.0V or higher."

If your input voltage is that low, you should amplify it so that the ADC returns a sufficiently large value.
I clear out lot of small and small problems that I was suffering . Thanks "TAHMID" again and again
Hi Tahmid

for 350v peak AC signal... Is it safe and good to use a voltage divider like u used here?

in proteus it seemed nice BTW. and if u know a good way to measure AC voltage tell me (RMS value).
It's safe to use a voltage divider, provided you set the voltage divider to give a low enough output voltage (safe enough for the PIC to handle) and that you are okay with not having isolation with the high voltage AC.

For the voltage reference ,Can I use a voltage divider from VDD to get an external Vref+ such as getting 4 v form 5 V VDD?
What a topic. It is amazing...................

Waiting for similar post from u...............

Thanks ..................

Part and Inventory Search

Blog entry information

Read time
6 min read
Last update

More entries in Uncategorized

More entries from Tahmid

Share this entry