cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupt cant set global variable?

texton1
Associate II
Posted on March 13, 2013 at 13:22

Hi all. 

I got a problem: Every time i am setting a global variable in my ISR it is set to 0 after the ISR has ended!

volatile int test; 

void main(void)

{

TIM1_DeInit(); 

TIM1_TimeBaseInit(10, TIM1_COUNTERMODE_UP, 20000, 0);

TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE); 

TIM1_Cmd(ENABLE); 

  /* Infinite loop */

enableInterrupts();

  while (1)

  {

test = test;

  }  

}

INTERRUPT_HANDLER(TIM1_UPD_OVF_TRG_BRK_IRQHandler, 11)

{

  test = 1 ;

}

Test is always 1 in the ISR but always 0 in the main??.. WHY??

Thanks in advance 🙂 
6 REPLIES 6
elil
Associate III
Posted on March 13, 2013 at 17:10

I'm quite sure there is yet another code except the code you've published here...

Anyway, I would suggest you to put a data breakpoint when test==0. When the breakpoint triggers, you would be able to see which code resets this variable.

Good luck!

E.L.

texton1
Associate II
Posted on March 13, 2013 at 17:48

Yes there is, i am using the standard libraries for the STM8 family. 

I am using SVDT - how do i set such a data break? 🙂  

fggnrc2
Associate II
Posted on March 13, 2013 at 18:21

The code which your compiler outputs contains the answer to your question.

Your code contains an access conflict between the ISR and the main code.

When you specify that test is volatile, the compiler assumes that its value may change between two consecutive reads, but it doesn't make the assignment atomic, i.e. the ISR may interrupt it.

Only assembler instructions are atomic (there ase some exceptions, for instance a DIVW instruction may be interrupted, but they affect only core registers), while an assignment consists usually in two assembly instructions: a read one (eg. LD A,test) and a write one (eg. LD test,A).

The compiler sometimes outputs a MOV test,test which is an atomic instruction.

This means that you should watch at the assembler code to know what happens and to take the right correction to your code.

If you disable interrupts before the assignment and enable them afterwards, the access conflict disappears, but this fix adds two bytes to the executable size.

BR

EtaPhi

texton1
Associate II
Posted on March 14, 2013 at 10:24

I tried to set a data break when the variable was set = 0 (Which never should happen) and it breaks at a assembly line saying: 

0690X00000604qaQAA.png

fggnrc2
Associate II
Posted on March 14, 2013 at 14:30

The breakpoint stopped your code in the initialization phase when all global variables are initialized, i.e. set to zero.

This means that your main() is still going to be executed, so this assembler dump is useless...

peeya
Associate
Posted on March 24, 2014 at 12:06

you may try this.

main.c declare the variable before main module.

char test = 0x00; (don't use just test = 0, it is very impotant)

at interupt file module, 

extern test;

good luck