2020-05-27 01:04 PM
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);
}
2020-06-05 10:03 AM
Never mind. I got it all sorted out.
2020-06-11 03:26 AM
There are tutorials at http://www.colecovision.eu/stm8/, they all use TIM1 though.
2020-06-11 10:08 AM
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;
}
}