16F873A ADC appears wrong.

Status
Not open for further replies.

5uco

Member
Hi Folks

Just why does my ADC not work properly ??

As far as I can tell, just putting the ADC result into a FR and looking at the result I should see 1023 dec. when I put 5V into the ADC pin.

What I get is 0907 dec. A DMM on the pin says 4.98V.

With a 1k pot. I have to wind the input to some 560mV before the wretched ADC says 0001.

The 5V is 4.98V, so don't think that is significant.

Compiler is MikroC 5.30.

What have I done wrong this time ??

I have, in the past using ASM, had ADC's working OK.

If I put any number as 'voltage' the LCD unscrambles it OK, so I think the code where I get the chars out works fine .

Code att.

Dave


Code:
// 16F873A
// 20MHz





#define ON 1;
#define OFF 0;
//

 sbit LCD_D4 at RC0_bit;
 sbit LCD_D5 at RC1_bit;
 sbit LCD_D6 at RC2_bit;
 sbit LCD_D7 at RC3_bit;
 sbit LCD_EN at RC4_bit;
 sbit LCD_RS at RC5_bit;
 sbit LCD_D4_Direction at TRISC0_bit;
 sbit LCD_D5_Direction at TRISC1_bit;
 sbit LCD_D6_Direction at TRISC2_bit;
 sbit LCD_D7_Direction at TRISC3_bit;
 sbit LCD_EN_Direction at TRISC4_bit;
 sbit LCD_RS_Direction at TRISC5_bit;
 //
 unsigned int voltage;
 unsigned int tens;
 unsigned int ones;
 unsigned int tenths;
 unsigned int hundths;
 unsigned char ch;
 unsigned int temp1;
 unsigned int temp2;



void check ()
{
CCP1CON = 0x00;
CCP2CON = 0x00;
ADCON0 = 0x80;
ADCON1 = 0xCE;
ADON_bit = ON;
GO_DONE_bit = ON;
do
{
}
while (GO_DONE_bit == 1);
voltage = ADRESH;
voltage = voltage << 8;
voltage = voltage + ADRESL;
tens = voltage / 1000;
temp1 = voltage % 1000;
ones = temp1 /100;
temp2 = temp1 % 100;
tenths = temp2 / 10;
hundths = temp2 % 10;
ch = tens + 48;
Lcd_Chr(2,1,ch);
ch = ones + 48;
Lcd_Chr_CP(ch);
ch = tenths + 48;
Lcd_Chr_CP(ch);
ch = hundths + 48;

Lcd_Chr_CP(ch);
delay_ms(100);
temp1 = 0;
temp2 = 0;
}








void main ()
{
TRISA = 0xFF;
Lcd_Init ();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);

do
{

check ();

}
while (1);
}
 
Last edited:
What your getting is about right. Why because your dividing your adc reading by a 1000.

If you scaled it like adc_read x 500 /1024 you'll get a reading from 0 to 5 volts
 
You need a delay between turning the ADC on and setting the GO bit. Look up acquisition time in the data sheet.

Mike.
 
Mike am I going crazy here or what but if op divides by 1023 ten bits that the adc can do by 1000 he gets 1.023. The op declare " unsigned int voltage" which can't hold 1.023 you'll get a 1 which is then scaled up to 1000. That would give reading like he is posting

I didn't think about the delay. Because he was using MikroC . But it needs one the way the Op is doing it.

Any way if he wants to use a unsigned int he needs to scale it to keep it from have a decimal point in it. Or just use the ADC value as is.That will
give a reading of 0 to 1023

Some thing like this would work better
Code:
char *temp = "0000";
unsigned int ADC_Value;
do {
   adc_Value = ADC_Read();
   temp[0] = adc_Value/1000 + 48; // 48 to get asc2  value
   temp[1] = (adc_Value/100)%10 + 48;
   temp[2] = (adc_Value/10)%10 + 48;
   temp[3] = adc_Value%10 + 48;
   Lcd_Out(1,1,temp);
   Delay_ms(1000);
  } while(1);

Make ADC read a function or just use the built in function
 
Last edited:
Burt and Mike ..

Many thanks for the replies.

Inserting a 1ms delay between ADON and GO_DONE fixes it ...

I'm not sure why as the Data Sheet only seems to require ADON being set before GO_DONE.

??

Somewhere I have the Microchip AN for using an ADC .. maybe I should look it up ..

Dave

EDIT Oooops, found it in the Data Sheet ...
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…