Skip to main content
Visitor II
May 27, 2020
Question

I would like to know how to use any timer, say TIM2, and GetCounter() correctly. I'm using SDCC on linux and compiling for an STM8L051. Please see some example blinky code. Below is the code I think should work. Any help is greatly appreciated.

  • May 27, 2020
  • 2 replies
  • 939 views
void main(void) {
 uint16_t tmpcnt = 0;
 uint8_t tmpcntrl, tmpcntrh;
 
 setup_pins();
 
 CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE);
 TIM2->PSCR = TIM2_Prescaler_1;
 TIM2->ARRH = 0;
 TIM2->ARRL = 1;
 TIM2->CNTRH = 0;
 TIM2->CNTRL = 1;
 
 TIM2->SR1 &= ~TIM_SR1_UIF;
 TIM2->CR1 |= TIM_CR1_CEN;
 
 while (1) {
 tmpcntrh = TIM2->CNTRH;
 tmpcntrl = TIM2->CNTRL;
 tmpcnt = (uint16_t)(tmpcntrl);
 tmpcnt |= (uint16_t)((uint16_t)tmpcntrh << 8);
 
 if (tmpcnt % 1000 > 500) {
 leds_on();
 } else {
 leds_off();
 }
 }
 TIM2->CR1 &= ~TIM_CR1_CEN;
 CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, DISABLE);
}
 

    This topic has been closed for replies.

    2 replies

    AClap.1Author
    Visitor II
    June 5, 2020

    Never mind. I got it all sorted out.

    Visitor II
    June 11, 2020

    There are tutorials at http://www.colecovision.eu/stm8/, they all use TIM1 though.

    AClap.1Author
    Visitor II
    June 11, 2020

    Thank you Phillipp. I was eventually able to figure out what I needed. In the SPL exampls for STM8L there is code for the TIM4 TimeBase example, and between that and others, I was able to make a working timer for TIM3 that compiles on linux with SDCC. I was able to get it to run down to about 30uS, but not faster. It seems every combination of PERIOD and Prescaler that would go faster just locks up my chip. Here's an example that blinks some leds.

    #include "stm8l15x.h"
    #include "leds.h"
     
    #define TIM3_PERIOD 2 /// up to 0xFFFF for TIM3
     
    volatile uint32_t TimingElapsed;
     
    static void CLK_Config(void);
    static void TIM3_Config(void);
    volatile uint32_t Elapsed(void);
    void TimingElapsed_Increment(void);
     
    void main(void) {
     uint32_t micros;
     CLK_Config();
     setup_pins();
     leds_on();
     
     TIM3_Config();
     
     while (1) {
     micros = TimingElapsed;
     if (micros % 333333 > 166666) {
     leds_on(); // Toggle LEDS
     } else {
     leds_off(); // Toggle LEDS
     }
     }
    }
     
    static void CLK_Config(void) {
     CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1); // HSI clock prescaler: 1
     CLK_SYSCLKSourceSwitchCmd(ENABLE); // Select HSI as system clock source 
     CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI);
     while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_HSI) {}
     CLK_PeripheralClockConfig(CLK_Peripheral_TIM3, ENABLE); // Enable TIM3 CLK 
    }
     
    static void TIM3_Config(void) {
     // TIM3 configuration:
     // Prescalar=16, 1MHz, TIM3_PERIOD=2, 3/1000000 = about 30uS -> YES
     // Time base config 
     TIM3_TimeBaseInit(TIM3_Prescaler_16, TIM3_CounterMode_Down, TIM3_PERIOD);
     TIM3_ClearFlag(TIM3_FLAG_Update); // Clear TIM3 update flag 
     TIM3_ITConfig(TIM3_IT_Update, ENABLE); // Enable update interrupt 
     enableInterrupts(); // enable interrupts 
     
     TIM3_Cmd(ENABLE); // Enable TIM3 
    }
     
    //INTERRUPT_HANDLER(TIM3_UPD_OVF_TRG_IRQHandler, 25) {
    //stm8l15x.h: #define INTERRUPT_HANDLER(a,b) void a() __interrupt(b)
    void TIM3_UPD_OVF_TRG_IRQHandler() __interrupt (21) {
     TimingElapsed_Increment();
     TIM3_ClearITPendingBit(TIM3_IT_Update); // Cleat Interrupt Pending bit
    }
     
    volatile uint32_t Elapsed(void) {
     return TimingElapsed;
    }
     
    void TimingElapsed_Increment(void) {
     if (TimingElapsed < 0xFFFFFFFF) {
     TimingElapsed++;
     } else {
     TimingElapsed=0;
     }
    }