cancel
Showing results for 
Search instead for 
Did you mean: 

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.

AClap.1
Associate II
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);
}
 

3 REPLIES 3
AClap.1
Associate II

Never mind. I got it all sorted out.

Philipp Krause
Senior II

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

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;
    }
}