[SOLVED] Any examples using the (hardware) timer ?

Hexmicro
Thu Sep 13, 2018 3:27 pm
Hi,

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


mrburnette
Fri Sep 14, 2018 2:54 pm
… we’re you using libmaple from Leaflabs, the example would be like:
http://docs.leaflabs.com/static.leaflab … timer.html

I have not looked into how timers are abstracted in the Official STM Arduino core.

Ray


Hexmicro
Fri Sep 14, 2018 4:53 pm
Thanks, I’ve seen a few examples using other libraries but was hoping to find the same for the STM core. If I can’t find any or figure that core timer implementation out out, I will look at switching to a different library.

Cheers for the link.

Kev


ChrisMicro
Sat Sep 15, 2018 5:10 am
Thanks, I’ve seen a few examples using other libraries

Do you mean core instead of examples?

For the STM32GENERIC core we have some timer examples.


Hexmicro
Sat Sep 15, 2018 5:05 pm
Sorry, I meant I’ve seen code examples using hardware timers but that use different cores (I think that’s the right terminology?) eg some using LibMaple from Roger.

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


fpiSTM
Sat Sep 15, 2018 6:45 pm
Hi Hexmicro,

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
}


Hexmicro
Sat Sep 15, 2018 8:00 pm
Brilliant, thanks very much for that. I will try it out and come back.

Appreciate all the help.

Kev


Hexmicro
Sat Sep 15, 2018 9:02 pm
When I first tried I had a compile error (‘TIM4’ was not declared in this scope ) but no other errors so quickly realised the STM32L432KC I’m using doesn’t have a Timer 4 ! Changed your example code refs from TIM4 to TIM15 and it compiled without error :D :D

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


Hexmicro
Sun Sep 16, 2018 6:49 pm
Just to confirm, the example code ran fine on the Nucleo STM32L432 once I changed to use TIM15, LED flashing as expected. I’ll now play around with it and hopefully use it to learn how to use the timer for more practical uses.

Thanks

Kev


nikosx
Mon Sep 17, 2018 6:56 pm
Tested OK with a nucleo64 F030R8 !!!!
thank you !

nikosx
Mon Sep 17, 2018 6:58 pm
… with #define TIMER_BLINK TIM6 (Using timer6 on F030…) :)

nikosx
Tue Sep 18, 2018 7:51 am
Tested OK also in a nucleo F091RC with 2 timers used, one driving LED, 2nd a serial print event.. Finally after a long time a Timer example with INT handler that works and also easy to use !!! Waiting for the timer lib update…

MGeo
Mon Oct 01, 2018 9:34 am
Hello all,

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


MGeo
Mon Oct 01, 2018 10:27 am
I should add that the application I’m trying to port from STM32duino core uses TIM2 and TIM3 (input capture of pilot commands from an RC receiver) and also TIM4 (PWM outputs to quadcopter motor controllers). I’ll start a new thread to avoid cluttering this one up.

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


Leave a Reply

Your email address will not be published. Required fields are marked *