Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com 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.

PIC16F877A ADC to LED Bar Graph display

Status
Not open for further replies.

salman.

Member level 1
Member level 1
Joined
Jul 30, 2012
Messages
40
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Visit site
Activity points
1,591
I am trying to drive an LED bar graph with the ADC of pic16f877a, I have written and compiled the code in mikroC but it does not simulates as it should on the proteus. I am sharing the code too please help me out.


I am using AN0 channel with Vref+ = Vdd and Vref-=Vss, with Left Justified scheme. I am also sharing the proteus simulation.

here is the code:

unsigned int value;

void main()
{
TRISA=0x01;
TRISB=0x00;
TRISD=0x00;
ADCON0=0x81;
ADCON1=0x0E;


do
{


ADCON0.F2=1;
while(ADCON0.GO!=0);
value=((ADRESL)|(ADRESH<<8));
switch (value)
{
case 102:
PORTB=0b10000000;
break;

case 204:
PORTB=0b11000000;
break;

case 306:
PORTB=0b11100000;
break;

case 307:
PORTB=0b11100000;
break;

case 409:
PORTB=0b11110000;
break;

case 511:
PORTB=0b11111000;
break;

case 512:
PORTB=0b11111000;
break;

case 613:
PORTB=0b11111100;
break;

case 614:
PORTB=0b11111100;
break;

case 716:
PORTB=0b11111110;
break;

case 818:
PORTB=0b11111111;
break;

case 920:
PORTD=0b10000000;
PORTB=0b11111111;
break;

case 921:
PORTD=0b10000000;
PORTB=0b11111111;
break;

case 1023:
PORTD=0b11000000;
PORTB=0b11111111;
break;

default:
PORTD=0b00000000;
PORTB=0b00000000;
}
}while(1);
}
 

Attachments

  • bargraph.rar
    15.5 KB · Views: 124

can you post the .hex and .cof files?

Try this
Code:
unsigned int value;

void main() 
{
	TRISA = 0x01;
	TRISB = 0x00;
	TRISD = 0x00;
	ADCON0 = 0x81;
	ADCON1 = 0x8E;
	CMCON = 0x07;
	CVRCON.CVROE = 0;

	do{

		ADCON0.F2=1;
		while(ADCON0.GO==1);
		ADCON0.GO = 0;
		value=((ADRESL)|(ADRESH<<8));
		switch (value)
		{
			case 102:
			PORTB=0b10000000;
			break;

			case 204:
			PORTB=0b11000000;
			break;
		
			case 306:
			PORTB=0b11100000;
			break;

			case 307:
			PORTB=0b11100000;
			break;

			case 409:
			PORTB=0b11110000;
			break;

			case 511:
			PORTB=0b11111000;
			break;

			case 512:
			PORTB=0b11111000;
			break;

			case 613:
			PORTB=0b11111100;
			break;

			case 614:
			PORTB=0b11111100;
			break;

			case 716:
			PORTB=0b11111110;
			break;

			case 818:
			PORTB=0b11111111;
			break;

			case 920:
			PORTD=0b10000000;
			PORTB=0b11111111;
			break;

			case 921:
			PORTD=0b10000000;
			PORTB=0b11111111;
			break;

			case 1023:
			PORTD=0b11000000;
			PORTB=0b11111111;
			break;

			default:
			PORTD=0b00000000;
			PORTB=0b00000000;
		}
	}while(1);
}
 
Last edited:
See my last post. Use the code I have posted.

For 2.5 volts raw adc value is 511

So ADRESH = 11111111
ADRESL = 10000000

You have choosen Left Justified

So ADRESH + ADRESL = 111111111 = 0x1FF = 511d

But you case 511 your code is
Code:
case 511:
PORTB=0b11111000;
break;

So, PORTB = 11111000 = F8. That is what you are getting.
 
Last edited:

here a code update jayanth.devarayanadurga, I used ADC_Read(0) here.

unsigned temp;

