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.

Glow LED on specified counter values 0-500 in 89c52 uC

Status
Not open for further replies.

imranahmed

Advanced Member level 3
Joined
Dec 4, 2011
Messages
817
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,298
Location
Karachi,Pakistan
Activity points
6,492
Please let me know I have 89c52 and I want to program in this manner that counter counts by external interrupt by push button 0 to 500.
When it reaches 10 glow LED1 and at 15 glow LED2 at 25 glow LED1 again at 30 glow LED2 and so on till 500.

Code:
unsigned int Counter = 0;
void ext0_isr(void) interrupt 0
{. 
Counter++;
 }

main()
{. 
if(Counter == 10)
LED1 = 1;
else if(Counter == 15)
LED2 = 1;
else if(Counter == 25)
LED1 = 1;

and so on till 500
}

In above for 0 to 500 LED1 and LED2 glow alternatively with gap of 10 and 5.

I want to know is there any possibility for shorter code size.
 

It looks as though you light led1 every 15 counts starting at 10.
Likewise led2 lights every 15 counts starting at 15.

This can be done by a simple formula, for each led.
 
Try this.

Code:
unsigned int Counter = 0;

void ext0_isr(void) interrupt 0
{ 
	Counter++;
}

main()
{ 
if(Counter % 10)LED1 = 1;
else 	LED2 = 1;
}

or

main()
{ 
if(Counter % 10)LED1 = 1;
elseif(!(Counter % 10))	LED2 = 1;
}
 
Yes exactly.Please hint

- - - Updated - - -

I will try it, you gave in previous thread great answer this answer also looks good I will try and let you know.
 

Hi,

In the given code I miss how the LEDs are set to "0".

Klaus
 
Hi,

In the given code I miss how the LEDs are set to "0".

Klaus

Code:
unsigned int Counter = 0;
unsigned char flag = 0;
void ext0_isr(void) interrupt 0
{. 
Counter++;
 }

main()
{. 
if(Counter == 10 && flag == 0)
{
LED1 = 1;
delay(1000);
LED1 = 0;
flag = 1;
}
else if(Counter == 15 && flag == 1)
{
LED2 = 1;
delay(1000);
LED2 = 0;
flag = 0;
}
else if(Counter == 25 && flag == 0)
{
LED1 = 1;
delay(1000);
LED1 = 0;
flag = 1;
}
else if(Counter == 30 && flag == 1)
{
LED2 = 1;
delay(1000);
LED2 = 0;
flag  = 0
}
else if(Counter == 40 && flag == 0)
{
LED1 = 1;
delay(1000);
LED1 = 0;
flag = 1;
}

and so on till 500
}

I want to make it shorter by using formula or FOR LOOP or other LOOP, any hint?
 

Hi,

As "counter" is used both in main and isr, it should be declared "volatile".

If "counter" needs multiple access to be processed (i.e. 16 bit variable on a 8 bit microcontroller) you should use "atomic" access.
For hobbyists this often is no problem, but for reliable industrial solutions it's very important to avoid malfunction.

If you want repeated function of LED glow every x events,
* consider to reset (or better: subtract x from) the counter
* or use the modulo operator

Klaus
 
Hi,

As "counter" is used both in main and isr, it should be declared "volatile".

If "counter" needs multiple access to be processed (i.e. 16 bit variable on a 8 bit microcontroller) you should use "atomic" access.
For hobbyists this often is no problem, but for reliable industrial solutions it's very important to avoid malfunction.

If you want repeated function of LED glow every x events,
* consider to reset (or better: subtract x from) the counter
* or use the modulo operator

Klaus



I also used while loop for forever operation.I will try your suggestions and will let you know.

Code:
unsigned int Counter = 0;
unsigned char flag = 0;
void ext0_isr(void) interrupt 0
{ 
Counter++;
 }

main()
{

while(1){
if(Counter == 10 && flag == 0)
{
LED1 = 1;
delay(1000);
LED1 = 0;
flag = 1;
}
else if(Counter == 15 && flag == 1)
{
LED2 = 1;
delay(1000);
LED2 = 0;
flag = 0;
}
else if(Counter == 25 && flag == 0)
{
LED1 = 1;
delay(1000);
LED1 = 0;
flag = 1;
}
else if(Counter == 30 && flag == 1)
{
LED2 = 1;
delay(1000);
LED2 = 0;
flag  = 0
}
else if(Counter == 40 && flag == 0)
{
LED1 = 1;
delay(1000);
LED1 = 0;
flag = 1;
}

and so on till 500
}}
 

Subtract the base values 10 and 15 from the Counter value and if the result modulo 10 and 15 is zero, turn the LED on, otherwise turn it off.

Make sure 'Counter' is declared volatile.

Brian.
 

Try this.

Code:
volatile unsigned int Counter = 0;
volaile unsigned int oldCounter = 0;

void ext0_isr(void) interrupt 0
{ 
	Counter++;
	
	if(oldCounter != Counter) {
		oldCounter = Counter;
		LED1 = 0;
		LED2 = 0;
	}
}

