cancel
Showing results for 
Search instead for 
Did you mean: 

Corrupt varible within an Interrupt on STM32F103ZET6

chrisr
Associate
Posted on June 06, 2011 at 08:02

I have a variable that is not appears to not being retrieved consistantly from within an interrupt.

 I have the following code for the Timer3, which is configure to interrupt on a count down timer.

unsigned int errorCount;

void TIM3_IRQHandler(void)

{

  static volatile unsigned int pwm_on = 0;

  if (TIM3->SR & 0x0001)      //Check interrupt source

  {

    TIM3->SR &= ~0x0001;    //Clear UIF Flag

  if (((pwm_on) && ((GPIOC->ODR & 0x0001) == 0)) ||

      ((pwm_on  == 0) && (GPIOC->ODR & 0x0001)))

    errorCount++;

    if (pwm_on)

    {

         GPIOC->ODR &= ~0x0001;

         pwm_on = 0;

    }

    else

    {

         GPIOC->ODR |= 0x0001;

         pwm_on = 1;

    }

The problem is that errorCount is not zero.  This interrupt operates about 7000 times per second, and in that time we get an error count of 7 - 15 times.  I am using this interrupt to toggle a pwm pin and it affects my device. 

If I toggle the pin directly like

GPIOC-> ^= 0x0001;

then everything is fine.

The only reason this could occur is if pwm_on was getting corrupted or was not being retrieved. 

I'm really stumped.

Any help would  be appreciated.

Thanks

#corrupt-ram-interrupt-stm32-timer
4 REPLIES 4
infoinfo989
Associate III
Posted on June 06, 2011 at 23:38

Which compiler are you using?

hfs99
Associate II
Posted on June 07, 2011 at 03:01

I made a tiny project and pasted your interrupt routine in. It works fine on my ''stamp'', and errorCount stays at zero. Maybe you need to look at what else you have going on?

I tried to upload a copy of the project (gcc, Makefile) to

http://www.overtracks.com/sos/20110606/toglaa.zip

Posted on June 07, 2011 at 03:36

Yes, seriously doubt it's a RAM problem.

Make sure ''volatile'' is actually being used properly, specifically for the GPIO and peripheral registers, not static locals.

Look at the generated assembly code, might be instructive.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
chrisr
Associate
Posted on June 08, 2011 at 07:03

Thanks for the replies.  I just found the problem.

The problem was that I was using the GPIOC->ODR |= 0x0001 and GPIO->ODR &= ~0x0001.

This was inadvertently setting the other bits briefly in that port.  Other pins in that port were used as an SPI bit bashed data stream and they were using |= and &= as well.  They were setting and unsetting each others bits and that seemed to cause my interrupt to sometimes not have the bit set when it should have been set.  This was due to the interrupt jumping in the middle of a write data bit of one of my bit bashed pins.

I thought that it was the variable that was getting corrupted but really it had been the GPIOC pin that was getting changed.

The solution was to use the GPIOC->BSRR register instead of the ODR register. 

I have since changed all usage of &= and |= for the GPIO pins to use the BSRR register instead. 

Thanks again.