Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Interrupt

Status
Not open for further replies.

vheerdg

New Member
Hi there can any one help im programming a 16f877 pic from my isr i call one function but from that funtion various others are called. but when i return via the closing } the interrupt goes mad. Can any one help.
 
Hi there can any one help im programming a 16f877 pic from my isr i call one function but from that funtion various others are called. but when i return via the closing } the interrupt goes mad. Can any one help.

You need to post your code - BUT - it's VERY, VERY important to keep ISR's as short as possible, and not to call routines from them. PIC's only have very limited stacks, and you're probably exceeding it.

So rewrite your program to make the ISR short with no calls (or hardly any).
 
Hi there thats exactly what i do i call routines from my interrupt cause i have my menu in side it here is my code What can i do besides chaging the whole code
//-----------------------------INTERRUPT Routine------------------------------------
interrupt isr() //interrupt service routine
{
INTF = 0;
SubtimeI();
if ((RB1 = 0)&&(RB2 = 0))
{
SubtimeI();
if ((RB1 = 0)&&(RB2 = 0))
{
PrintMM1();
}
}
}




//***********TOP LEVEL MENU -- MAX,OPTIMAL,MIN LEVEL ADJUST--**********


void PrintMM1() //max level adjust menu
{
CLRSI();
for (a = 19; a < NN; a++)
{
PORTD = num[a];
LCDPI();
if (a == 29)
{
DisArrow();
a = 126;
}
}
while (loop1 != 0)
{
loop2 = 1;
//Delayms(50);
if ((RB2 = 0)&&(RB1 = 0))
{
loop1 = 0;
}
Delayms(50);
else if (RB1 == 1) //scroll
{
PrintMM2();
}
Delayms(50);
else if (RB2 == 1) // select
{
CLRSI();
for (a = 19; a < NN1; a++) //max level menu entered
{
PORTD = num[a];
LCDPI();
}
SubtimeI();
lev1 = max;
MM1();
}

}

}


void PrintMM2() //optimal level adjust menu
{
CLRSI();
for (a = 30; a < NN; a++)
{
PORTD = num[a];
LCDPI();
if (a == 40)
{
DisArrow();
a = 126;
}
}
while (loop1 != 0)
{
loop2 = 1;
Delayms(50);
if ((RB2 = 0)&&(RB1 = 0))
{
loop1 = 0;
}
Delayms(50);
else if (RB1 == 1) //scroll
{
PrintMM3();
}
Delayms(50);
else if (RB2 == 1) // select
{
CLRSI();
for (a = 30; a < NN2; a++) //optimal level menu entered
{
PORTD = num[a];
LCDPI();
}
SubtimeI();
lev1 = opt;
MM1();
}
}

}


void PrintMM3() //min level adjust menu
{
CLRSI();
for (a = 41; a < NN; a++)
{
PORTD = num[a];
LCDPI();
if (a == 51)
{
DisArrow();
a = 126;
}
}
while (loop1 != 0)
{
loop2 = 1;
Delayms(50);
if ((RB2 = 0)&&(RB1 = 0))
{
loop1 = 0;
}
Delayms(50);
else if (RB1 == 1) //scroll
{
PrintMM1();
}
Delayms(50);
else if (RB2 == 1) // select
{
CLRSI();
for (a = 41; a < NN3; a++) //min level menu entered
{
PORTD = num[a];
LCDPI();
}
SubtimeI();
lev1= min;
MM1();
}
}

}
//***************CURRENT LEVEL DISPLAY**********************
void DisplayLevI()
{
MN = 77;
X= 10;
CLRSI();

for (a = 59;a < MN; a++)
{
--X;
PORTD = num[a];
LCDPI();
if (a == 67)
{
a = lev;
}
if (X == 0)
{
a = 77;
}
}
}


