AnsweredAssumed Answered

Interrupts with STM8S003F3P6 and TIM2

Question asked by David Instone on Jun 17, 2017
Latest reply on Jun 19, 2017 by David Instone

STVD 4.3.10

Cosmic V4.3.7

eBay el cheapo STM8S003F3P6 (The blue one with the LED on B5)

 

Hello all. I am having a bit of a problem with I suspect basic interrupt coding. I have the LED blinking at a variable rate with a variable delay so all the port setups are OK but when I try to use TIMs with an interrupt it appears that I cannot change the Update Interrupt flag. In the debugger the interrupt service routine is entered, I can single step through it and toggle the LED but as soon as it is finished it goes straight back to the start of the Int routine. In the watch window the UIF flag does not get changed no matter what code I use but I can change it manually. In which case the program just seems to hang at the end of the interrupt routine. Here is the code

 

#define TIM2_CR1_ARPE    ((uint8_t)0x80) /*!< Auto-Reload Preload Enable mask. */
#define TIM2_CR1_OPM     ((uint8_t)0x08) /*!< One Pulse Mode mask. */
#define TIM2_CR1_URS     ((uint8_t)0x04) /*!< Update Request Source mask. */
#define TIM2_CR1_UDIS    ((uint8_t)0x02) /*!< Update DIsable mask. */
#define TIM2_CR1_CEN     ((uint8_t)0x01) /*!< Counter Enable mask. */

 

#define TIM2_IER_UIE     ((uint8_t)0x01) /*!< Update Interrupt Enable mask. */

 

#define TIM2_SR1_UIF     ((uint8_t)0x01) /*!< Update Interrupt Flag mask. */
/*SR2*/

 

void main( void )
{
    disable_interrupts();
    SetupOutputPortB();
    InitialiseTimer2();
    SetupTimer2();
    //enable_interrupts();
    main_loop();
  return;
}

 

void main_loop(void)
{
  while(1)
  {                     
    // Our LED is on Port B5
    //Turn on and off the output and then delay

            delay(40000);
            GPIOB->ODR ^= BIT5; //1<<5;// PB.5 XOR PIN5 Toggle

// Delay blink works fine

  }

}

 

void InitialiseTimer2()
{
TIM2->CR1 = 0;               // Turn everything TIM2 related off.
TIM2->IER = 0;
TIM2->SR1 = 0;
TIM2->SR2 = 0;
TIM2->CCER1 = 0;
TIM2->CCER2 = 0;
TIM2->CCER1 = 0;
TIM2->CCER2 = 0;
TIM2->CCMR1 = 0;
TIM2->CCMR2 = 0;
TIM2->CCMR3 = 0;
TIM2->CNTRH = 0;
TIM2->CNTRL = 0;
TIM2->PSCR = 0;
TIM2->ARRH  = 0;
TIM2->ARRL  = 0;
TIM2->CCR1H = 0;
TIM2->CCR1L = 0;
TIM2->CCR2H = 0;
TIM2->CCR2L = 0;
TIM2->CCR3H = 0;
TIM2->CCR3L = 0;
}

 

void SetupTimer2()
{
TIM2_PSCR = 0x000f;      // 2^PSC[3:0] Prescaler.

TIM2->ARRH = 0xef;      // c3 195 High byte of 50,000.

TIM2->ARRL = 0xfe;         // 55 85 Low byte of 50,000.

 

TIM2->CR1 |= TIM2_CR1_ARPE;   //0x80;     Auto reload preload enabled
TIM2->IER |= TIM2_IER_UIE;      //0x01;    TIM2 Update Interrupt enabled
TIM2->CR1 |= STM8_TIMx_CR1_CEN;   //0x01;    Turn ON timer
}

 

@far @interrupt void TIM2_UPD_OVF_IRQHandler(void);
//#define IRQ13 TIM2_UPD_OVF_IRQHandler

 

@interrupt void TIM2_UPD_OVF_IRQHandler(void){

// Interrupt routine is called no problem.

GPIOB->ODR ^= BIT5;             // PB.5 XOR PIN5
/* Even TIM2_SR1 = 0; Does not work  */
TIM2_SR1 ^= TIM2_SR1_UIF; //; 0x01
/*Reset the interrupt otherwise it will fire again straight away.
  Which it does anyway */
// disable_interrupts();
}

 

So can anybody figure out what I am missing here?

Outcomes