Interrupts on STM32F4 - Page 1
Forum section: electronics / general

author: farsi
author_rank: Regular Contributor
timestamp: November 18, 2015, 02:50:09 pm
content: Hi,I am a bit puzzled on how to write interrupt functions for the STM32F4. I copy and pasted some code from examples on the net, and I think to understand the basic setup ofNVIC_Init(&NVIC_InitStructure);But still, I don't understand exactly how to write interrupt handlers for UART and EXTI events.How can I improve learning these things (books, examples, ... ) ?Thanks!

author: Jeroen3
author_rank: Super Contributor
timestamp: November 18, 2015, 06:48:39 pm
content: With the manuals:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CIHIGCIF.htmlBut this is the basics:An interrupt originates from the peripheral, to work the peripheral needs power and clock. This is fixed in RCC, but you'd probably already knew that.Then the interrupt source must be enabled in the peripheralsinterrupt control register. Such as USART_ISR.Next the NVIC must have the interrupt channel of the peripheral enabled.See CMSIShttp://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CIHIGCIF.htmlYou probably have something similar available.Also in the NVIC you can adjust the preemptive priority. Since arm allows higher priority interrupts to start inside lower priority interrupts. This gets you nested interrupts, and you should be aware of this. For example, RESET and HARDFAULT always executes. The order of the table is the default priority iirc. Watch your stack.When you didn't remap the interrupt vector table, it will still be at the top of your bootable region. This is a lookup table with vectors (function pointers) to where the interrupt routine code is located, this can be in RAM if you've put them there to make things fast. Your (assembly) startup file should have this list, with WEAK defined functions. Weak means that they are defined, but they can be overridden. Also there is a infinite loop to catch any interrupts that fired, but don't have a valid address in the table. (eg: still weak)In this list you find names "USART1_IRQHandler" or something more generic.Simply creating the function will do the work of the vector table.Code:void USART1_IRQHandler(void) {//Check if interrupt was because data is receivedif (USART_GetITStatus(USART1, USART_IT_RXNE)) {//Do your stuff here//Clear interrupt flagUSART_ClearITPendingBit(USART1, USART_IT_RXNE);}}In the function you then have to checkwhyyou are in the interrupt. There may be 254 interrupt channels, the number of wires going to the nvic are limited and peripheral interrupts are often grouped. You check this by reading the peripheral flags.Then you do your stuff, for that flag.Next you clear the peripheral flag, to notify you're done. This is done by writing a 1 to that bit. Simply do something like USART_ISR |= (1<<bitnumber); Or use driver. "USART_ClearITPendingBit".Then you return.Now what happens when you do not clear the status flag OR'd to the nvic? Well, you'll end up in an infinite loop of the interrupt, with any higher priority as nested interrupts.You can also fire the interrupt from software using the NVIC, but the USART will not have its status flag set.Refer to the "STM32F3xxx and STM32F4xxx Cortex-M4 programming manual" for details about the nvic used in the f4's.Obviously, this is totally redundant information that can be found if you look right for websites of universities and such... But hey, It's my thousandth post, why not make it useful?

author: richardman
author_rank: Frequent Contributor
timestamp: November 19, 2015, 02:32:19 am
content: Quote from: farsi on November 18, 2015, 02:50:09 pmIt's a multiple step process:hook up the vector table entry to an interrupt handlerset priority in the NVICenable interrupt in the NVICfor shared interrupts, make sure to check for the correct interrupt bits in the interrupt handlerfor EXTI, you need to also enable SYSCFG

author: westfw
author_rank: Super Contributor
timestamp: November 19, 2015, 06:22:58 am
content: QuoteNote that this is USUALLY done by creating a normal C function whose name matches the pre-defined handler name in some startup file.Unlike many architectures, cortex M interrupt handlers to not need to be tagged with any special "attributes" to save additional registers or flags; that's all done by the hardware (whether you'd want it to or not!)

author: richardman
author_rank: Frequent Contributor
timestamp: November 19, 2015, 06:43:09 am
content: Quote from: westfw on November 19, 2015, 06:22:58 amYes, interrupt handlers for Cortex-M are just plain C functions.How to do this part is compiler vendor specific. For us (ImageCraft), you include a copy of the vector file, and just modify as needed. Keil wants you to provide a "non-weak" definition for the handlers (if you don't, then their "weak" handlers will be linked in by default.

author: farsi
author_rank: Regular Contributor
timestamp: November 19, 2015, 01:11:24 pm
content: Thanks, how nice! Wow, looks like I'll have some options to explore now. One reason I was asking is that experimenting on a Windows PC without Keil is quite difficult. Also, working with STM32 feels like seeing the trees without seeing the forrests. Well, maybe I played a bit too much with gcc and Arduino last year (which I liked, but this ARM cores are rather popular for "professional" embedded systems)

author: dannyf
author_rank: Super Contributor
timestamp: November 21, 2015, 07:04:31 pm
content: QuoteHandlers are generally defined in the start-up file -> but they can be device / tool specific.The start-up files themselves can be assembly (typically) or C.

author: cncjerry
author_rank: Unknown
timestamp: November 23, 2015, 01:30:11 am
content: Go to the site if you haven't already:http://stm32f4-discovery.com/He also has free GCC compiler/toolchain instructions that really work. His libraries all work if you have the latest versions. What I liked about his code examples was that all the source was there and he seemed to keep it simple. The STM32F4 learning curve is ridiculously steep compared to arduino but the performance is far worth it. It takes a lot of persistence to get your first working code but gets easier. I gave up several times and went back to arduino for later projects but now that I got it all working I'll stick with the F4. If you drift over to the nucleo boards stay away from mbed and learn how to program it using the toolchain.

author: mikerj
author_rank: Super Contributor
timestamp: November 23, 2015, 01:13:02 pm
content: Quote from: richardman on November 19, 2015, 02:32:19 amA peripheral may also have it's own interrupt enable bit: e.g. the DMA would need the TEIE bit set, as well as the appropriate NVIC enable bit. Some peripheral only require the NVIC bit to be set e.g. Systick.

author: farsi
author_rank: Regular Contributor
timestamp: November 23, 2015, 02:33:20 pm
content: QuoteThat is an impressive collection of blog posts. On quick glance, he uses the free Keil toolchain and CooCox for the first posts.One of his latest tweets was 5k unique visitors a day. So, I guess I am not the only one who is taking the jump from Arduino to MCUs with more features.