//*************MIDDLE MENU --- INCREASE AND DECREASE---**********
void MM1()
{
CLRSI();
if (lev1 == 0x00) //Full Tank 11111111
{
lev = 67 ;
}
else if (lev1 == 0x01) //00000001
{
lev = 68 ;
}
else if (lev1 == 0x03) //00000011
{
lev = 69;
}
else if (lev1 == 0x07) //00000111
{
lev = 70;
}
else if (lev1 == 0x0F)// Tank half full 00001111
{
lev = 71;
}
else if (lev1 == 0x1F) // 00011111
{
lev = 72 ;
}
else if (lev1 == 0X3F) //00111111
{
lev = 73;
}
else if (lev1 == 0X7F) //01111111
{
lev = 74;
}
else if (lev1 == 0XFF)//Tank Empty 11111111
{
lev = 75;
}
Z = 2;
DisplayLevI();
while (loop2 != 0)
{
Delayms(50);
if ((RB2 = 0)&&(RB1 = 0)) //Enter
{
loop2 = 0;
}
Delayms(50);
else if (RB1 == 1) //Increment
{
if(lev1 == 0x01)
{
lev1 = 0x03;
MM1();
}
else if((lev1 == 0x00)||(lev1 == 0x03)||(lev1 == 0x07)||(lev1 == 0x0F)||(lev1 == 0x1F)||
(lev1 == 0X3F)||(lev1 == 0X7F)||(lev1 == 0XFF))
{
lev1 = (lev1 * 2) + 1;
MM1();
}
}
Delayms(50);
else if (RB2 == 1) //Decrement
{
if(lev1 == 0x01)
{
lev1 = 0x00;
MM1();
}
else if((lev1 == 0x03)||(lev1 == 0x07)||
(lev1 == 0x0F)||(lev1 == 0x1F)||
(lev1 == 0X3F)||(lev1 == 0X7F)||
(lev1 == 0XFF))
{
lev1 = (lev1 - 1) / 2;
MM1();
}
}

}
}

//-----------Display Arrow------------------------------------------------------------
void DisArrow()
{
RB4 = 0; //RS line
PORTD = 0x8E; //set cgram address
LCDPI(); // Clock data into lcd
RB4 = 1;
PORTD = 0x00;
LCDPI();
RB4 = 0; //RS line
PORTD = 0xCE; //set cgram address
LCDPI(); // Clock data into lcd
RB4 = 1;
PORTD = 0x01;
LCDPI();
RB4 = 0; //RS line
PORTD = 0x8F; //set cgram address
LCDPI(); // Clock data into lcd
RB4 = 1;
PORTD = 0x02;
LCDPI();
RB4 = 0; //RS line
PORTD = 0xCF; //set cgram address
LCDPI(); // Clock data into lcd
RB4 = 1;
PORTD = 0x03;
LCDPI();
}

//-------------------CLEAR, DELAY AND CLOCK IN LCD FUNCTIONS---------------------
void CLRSI()
{
RB4 = 0;
PORTD = 0x01;
LCDPI();
RB4 = 1;
}

void LCDPI()
{
RB5 = 0; //ENABLE
Delayms(50);

RB5 = 1; //ENABLE
Delayms(50);
}

void SubtimeI()
{
multime = 10;
while (multime != 0)
{
--multime;
Delayms(200);
}
}
 
Hi!

When you post code, please use code tags (hit the "#" button in the editor when writing your post, and then put the source code between the code tags which are added to your post). It will make your code much easier to read and maintain its formatting.

Here is your original code in code tags, for people who wish to be able to read it easily:

Code:
//-----------------------------INTERRUPT Routine------------------------------------
interrupt isr() //interrupt service routine
{
    INTF = 0;
    SubtimeI();
    if ((RB1 = 0)&&(RB2 = 0))
    {
        SubtimeI();
        if ((RB1 = 0)&&(RB2 = 0))
        {
            PrintMM1();
        }
    }
}




//***********TOP LEVEL MENU -- MAX,OPTIMAL,MIN LEVEL ADJUST--**********


void PrintMM1() //max level adjust menu
{
    CLRSI();
    for (a = 19; a < NN; a++)
    {
        PORTD = num[a];
        LCDPI();
        if (a == 29)
        {
            DisArrow();
            a = 126;
        }
    }
    while (loop1 != 0)
    {
        loop2 = 1;
//Delayms(50);
        if ((RB2 = 0)&&(RB1 = 0))
        {
            loop1 = 0;
        }
        Delayms(50);
        else if (RB1 == 1) //scroll
        {
            PrintMM2();
        }
        Delayms(50);
        else if (RB2 == 1) // select
        {
            CLRSI();
            for (a = 19; a < NN1; a++) //max level menu entered
            {
                PORTD = num[a];
                LCDPI();
            }
            SubtimeI();
            lev1 = max;
            MM1();
        }

    }

}


