Infinite loop inside a loop

Status
Not open for further replies.

stuckkk

Newbie level 6
Joined
Dec 18, 2012
Messages
13
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,383
Hi,

I have a if-else with five options and if any of the options is selected it lights one LED and make another LED blink infinitely. After that, how can I make the program to loop back to the if-else with five options while the LED is blinking infinitely
 

Here is the code..

Code:
			input=PORTA;				//read PORTA again
			switch(input)
			{
				case 0x01:
				function ();
				function_1 ();
				PORTB= PORTB | 0x01;
				break;
				
				case 0x02:
				function ();
				function_1 ();
				PORTB= PORTB | 0x02;
				break;
				
				case 0x04:
				function ();
				function_1 ();
				PORTB= PORTB | 0x04;
				break;
				
				case 0x08:
				function ();
				function_1 ();
				PORTB= PORTB | 0x08;
				break;
			
				case 0x10:
				function ();
				function_1 ();
				PORTB= PORTB | 0x10;
				break;

void function_1 ()
{
	while(1)
	{
		delay(1000);		
		PORTB = PORTB | 0x40;
		delay(1000);
		PORTB = PORTB & 0xBF;
	}
        }	
			}

I am using MPLAB and PIC simulator to simulate. Model is PIC 16F628.

After any case is selected I want the LED in function_1 to blink infinitely. And the program to loop back to the switch(input) part. How can I do this while the LED is blinking infinitely. Is there another method I can use for this?
 

Remove the while() loop in function_1(). Then when case is 0x01 function_1() will be executed and then due to break; the execution comes out of switch case but the value of input will be still 0x01 so it will get executed again. So, function_1() executes infinitely.
 

I think this should work

Code:
unsigned char flag1 = 0;

void function_1()
{
    static unsigned int counter = 0;

    if((flag1 == 1) && (counter++ == 1000)) // execute every 1000 calls and when flag is 1
    {
        PORTB ^= 0x40;   // invert pin state
        counter = 0;     // clear counter
    }
    else
    {
        delay(1);         // 1ms delay
    }
}


void main(void)
{
 unsigned char input=0;

    while(1)
    {
        input = PORTA;				//read PORTA again

        switch(input)
        {
            case 0x01:
                function();
                flag1=1;    //function_1();
                PORTB = PORTB | 0x01;
                break;

            case 0x02:
                function();
                flag1=1;    //function_1();
                PORTB = PORTB | 0x02;
                break;

            case 0x04:
                function();
                flag1=1;    //function_1();
                PORTB = PORTB | 0x04;
                break;

            case 0x08:
                function();
                flag1=1;    //function_1();
                PORTB = PORTB | 0x08;
                break;

            case 0x10:
                function();
                flag1=1;    //function_1();
                PORTB = PORTB | 0x10;
                break;
        }

        function_1();
    }
}
 
Thanks.. I have changed the code as below
Code:
void function_1()
{
    if(flag == 1)
    {
        PORTB = PORTB | 0x40; 
        __delay_ms (20);
    	PORTB = PORTB & 0xBF;
        __delay_ms (20);
	}
}

Is the function continuously being run or is it being called during the while(1) loop in the main function, and runs during the while(1) loop each time?

I have one more q, when I select one case and it loops back to the switch case, I have to deselect the selected case before selecting the next case. I have tried using 'input =0'. When I run the PIC simulator and deselect the selected case and select another case the program works fine. Is there a way I can erase the last selected case from input.
 

The function is called one time in each loop.

Your code is fine but for 40ms while the two delays execute your mcu will be frozen, no key detection works during that time and although this may not be a big issue with the small delay you use it will become a problem with higher delays.

In my version I had a counter variable so the delay was executed in 1ms segments , so the inputs were rechecked every 1ms.
In your code the input will be rechecked every 40ms , if you use two 1000ms delays like in the first code then the input will be checked every two seconds.


It depends what you want to do, if you place the code after the case then it will be cleared immediately after each evaluation.
 
IF you clear the value of input then function_1() will not execute infinitely. Why do you want to clear input variable. If input is 0x01 case (0x01) will be executed infinitely and when input changes to some other value the other case gets automatically executed and case(0x01) will stop executing.

You can also use alexan_e's code. As you are calling function_1() in all the cases you can use it as alexan_e has mentioned.
 
I think function_1 will be executed infintely if I use alexan_e's code as it is called after the switch case.

I want to clear input variable because if one case is selected and I want to go to another case, I need to deselect the previously selected case for the second case to execute. Now the inputs act as pushbutton switches.

If I had selected case0x04 and I want to go to case0x02, I have to change case0x02 to 0x06. Is there a way I can use this same cases and the program be able to go to another case even if one case is already active
 

You can change case by changing value of input. I think you are changing the value of input with push buttons. right? When One case is executing and you want to change the case you just have to change the value of input. You don't need to clear input to change the case. If you change input value case changes according to it. The previous case will not be executed.
 


In the previous post you asked how to blink a led indefinitely as soon as the first selection was made, that is what my code does, that doesn't stop you from making another selection since the input is constantly scanned and the led keeps blinking.
The input will just reflect the last input, if that changes then it will lead to a different switch option.
 

