Welcome to EDAboard.com

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

Register Log in

Problem with switch case in interrupt

Status
Not open for further replies.

bhengsoh

Newbie level 6
Joined
Apr 17, 2010
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,405
I am having problem with switch case. The program look like this:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
unsigned char state;
void main()
{
        state = 1;
}
static void interrupt isr()
{
    if(T0IF)
    {
        T0IF = 0;
        TMR0 = -40;
 
        switch(state)
        {
            case 1: GPIO2 = ~GPIO2;
            state = 2;
            break;
            case 2: GPIO1 = ~GPIO1;
            state = 1;
            break;
            default:    ;
        }
    }
}


It stuck at case 1. Pls hep me to debug this.
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
47,489
Helped
14,048
Reputation
28,351
Reaction score
12,706
Trophy points
1,393
Location
Bochum, Germany
Activity points
276,162
There's no problem with the switch case. I guess, no interrupt is executed. No interrupt enable can be seen in your code. Also depending on the compiler, you'll need an endless loop in the main() function.
 

ckshivaram

Advanced Member level 5
Joined
Apr 21, 2008
Messages
5,070
Helped
2,146
Reputation
4,298
Reaction score
2,087
Trophy points
1,393
Location
villingen (Germany) / Bangalore
Activity points
30,097
But its a bad design to use switch case in interrupt and making the ISR code more lengthier...

Which controller and IDE.. the syntax for ISR routines vary from compiler to compiler,......
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
47,489
Helped
14,048
Reputation
28,351
Reaction score
12,706
Trophy points
1,393
Location
Bochum, Germany
Activity points
276,162
But its a bad design to use switch case in interrupt.
It may be required in some cases. If alternative code pathes exist in an ISR, there's nothing against a case structure. It's usually more effective than if..else..if spaghetti code.

In any case, the original problem isn't related to coding style.
 

bhengsoh

Newbie level 6
Joined
Apr 17, 2010
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,405
Below is part of my program:

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <pic.h>
__CONFIG(0x00C2);
 
#define max_bit         16
 
unsigned int encode_val;
volatile unsigned char state,encode_count;
 
void start_tx(unsigned int val);
 
static void interrupt isr()
{
    if(T0IF)
    {
        T0IF = 0;
        TMR0 = -4;
        switch(state)
        {
            case 1: GPIO0 = ~GPIO0;
                    state = 2;
                    break;
            case 2: GPIO1 = ~GPIO1;
                    state = 1;
                    break;
            default:    break;
        }
    }
}
void main()
{
    CMCON0 = 7;
    ANSEL = 0;
    TRISIO = 0;
    start_tx(1);
// TMR 0 configuation
    T0CS = 0;                   
    PSA = 0;                        
    PS2 = 1;                        // prescale 1:32
    PS1 = 1;                        //
    PS0 = 1;                        //
    T0IE = 1;                       // TMR0 Interrupt
    GIE = 1;;
}
 
void start_tx(unsigned int val)
{
    unsigned int i,parity = 0;
    for(i=0;i<max_bit;i++)
    {
        if((val>>i)&1)
        {
            parity++;
        }
    }
    if(parity&1)
    {
        encode_val = val | 0x8000;
    }
    state = 1;
}


I dunno where is wrong. I have also try if else and does not work too. It shows me that the switch case is stuck at case 1 when timer interrupt in simulation. And sometimes the case 1 is not executed when timer interrupt.
 
Last edited:

alexxx

Advanced Member level 4
Joined
Apr 17, 2011
Messages
1,013
Helped
273
Reputation
552
Reaction score
270
Trophy points
1,383
Location
Greece
Activity points
7,938
bhengsoh said:
It shows me that the switch case is stuck at case 1 when timer interrupt.
Hi!

I don't see a main loop, so I wonder how do you even get an interrupt. But anyway, in your start_tx(1) function, at the last line you write state = 1. Is state variable changing anywhere else in your program? If no, then case 1 will always be running inside the interrupt.
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
47,489
Helped
14,048
Reputation
28,351
Reaction score
12,706
Trophy points
1,393
Location
Bochum, Germany
Activity points
276,162
I don't see a main loop
Yes, I mentioned the same. There should be a while(1); at the end of main(), otherwise the code will possibly restart all over again.
 

alexxx

