First posting here!
I’ve tried to find simple code examples that use the timer.c in the STM core but without much luck. I can see others have done hardware timers in different cores but I’ve a ST32L423 Nucleo board and generally I’m trying to make use of the ST core library, which so far has worked for me.
If anyone has a LED blink or other simple example, using interrupts with a hardware timer, it will help me see how to initialise and make the necessary calls to timer.c. Eventual goal is to set up PWM but I need to crawl before I walk !
Thanks in advance.
Kev
http://docs.leaflabs.com/static.leaflab … timer.html
I have not looked into how timers are abstracted in the Official STM Arduino core.
Ray
Cheers for the link.
Kev
Do you mean core instead of examples?
For the STM32GENERIC core we have some timer examples.
I started using the ‘official’ ST core and so far got stuff working so my ideal was to stick with that and use its timer library.
I think I just found one example using this but I can’t get it to compile. I’ll try and fix this but if I’m stuck (likely!), will post here to see if anyone can help point out what I’m doing wrong.
Thanks
Kev
You could try this:
/*
Blink with Timer
Turns an LED on for one second, then off for one second, repeatedly.
*/
#define TIMER_BLINK TIM4
volatile uint16_t count = 0;
/* Handler for stimer */
static stimer_t TimHandle;
/**
@brief blink callback. Call by a timer interrupt.
@param htim: pointer to stimer_t
@retval None
*/
static void blink(stimer_t *htim) {
UNUSED(htim);
if (count++ == 100) {
count = 0;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
}
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
/* Set TIMx instance. */
TimHandle.timer = TIMER_BLINK;
/* Timer set to 10ms */
TimerHandleInit(&TimHandle, 10000 - 1, ((uint32_t)(getTimerClkFreq(TIMER_BLINK) / (1000000)) - 1));
attachIntHandle(&TimHandle, blink);
}
// the loop function runs over and over again forever
void loop() {
// do nothing
}
Appreciate all the help.
Kev
I’m away from home at present so can’t download to my hardware but compiling is a massive step forward for me, so thanks for the help. This should help me progress and start to use for the PWM application I’m working on.
Thanks again.
Kev
Thanks
Kev
thank you !
I’ve tested the sketch from here (https://www.stm32duino.com/viewtopic.php?p=49879#p49879) on Nucleo-F103RB, works as expected for TIM1 through TIM4.
I’m hoping to gain enough understanding of this core and STM32 timer control to port this flight controller application (http://www.brokking.net/ymfc-32_main.html). This was originally developed around a slightly earlier version of Roger’s STM32duino core (http://www.brokking.net/YMFC-32_downloads.html). It makes use some lower level bit manipulation of TIM2-4 for interrupt based input capture of pulse inputs as well as hardware PWM control of outputs.
I’m working toward a HAL based core for this app to be able to move over to F3/F4 based boards. At the same time I’m climbing the general STM32/HAL learning curve, having migrated from 8 bit AVRs. I’ve been playing with STM32generic as it appears to have working HardwareTimer functionality, but issues with basic Arduino functions in that core have me rethinking that path.
Very much looking forward to helping with HardwareTimer progress and helping with development and test where I can.
Thanks,
George
Typical input capture interrupt handler (toggles the input capture edge direction within interrupt to get enough input channels (6 pulse capture inputs are needed):
void handler_channel_1(void) { //This function is called when channel 1 is captured.
if (0b1 & GPIOA_BASE->IDR >> 0) { //If the receiver channel 1 input pulse on A0 is high.
channel_1_start = TIMER2_BASE->CCR1; //Record the start time of the pulse.
TIMER2_BASE->CCER |= TIMER_CCER_CC1P; //Change the input capture mode to the falling edge of the pulse.
}
else { //If the receiver channel 1 input pulse on A0 is low.
channel_1 = TIMER2_BASE->CCR1 - channel_1_start; //Calculate the total pulse time.
if (channel_1 < 0)channel_1 += 0xFFFF; //If the timer has rolled over a correction is needed.
TIMER2_BASE->CCER &= ~TIMER_CCER_CC1P; //Change the input capture mode to the rising edge of the pulse.
}
}