main()
{ 
if(Counter % 10)LED1 = ~LED1;
elseif(!(Counter % 10))	LED2 = ~LED2;
delay(1000);
}
 

Try this.

Code:
volatile unsigned int Counter = 0;
volaile unsigned int oldCounter = 0;

void ext0_isr(void) interrupt 0
{ 
	Counter++;
	
	if(oldCounter != Counter) {
		oldCounter = Counter;
		LED1 = 0;
		LED2 = 0;
	}
}

main()
{ 
if(Counter % 10)LED1 = ~LED1;
elseif(!(Counter % 10))	LED2 = ~LED2;
delay(1000);
}

LED1 should start from 10 and with gap 15 it will lit-up, means 10,25,40,55,70....... till 500.

and

LED2 should start from 15 and with gap 15 it will lit-up, means 15,30,45,60,75........till 500.

- - - Updated - - -

I tried this but LED was glowing at start of Counter means at Counter value 1.

- - - Updated - - -

Subtract the base values 10 and 15 from the Counter value and if the result modulo 10 and 15 is zero, turn the LED on, otherwise turn it off.

Make sure 'Counter' is declared volatile.

Brian.

I tried this, but only at value 10 of counter LED was litting-up but I also want to lit-up to whole sequence 0-500 first start at 10 then 25 then 40 then 55 then 70.....so on 500.
Same as applies for 15 but how to resolve please more hints needed.

Code:
	if((!(10 - Counter) % 10) && flag == 0)
            {						
		LED1 = 1;
                delay(1000);
                LED = 0;
                flag = 1;					
	   }
 

Very simple. Try this.

Code:
volatile unsigned int Counter = 0;
volaile unsigned int oldCounter = 0;

void ext0_isr(void) interrupt 0
{ 
	Counter++;	
}

main()
{ 
if(Counter >= 10) && ((Counter % 15) == 10) { LED2 = 0; LED1 = ~LED1; }
elseif((Counter >= 15) && ((Counter % 10) == 0)){ LED1 = 0; LED2 = ~LED2;}
delay(1000);
}
 

Very simple. Try this.

Code:
volatile unsigned int Counter = 0;
volaile unsigned int oldCounter = 0;

void ext0_isr(void) interrupt 0
{ 
	Counter++;	
}

main()
{ 
if(Counter >= 10) && ((Counter % 15) == 10) { LED2 = 0; LED1 = ~LED1; }
elseif((Counter >= 15) && ((Counter % 10) == 0)){ LED1 = 0; LED2 = ~LED2;}
delay(1000);
}


It is working only Counter value of 10 only after 10 onwards it is not working.
I tried only for if(Counter >= 10) && ((Counter % 15) == 10) this condition for LED1 only.
 

Missing brackets.

Code:
volatile unsigned int Counter = 0;
volaile unsigned int oldCounter = 0;

void ext0_isr(void) interrupt 0
{ 
	Counter++;	
}

main()
{ 
if((Counter >= 10) && ((Counter % 15) == 10)) { LED2 = 0; LED1 = ~LED1; }
elseif((Counter >= 15) && ((Counter % 10) == 0)){ LED1 = 0; LED2 = ~LED2;}
delay(1000);
}
 

from my post #9:

Subtract the increment from the counter then check the modulo for zero.
You did it the other way around! Subtracting Counter from 10 results in a 'negative' rollover of the unsigned int!

if(((Counter - 10) % 10) == 0) LED1 = 1; else LED1 = 0;
if(((Counter - 15) % 15) == 0) LED2 = 1; else LED2 = 0;

Brian.
 

Hi,

(Counter - 10) % 10)
(Counter - 10) % 10) is the same as (Counter % 10)
(Counter - 15) % 15) is the same as (Counter % 15)

Klaus
 

Problem Solved

I used simple formula not huge coding needed but unfortunately no one in thread could provide proper answer, however problem solved.

Code:
volatile unsigned int Counter=0, h=10, v=15;

isr(void) interrupt 0
{
Counter++;
}


main()
{
while(1)
if(Counter == h)         // for LED1
{
LED1=1;
delay(1000);			
LED1=0;
h+=15;  
} 

if(Counter == v)         // for LED2
{
LED2=1;
delay(1000);			
LED2=0;
v+=15;  
} 
}
}               											}
 

I used simple formula not huge coding needed but unfortunately no one in thread could provide proper answer, however problem solved

Problem 'solved' with a bad programming style, consider next time using state machine handling delays with flags instead of closed loop delays. I would not be surprised if you reopen the discussion reporting that with the above working code you are unable to do well other tasks besides this LED blinky itself. By the way, with the code above, you perform the required task as expected only in the first iteration.
 

Problem 'solved' with a bad programming style, consider next time using state machine handling delays with flags instead of closed loop delays. I would not be surprised if you reopen the discussion reporting that with the above working code you are unable to do well other tasks besides this LED blinky itself. By the way, with the code above, you perform the required task as expected only in the first iteration.

Yes you saying alright but please let me know how to do in best way.How to use state machine handling delays with flags?

Please let me know.


Are you taking about only delays (bad programming style)?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top