The program works with push buttons only. I want to make it work with toggle switches.

When I simulate using PIC simulator IDE, I need to switch off previously selected case for another case to be executed.
 

But a toggle switch will keep giving a value to the input which will complicate things, how can this be ignorred?

So it is like having four push buttons, when you push the first the input detects that the first button sas been pushed, then without leaving that you also press the second button and then also a third button now what is the code supposed to do?

Unless this is the wantede behaviour, each button/switch to control one bit of the port.
In that case replace the switch.case with ifs

Code:
input = PORTA;	//read PORTA again


if(input & 0x01)
{
    function();
    function_1();
    PORTB = PORTB | 0x01;
}

if(input & 0x02)
{
    function();
    function_1();
    PORTB = PORTB | 0x02;
}

if(input & 0x04)
{
    function();
    function_1();
    PORTB = PORTB | 0x04;
}

if(input & 0x08)
{
    function();
    function_1();
    PORTB = PORTB | 0x08;
}

if(input & 0x10)
{
    function();
    function_1();
    PORTB = PORTB | 0x10;
}

- - - Updated - - -

but remove function_1(); from there and use the flag in its place

- - - Updated - - -

like this
Code:
unsigned char flag1 = 0;

void function_1()
{
    static unsigned int counter = 0;

    if((flag1 == 1) && (counter++ == 1000)) // execute every 1000 calls and when flag is 1
    {
        PORTB ^= 0x40;   // invert pin state
        counter = 0;     // clear counter
    }
    else
    {
        delay(1);         // 1ms delay
    }
}


void main(void)
{
    unsigned char input = 0;

    while(1)
    {
        input = PORTA;				//read PORTA again

        if(input & 0x01)
        {
            function();
            flag1 = 1;  //function_1();
            PORTB = PORTB | 0x01;
        }

        if(input & 0x02)
        {
            function();
            flag1 = 1;  //function_1();
            PORTB = PORTB | 0x02;
        }

        if(input & 0x04)
        {
            function();
            fflag1 = 1;  //function_1();
            PORTB = PORTB | 0x04;
        }

        if(input & 0x08)
        {
            function();
            flag1 = 1;  //function_1();
            PORTB = PORTB | 0x08;
        }

        if(input & 0x10)
        {
            function();
            flag1 = 1;  //function_1();
            PORTB = PORTB | 0x10;
        }

        function_1();
    }
}

- - - Updated - - -

Note that I have no idea about function(); and how it can effect the execution
 
Last edited:

He wants function_1() to be executed only when toggle switches are ON. The function_1() in the while91) loop will execute all the time whether switch is pressed or not and hence led will blink all the time.
 

This is what he said
I have a if-else with five options and if any of the options is selected it lights one LED and make another LED blink infinitely

If I misunderstood and he wants to blink the led only while the switches are active then there is only one more line needed at the end

Code:
unsigned char flag1 = 0;

void function_1()
{
    static unsigned int counter = 0;

    if((flag1 == 1) && (counter++ == 1000)) // execute every 1000 calls and when flag is 1
    {
        PORTB ^= 0x40;   // invert pin state
        counter = 0;     // clear counter
    }
    else
    {
        delay(1);         // 1ms delay
    }
}


void main(void)
{
    unsigned char input = 0;

    while(1)
    {
        input = PORTA;				//read PORTA again

        if(input & 0x01)
        {
            function();
            flag1 = 1;  //function_1();
            PORTB = PORTB | 0x01;
        }

        if(input & 0x02)
        {
            function();
            flag1 = 1;  //function_1();
            PORTB = PORTB | 0x02;
        }

        if(input & 0x04)
        {
            function();
            fflag1 = 1;  //function_1();
            PORTB = PORTB | 0x04;
        }

        if(input & 0x08)
        {
            function();
            flag1 = 1;  //function_1();
            PORTB = PORTB | 0x08;
        }

        if(input & 0x10)
        {
            function();
            flag1 = 1;  //function_1();
            PORTB = PORTB | 0x10;
        }

        function_1();
        [COLOR="#FF0000"]flag1 = 0;[/COLOR] // clear flag after each scan.
    }
}
 

Are you saying that if toggle switch 1 is ON and case 1 is running then if you toggle ON switch 2 case 1 should stop and case 2 should run?

If toggle switch 1 is ON and case 1 is running and if I ON toggle switch 2, the LED in case 1 should stay ON but now have to go to case 2 and ON case 2 LED.

Will toggle switches make the program very complicated?
 

A switch can only select one of the options or if you remove the break it will executed any statement below the case which it true until the end or until a break.
That doesn't seem to be what you want.

In my previous code I would also change the function to the following so that it clears the counter and turns off the led when flag is off
Code:
void function_1()
{
    static unsigned int counter = 0;

    if(flag1 == 1)
    {
        if(counter++ == 1000) // execute every 1000 calls and when flag is 1
        {
            PORTB ^= 0x40;   // invert pin state
            counter = 0;     // clear counter
        }
        else
        {
            delay(1);         // 1ms delay
        }
    }
    else
    {
        counter = 0;  // clear caounter
        PORTB = PORTB & 0xBF; // turn off led
    }
}
 

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