ADC value to LCD with PIC microcontroller

Status
Not open for further replies.

ravi17

New Member
Hi,

I am trying to send ADC value to LCD with PIC16F877A but only the first digit is displayed(picture attached). Can anybody help? here is the code:

void main(void)
{
sys_init();
lcd_init();

unsigned int adc;
int v;
char a,b,c,d;

while(1)
{
adc = adc_read();
v = ((adc*5)/1023)*100; //eg v=234

a = v%10+48; //4
b = v/10; //23
c = b%10+0x30; //3
d = b/10+0x30; //2

send_string("Volt: ");

send_char(d);
send_char('.');
send_char(c);
send_char(a);
__delay_ms(1000);
send_cmd(0x01); // clear the screen

}

}

the ADC code:

#include "adc.h"

unsigned int adc_read()
{
GO_nDONE = 1;
while(GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}

the LCDd code:

void send_char(char data)
{

RS = 1; //select Data Reg.

PORTD = (PORTD & 0x0F)|(data & 0xF0); //send upper nibble
EN = 1;
__delay_ms(1);
EN = 0;

PORTD = (PORTD & 0x0F)|((data<<4) & 0xF0); //send lower nibble
EN = 1;
__delay_ms(1);
EN = 0;
}
 

Attachments

  • 1.jpg
    92.6 KB · Views: 371
Last edited:
Debug it, add the line v=123; after the line v = ((adc*5)/1023)*100; //eg v=234 and then you'll know where the error is. It could be the ADC reading or the displaying.

Mike.
 
Debug it, add the line v=123; after the line v = ((adc*5)/1023)*100; //eg v=234 and then you'll know where the error is. It could be the ADC reading or the displaying.

Mike.
hi Pommie,

thanks, when v =123 is added the digits are displayed correctly.
i have tried debug but couldn't figure out how to get the variables window in proteus.

so what we know is that v = ((adc*5)/1023)*100; is creating the problem. I tried by changing the data type of v but not working. I think the conversion eqn. is ok.

could you perhaps give more insight??
 
I'm just a braindead Basic programmer but won't this equation be done in integer math?

v = ((adc*5)/1023)*100

Try rearranging it to:

v = ((adc*5*100)/1023)

(adc*5)/1023 will only evaluate to one digit in integer math.
 
The maths needs to be done in a 32 bit variable as ADC*5*100 can be over half a million and a 16 bit integer can only hold 65535 maximum.

Try making v a long and do the maths 1 bit at a time,
Code:
unsigned long v;
    v=(long)adc;
    v*=500L;              //may not need the L at the end
    v/=1024L;
Mike.
Note, see thread on why it should be 1024.

Edit, added cast to long.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…