void main() {
TRISA=0x01;
TRISB=0x00;
TRISD=0x00;
ADCON0=0x81;
ADCON1=0x0E;


do
{
delay_us(100);

ADCON0.GO=1;
while(ADCON0.GO==1);
//value=((ADRESL)|(ADRESH<<8));
temp = Adc_Read(0);
switch (temp)
{
case 102:
PORTB=0b10000000;
PORTD=0b00000000;
break;

case 204:
PORTB=0b11000000;
PORTD=0b00000000;
break;

case 306:
PORTB=0b11100000;
PORTD=0b00000000;
break;

case 307:
PORTB=0b11100000;
PORTD=0b00000000;
break;

case 409:
PORTB=0b11110000;
PORTD=0b00000000;
break;

case 511:
PORTB=0b11111000;
PORTD=0b00000000;
break;

case 512:
PORTB=0b11111000;
PORTD=0b00000000;
break;

case 613:
PORTB=0b11111100;
PORTD=0b00000000;
break;

case 614:
PORTB=0b11111100;
PORTD=0b00000000;
break;

case 716:
PORTB=0b11111110;
PORTD=0b00000000;
break;

case 818:
PORTB=0b11111111;
PORTD=0b00000000;
break;

case 920:
PORTD=0b10000000;
PORTB=0b11111111;
break;

case 921:
PORTD=0b10000000;
PORTB=0b11111111;
break;

case 1023:
PORTD=0b11000000;
PORTB=0b11111111;
break;

default:
PORTD=0b00000000;
PORTB=0b00000000;
}

/*If (temp=102)
{PORTB=0b10000000;}
else if (temp = 204)
{PORTB=0b11000000;}
else if (temp = 306)
{PORTB=0b11100000;}
else if (temp = 307)
{PORTB=0b11100000;}
else if (temp = 409)
{PORTB=0b11110000;}
else if (temp = 511)
{PORTB=0b11111000;}
else if (temp =512)
{PORTB=0b11111000;}
else if (temp = 613)
{PORTB=0b11111100;}
else if (temp = 614)
{PORTB=0b11111100;}
else if (temp = 716)
{PORTB=0b11111110;}
else if (temp = 818)
{PORTB=0b11111111;}
else if (temp = 920)
{PORTD=0b10000000;
PORTB=0b11111111;}
else if (temp = 921)
{PORTD=0b10000000;
PORTB=0b11111111;}
else if (temp = 1023)
{PORTD=0b11000000;
PORTB=0b11111111;}*/
}while(1);
}

- - - Updated - - -

Thanks a lot jayanth.devarayanadurga, your code works!!! But could you please explain to me what mistake i was making there?
 

See my last post. What was the problem you were facing? You had not disabled the Comparators on RA0 pin. You had not disabled Comparator Voltage Reference in RA2 pin (CVREF). Your ADCON1 settings were wrong. You had only set PCFG3-PCFG0 bit in ADCON1. You had to set ADFM and ADCS2 bit.

You don't need these lines
Code:
ADCON0.GO=1;
while(ADCON0.GO==1);
//value=((ADRESL)|(ADRESH<<8));

if you are using ADC_Read() function.
 

can you post the .hex and .cof files?

Try this
Code:
unsigned int value;

void main() 
{
	TRISA = 0x01;
	TRISB = 0x00;
	TRISD = 0x00;
	ADCON0 = 0x81;
	ADCON1 = 0x8E;
	CMCON = 0x07;
	CVRCON.CVROE = 0;

	do{

		ADCON0.F2=1;
		while(ADCON0.GO==1);
		ADCON0.GO = 0;
		value=((ADRESL)|(ADRESH<<8));
		switch (value)
		{
			case 102:
			PORTB=0b10000000;
			break;

			case 204:
			PORTB=0b11000000;
			break;
		
			case 306:
			PORTB=0b11100000;
			break;

			case 307:
			PORTB=0b11100000;
			break;

			case 409:
			PORTB=0b11110000;
			break;

			case 511:
			PORTB=0b11111000;
			break;

			case 512:
			PORTB=0b11111000;
			break;

			case 613:
			PORTB=0b11111100;
			break;

			case 614:
			PORTB=0b11111100;
			break;

			case 716:
			PORTB=0b11111110;
			break;

			case 818:
			PORTB=0b11111111;
			break;

			case 920:
			PORTD=0b10000000;
			PORTB=0b11111111;
			break;

			case 921:
			PORTD=0b10000000;
			PORTB=0b11111111;
			break;

			case 1023:
			PORTD=0b11000000;
			PORTB=0b11111111;
			break;

			default:
			PORTD=0b00000000;
			PORTB=0b00000000;
		}
	}while(1);
}

Thanks a lot jayanth.devarayanadurga, your code works!!! But could you please explain to me what mistake i was making there?
 

If I am using left justified, which i actually am using so the ADFM bit in ADCON1 must be set 0 for this scheme(left justified) and hence ADCON1=0x0E;
I have configured PCFG3-PCFG0 i.e PCFG3 = 1, PCFG2=1, PCFG1=1, PCFG0=0.....so how are my ADCON setting wrong?
 

2.5V means 511d or 0x1FF or 111111111

So you are getting right value for 511d but you make PORTB = 11111000 if value = 1111111111
So F8 is the right value for your code.

sorry i did not get it.... I am already using PORTB = 11111000 for 511 in my code

case 511:
PORTB=0b11111000; <------------
PORTD=0b00000000;
break;


Also do explain why you used ADCON0.GO=0, setting it to 0 means "A/D conversion not in progress" and it is cleared(0) automatically when the conversion ends.
 

The value of the variable value is 111111111 or 511d or 0x1FF for 2.5v which is right. You are making PORTB = 11111000 ie.e, 0xF8 if value is 511d. So, you are getting right values.

First you have to make ADCON0.GO = 1 to start a conversion process and then you have to use while(ADCON0.GO == 1) to loop until ADCON.GO is equal to 1. After a2d conversion ADCON0.GO becomes 0 and so comes out of the while loop. I just made ADCON0.GO = 0 for testing purpose. It is not needed.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top