2 years, 2 months ago.

How to get interrupt from pwmout

Hi All,

Been playing with microcontrollers for a while but very new to mbed.

Just ordered one of these and would like to use mbed on it. In fact, in PlatformIO, mbed is the only option for programming this board.

In Arduino it is possible to set up a PWM output on a pin and have an overflow (i.e. every time one pulse is finished) trigger an ISR. Admittedly you have to play with registers to do that, but on an 8 bit AVR processor it's not that difficult. I was wondering, given that mbed has a lot more high level functionality than Arduino/AVR, if the same thing is doable in mbed in a more elegant and efficient manner.

I've looked at the pwmout function but that doesn't seem to have an option to attach a callback. There is an interrupt enable and ISR enable in the register definitions for the timer(s) that can do PWM output, so it would seem it is possible. I was hoping that there might be an easier way than register manipulation to get this happening. Or do I have to be anointed into the mysteries of C++ to be able to understand any of this.

As a bit of background. I'm trying to create a PPM output stream using PWM, so the ISR set's the pulse length (period) of the next PWM output pulse. All this requires (in the ISR) is incrementing an index to an array, and setting the count max (modulo) to the value pointed to by the index. Just a few instructions, so the ISR is very fast. The array values are updated asynchronously by the rest of the program by reading analog and digital inputs, doing some manipulations, and setting the output value in the array. But most of you probably already knew this.

Thanks, Ian

1 Answer

2 years, 2 months ago.

Ian -

The platform you are working with is an STM32F303K8T6 - right? Your current approach is based on the PWM functionality, but I think you can easily do what you want using the "one pulse mode" (OPM) of any of the MCU’s timers. This timer mode is described in Section 2.6 of AN4013, "STM32 cross-series timer overview". You can find example code in the STM32Cube F3 firmware examples:


The two basic timers are a good choice (TIM 6 or TIM 7) for this application, as they are not used by mbed and are not assigned to any specific pins. You can set the desired output pin when you fire the timer to start the pulse. Toggle the output pin, update the pulse length and re-start the timer in the IRQ handler.

The register definitions you will need are in RM0316, the Reference Manual for the MCU.

The IRQn’s are defined in "stm32f303x8.h":

TIM6_DAC1_IRQn for TIM6 and TIM7_DAC2_IRQn for TIM7.

The default IRQHandler function names are defined in "startup_stm32f303x8.s":

TIM6_DAC1_IRQHandler for TIM6 and TIM7_DAC2_IRQHandler for TIM7.

J. Roth

Thanks for the detailed reponse @j roth, much appreciated.

I have discovered RM0316 and have been studying it, that's where I learned that a timer in PWM mode can generate an interrupt. However I don't know where to find the other files you mentioned. I'm assuming they are libraries (or in libraries) somewhere but I haven't delved deeply enough into mbed yet to find them.

I have also downloaded the stm32cubeF3 but have not yet worked out how to install or use it. I'm finding the whole stm32 ecosystem a tad confusing I have to say, more complex than your basic Arduino stuff which is a doddle by comparison. I feel like I've stepped out of a Piper Cub and into a Jumbo jet!

The above notwithstanding, I am looking for a simpler approach using high level instructions rather than register manipulation. I've had another look at the API functions, this time bearing in mind your advice about timers, and found that maybe the timeout function might work. The documentation says that it is suitable for time periods from microseconds up. If I can set the period of the next timeout from within the ISR (or poll a switch to do it in the endless loop) it might do what I want it to do. I'll do some experimenting and report progress.

Thanks again, Ian

posted by Ian Harris 08 Sep 2018