STM8 simple timer 4 interrupt

It took me way too long to figure out how to user timer4 on a STM8s103F3 breakoutboard. So for future reference to others in a similar situation, here is what I found.

Tools used:
Arduino IDE 1.8.7 (Newest version should work as well)
Sduino STM8 core ver 0.5.0

Timer 4 can be used in the arduino IDE/sduino 0.5.0, but at the expense of the delay(ms) function.
The delay function uses timer 4, and therefore reprogramming it will render delay(ms) unusable.

As the interrupt vector for timer 4 is not defined in the sduino core file arduino.h, we have to approach the ISR without using attachinterrupt() function.
The ISR can be defined this way:

INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler,23)
{
// put you code here
TIM4_ClearFlag(TIM4_FLAG_UPDATE); //very important, if not cleared the interrupt function is called over and over stalling the uP

}

One thing that is very important is to include the interrupt flag reset TIM4_ClearFlag(TIM4_IT_UPDATE). If you don’t, the uP will call the ISR forever ,and not just once very timer overflow.
Beware that if you use delay() anywhere in code, the compiler will respond with this message:
Multiple definition of _TIM4_UPD_OVF_IRQHandler
This is because delay() function also uses timer 4, and more than one definition of an ISR results in the above error message.

Even if the delay function is not used, the Sduino core initialize timer 4 anyway and sets it running.
The Sduino initializes Prescaler reg= 6 and Autoreload reg= 249. This results in 1ms ticks with a clock source of 16Mhz.

If this time does not fit your code you will have to load the Prescaler register & AutoReload register with suitable values.
Doing so can be done with this functions:
TIM4_TimeBaseInit(Prescaler ,AutoReload value)
For Prescaler the value can be 1-7 (2^value), and for autoreload value 0-255

For a complete reference of all timer4 functions used to configure timer4 look here:
https://documentation.help/STM8S-A-Standard-Peripherals-Drivers/group__TIM4__Public__Functions.html

The small example below should be enough to verify that the timer is running and the ISR is called:

int timercount=0;

INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler,23)
{
  timercount++;  
  TIM4_ClearFlag(TIM4_FLAG_UPDATE); //very important, if not cleared the interrupt function is called over and over stalling the uP 
}

void setup() {
    Serial_begin(115200);  //init uart
  } //end setup

unsigned int i=0;
unsigned int j=0;

void loop() {
  Serial_print_s("timercount: ");  
  Serial_println_i(timercount);
  
//for loop acts as delay function
  for (i=0; i<20000; i++) 
    { for (j=0; j<200; j++);   }
  //delay(500);  //try to comment this line in, and see the compiler error
} //end loop

I’m by no means an expert with either STM8 or arduino IDE, so my conclusion might be wrong, but it is working for me at least.

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.