# Problem with switch case in interrupt

Status
Not open for further replies.

#### bhengsoh

##### Newbie level 6
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
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
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
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
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
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
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.

bhengsoh

### bhengsoh

Points: 2

#### alexxx

##### Advanced Member level 4
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
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
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

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

### bhengsoh

Points: 2

#### bhengsoh

##### Newbie level 6
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
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
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
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.