void PrintMM2() //optimal level adjust menu
{
    CLRSI();
    for (a = 30; a < NN; a++)
    {
        PORTD = num[a];
        LCDPI();
        if (a == 40)
        {
            DisArrow();
            a = 126;
        }
    }
    while (loop1 != 0)
    {
        loop2 = 1;
        Delayms(50);
        if ((RB2 = 0)&&(RB1 = 0))
        {
            loop1 = 0;
        }
        Delayms(50);
        else if (RB1 == 1) //scroll
        {
            PrintMM3();
        }
        Delayms(50);
        else if (RB2 == 1) // select
        {
            CLRSI();
            for (a = 30; a < NN2; a++) //optimal level menu entered
            {
                PORTD = num[a];
                LCDPI();
            }
            SubtimeI();
            lev1 = opt;
            MM1();
        }
    }

}


void PrintMM3() //min level adjust menu
{
    CLRSI();
    for (a = 41; a < NN; a++)
    {
        PORTD = num[a];
        LCDPI();
        if (a == 51)
        {
            DisArrow();
            a = 126;
        }
    }
    while (loop1 != 0)
    {
        loop2 = 1;
        Delayms(50);
        if ((RB2 = 0)&&(RB1 = 0))
        {
            loop1 = 0;
        }
        Delayms(50);
        else if (RB1 == 1) //scroll
        {
            PrintMM1();
        }
        Delayms(50);
        else if (RB2 == 1) // select
        {
            CLRSI();
            for (a = 41; a < NN3; a++) //min level menu entered
            {
                PORTD = num[a];
                LCDPI();
            }
            SubtimeI();
            lev1= min;
            MM1();
        }
    }

}
//***************CURRENT LEVEL DISPLAY**********************
void DisplayLevI()
{
    MN = 77;
    X= 10;
    CLRSI();

    for (a = 59;a < MN; a++)
    {
        --X;
        PORTD = num[a];
        LCDPI();
        if (a == 67)
        {
            a = lev;
        }
        if (X == 0)
        {
            a = 77;
        }
    }
}


//*************MIDDLE MENU --- INCREASE AND DECREASE---**********
void MM1()
{
    CLRSI();
    if (lev1 == 0x00) //Full Tank 11111111
    {
        lev = 67 ;
    }
    else if (lev1 == 0x01) //00000001
    {
        lev = 68 ;
    }
    else if (lev1 == 0x03) //00000011
    {
        lev = 69;
    }
    else if (lev1 == 0x07) //00000111
    {
        lev = 70;
    }
    else if (lev1 == 0x0F)// Tank half full 00001111
    {
        lev = 71;
    }
    else if (lev1 == 0x1F) // 00011111
    {
        lev = 72 ;
    }
    else if (lev1 == 0X3F) //00111111
    {
        lev = 73;
    }
    else if (lev1 == 0X7F) //01111111
    {
        lev = 74;
    }
    else if (lev1 == 0XFF)//Tank Empty 11111111
    {
        lev = 75;
    }
    Z = 2;
    DisplayLevI();
    while (loop2 != 0)
    {
        Delayms(50);
        if ((RB2 = 0)&&(RB1 = 0)) //Enter
        {
            loop2 = 0;
        }
        Delayms(50);
        else if (RB1 == 1) //Increment
        {
            if(lev1 == 0x01)
            {
                lev1 = 0x03;
                MM1();
            }
            else if((lev1 == 0x00)||(lev1 == 0x03)||(lev1 == 0x07)||(lev1 == 0x0F)||(lev1 == 0x1F)||
                    (lev1 == 0X3F)||(lev1 == 0X7F)||(lev1 == 0XFF))
            {
                lev1 = (lev1 * 2) + 1;
                MM1();
            }
        }
        Delayms(50);
        else if (RB2 == 1) //Decrement
        {
            if(lev1 == 0x01)
            {
                lev1 = 0x00;
                MM1();
            }
            else if((lev1 == 0x03)||(lev1 == 0x07)||
                    (lev1 == 0x0F)||(lev1 == 0x1F)||
                    (lev1 == 0X3F)||(lev1 == 0X7F)||
                    (lev1 == 0XFF))
            {
                lev1 = (lev1 - 1) / 2;
                MM1();
            }
        }

    }
}

