#### corefinder

Joined Oct 6, 2011
55
Hi, I have made a program in which I ma using inbuilt ADC module of Pic 16F887. It is a simple program in which AN0 of port a is selected as analog input. I gave a variable supply to analog pin and compared it with 3 volt. If the variable voltage is greater than 3 volt then led should blink..but it didn't. I compiled the program using MicroPro C and it did not give any error but led is not blinking. I wonder that my program has some error...and here I need your help to understand what is going wrong in program.

Here is a program
Rich (BB code):
# include<built_in.h>
void delay();
sbit led at PORTA.B1;
void main() {
int value;
TRISA=0x01;
ANSEL=0X01;
do
{
delay();
delay();
delay();
if(value>3)
led=1;
else
led=0;
}
while(1);
}
void delay()
{
int i,j;
for(i=0;i<255;i++)
{
for(j=0;j<255;j++);
}
}

#### JohnInTX

Joined Jun 26, 2012
3,809
Rich (BB code):
value= ADRESH*256+ADRESL;
if(value>3)
led=1;
else
led=0;
The ADC does not return volts. It returns a count value that is proportional to (Vin / Vref) * the full range count.. For example if Vref = 5.0V and 3 volts is applied the count will be 3.0 / 5.0 = .6*the full range count.

What the full range count is depends on the number of bits in the ADC, how its scaled AND how the result is justified in ADRESH/L. Your PIC has a 10 bit ADC so its raw count will be 0-1023. In the example the raw count is (3.0/5.0)*1024 = 614, not 3.

Rich (BB code):
value= ADRESH*256+ADRESL;
From the datasheet, note that the 10 bit result can be justified left or right in ADRESH/L. If right justified, the raw result is 0-1023. Left justifying shifts the result to the left 6 bits (which is the same as multiplying by 64) so the raw result is 0-65472, going up 64 for each raw ADC count. Your scaling arithmetic is therefore incorrect for a 10 bit value (its OK for a right justified 8 bit value).

The value register must be an UNSIGNED int for left justified results (or any scaled value >32767).

In any case, you'll have to know how the ADC is configured by ADC_Init() i.e. what Vref is, justification etc, to know what to do.

Finally, your code will not blink the LED above a particular value, it will turn it ON when above and OFF when below.

Last edited:

#### donpetru

Joined Nov 14, 2008
185
I wrote the code below for Atmega 8. It can easily adapt to a PIC microcontroller using mikroC for PIC.
Rich (BB code):
/******* Atmega 8 software ****** F_CPU = 8MHz ******/

float VREF = 5.00;

void main() {
DDC0_bit = 0;                    // Setup PORTC pin 0 as intput ADC

DDB4_bit = 1;                    // Setup PORTB pin 4 as output for led blinking

// Main loop
do  {

// Measures and calculates voltage channel ADC0

// Test - if voltage read is greater 3 V then led bliking
{
do {
DDB4_bit = 0;
Delay_ms(1000);
DDB4_bit = 1;
Delay_ms(1000);

}

} while(1);
}

Last edited:

#### RRITESH KAKKAR

Joined Jun 29, 2010
2,823
At the place of ADRESH use if else....

Rich (BB code):
#include <htc.h>
__CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
#define _XTAL_FREQ 20000000

main(){
TRISB=0X00;
TRISA = 0xff ;
PEIE=1;
while(1){

//GIE=1;

__delay_us(10);
GO_DONE=1;
__delay_us(10);

}
}