Advanced Member level 4
Joined
Apr 17, 2011
Messages
1,013
Helped
273
Reputation
552
Reaction score
270
Trophy points
1,383
Location
Greece
Activity points
7,938
FvM said:
alexxx said:
I don't see a main loop
Yes, I mentioned the same.
I saw that you mentioned it FvM, but he updated his code and still this error existed, that's why I mentioned it again. Maybe you 're right and I should have used your words in quotes, sorry about that.
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
47,489
Helped
14,048
Reputation
28,351
Reaction score
12,706
Trophy points
1,393
Location
Bochum, Germany
Activity points
276,162
Maybe you 're right and I should have used your words in quotes, sorry about that.
It's O.K. to repeat this point, I didn't want to complain, just wondering why it's unchanged.
 

bhengsoh

Newbie level 6
Joined
Apr 17, 2010
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,405
I use the timer overflow flag as interrupt, and that's how it get interrupt every few usec without main loop. Anyway, I believe it is the read-modify-write problem. I make shadow copy of GPIO to continuously update the output pin. Now it was working in simulation. However, the switch case is really bothering me, as it is disassembled into many lines of codes, and the second interrupt might happen before the first interrupt end, especially when I have a long statement. But I still need it as my code will have like 7 cases.

Another method I found online was to use array of pointer to function method, but I dunno it is worth or not. Perhaps anyone with experience of using this method can advise me, as I dunno how to implement it in interrupt function.
 

alexan_e

Administrator
Joined
Mar 16, 2008
Messages
11,895
Helped
2,020
Reputation
4,156
Reaction score
2,031
Trophy points
1,393
Location
Greece
Activity points
64,377
I use the timer overflow flag as interrupt, and that's how it get interrupt every few usec without main loop.
you still need to have a loop to ensure that the execution never exits the main function, if you get out of the main function you will get unpredicted results.
In an operating system there is an idle service that can take care of this but in an mcu you must ensure that you stay inside the main process at all times.
A simple while(1); does exactly that

Alex
 

bhengsoh

Newbie level 6
Joined
Apr 17, 2010
Messages
14
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,405
Thanks. Now I can understand fully what the problem in my code. Without infinite loop, the program will end. I will remember this mistake. Thanks again.
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
47,489
Helped
14,048
Reputation
28,351
Reaction score
12,706
Trophy points
1,393
Location
Bochum, Germany
Activity points
276,162
Anyway, I believe it is the read-modify-write problem.
You previously reported state to be stuck in case 1 rather than GPIO not set correctly. Obviously this is not the same. Anyway, why do you assume a RMW problem? Do you overload the GPIO pins?
However, the switch case is really bothering me, as it is disassembled into many lines of codes, and the second interrupt might happen before the first interrupt end, especially when I have a long statement. But I still need it as my code will have like 7 cases.
I won't assume, that your compiler is inserting arbitrary code for case structures. So the most likely explanation is, that the code is exactly representing the complexity of the problem. But we have to guess here, because you didn't show the real code. It's not important by the way, how many code lines are generated in total. The interesting point is, how many are executed in the active state.

There are different ways to code a case structure. Good compilers will choose indirect jumps for processors, that support it. But it's not an option for PIC10. So passing a chain of conditional branches is the only way to do it.
you still need to have a loop to ensure that the execution never exits the main function
Maybe your code is already taking care of this point, but at least you're excellent in ignoring pretty strong hints.
 

alexxx

Advanced Member level 4
Joined
Apr 17, 2011
Messages
1,013
Helped
273
Reputation
552
Reaction score
270
Trophy points
1,383
Location
Greece
Activity points
7,938
bhengsoh said:
Another method I found online was to use array of pointer to function method, but I dunno it is worth or not.
Although I use function pointers I avoid them inside interrupt routines, because I get slower execution time. The code may look small and shipshape, but the disassembly window always tells the truth in cases like that and I suggest to advice this window from time to time. Still you can always test execution times for different code versions and judge by yourself, but I think it is better to stick with the switch-case version inside the interrupt code.

Hope that helped.
 

FvM

Super Moderator
Staff member
Joined
Jan 22, 2008
Messages
47,489
Helped
14,048
Reputation
28,351
Reaction score
12,706
Trophy points
1,393
Location
Bochum, Germany
Activity points
276,162
Although I use function pointers I avoid them inside interrupt routines, because I get slower execution time.
That would be my guess, too. But in addition, they aren't available for PIC10 as far as I understand.
 

Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top