//-----------Display Arrow------------------------------------------------------------
void DisArrow()
{
    RB4 = 0; //RS line
    PORTD = 0x8E; //set cgram address
    LCDPI(); // Clock data into lcd
    RB4 = 1;
    PORTD = 0x00;
    LCDPI();
    RB4 = 0; //RS line
    PORTD = 0xCE; //set cgram address
    LCDPI(); // Clock data into lcd
    RB4 = 1;
    PORTD = 0x01;
    LCDPI();
    RB4 = 0; //RS line
    PORTD = 0x8F; //set cgram address
    LCDPI(); // Clock data into lcd
    RB4 = 1;
    PORTD = 0x02;
    LCDPI();
    RB4 = 0; //RS line
    PORTD = 0xCF; //set cgram address
    LCDPI(); // Clock data into lcd
    RB4 = 1;
    PORTD = 0x03;
    LCDPI();
}

//-------------------CLEAR, DELAY AND CLOCK IN LCD FUNCTIONS---------------------
void CLRSI()
{
    RB4 = 0;
    PORTD = 0x01;
    LCDPI();
    RB4 = 1;
}

void LCDPI()
{
    RB5 = 0; //ENABLE
    Delayms(50);

    RB5 = 1; //ENABLE
    Delayms(50);
}

void SubtimeI()
{
    multime = 10;
    while (multime != 0)
    {
        --multime;
        Delayms(200);
    }
}

(Note: I haven't actually read the code yet; I've just formatted it. I'll take a look at it and post again later if someone else doesn't beat me to it.)


Torben
 
OK, a quick reading seems to show that if RB1 keeps being 1, then you have a recursive loop on your hands and your stack will overflow. PrintMM1() will call PrintMM2(), which will call PrintMM3(), which will call PrintMM1(), which will call PrintMM2(), which will. . .but you get the idea. :) Your poor stack will overflow and when you return back out of those functions things will get nasty.

I would think that you need another approach to handling the menu. Having said that, I'm not a PIC expert like some others on the forum, so wait for their input before deciding anything. If it were me, I'd rewrite the entire menu system, using lookup tables for the menu decisions, for instance. Besides stack abuse, there are magic numbers all throughout the code and some other style issues. But I think the big problem is the stack.


Torben
 
I don't do C, but your entire premise is wrong from the beginning - I would suggest rewriting it from scratch, and doing the absolute minimum in the ISR, and no calls.

You're also making matters much worse using C as well, as you've no idea how many calls each section of C code might be generating.
 
I don't do C, but your entire premise is wrong from the beginning - I would suggest rewriting it from scratch, and doing the absolute minimum in the ISR, and no calls.

I agree--I wouldn't write it like that even for a high-level architecture in a high-level language with gobs of stack space.

You're also making matters much worse using C as well, as you've no idea how many calls each section of C code might be generating.

I have to ask about this statement. Do you mean "calls" in the strict sense? If so I disagree--it's not hard to determine how many calls are made in C code. That said, it can certainly be tedious if you're not familiar with the compiler and environment. For a language like Java or PHP I would agree with you: it would be a gargantuan task to work out the number of calls unless you had help from the language designers or deep insight into the language itself.

In any event, this menu code should be rewritten so that it's not an issue. There is no way that a menu system should be so tightly written that it couldn't be written in C or even BASIC. And certainly not in an interrupt routine. Triggered by an interrupt, sure. But as you say, not inside one.

Just my $0.02 CDN. ;)


Torben
 
You're also making matters much worse using C as well, as you've no idea how many calls each section of C code might be generating.

I also thought this but after using various C compilers I now realize that they use a software stack in order to circumvent the stack limitation of the pic. Some compilers have a jump table in ROM that's indexed into in order to effect a return via a RAM location. My head hurts just thinking about writing that complier.

Mike.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top