cancel
Showing results for 
Search instead for 
Did you mean: 

Understand how interrupts work

Francesco_
Associate II

Hi all,

I'm trying to figure out how to handle an interrupt. In particular I would like to handle an interrupt without using the HAL library.

I want to handle the uart interrupt in reception:

RXNEIE enabled: when the data is received an interrupt occours and RXNE = 1.

If I understand correctly, when an interrupt occurs, instructions are executed in the interrupt vector (NVIC) but I cannot understand how to manage this register.

In detail, how should the code that allows me to check the RXNE bit after the interrupt occur?

8 REPLIES 8

You did not tell us, which peripheral and which STM32, but maybe this little example ISR (Interrupt Service Routine) in https://community.st.com/s/question/0D50X0000BVpldhSQB/how-to-have-continuous-uart-burst-transmit-while-ensuring-receive-works- will help with understanding.

JW

Francesco_
Associate II

I'm using a STM32F103RB Nucleo and the peripheral is UART2, now i reading your example.

Francesco_
Associate II

@Community member​ how does "void USART1_IRQHandler(void)" work? What happens at the register level?

The processor has a vector table with the address of this function, when the interrupt occurs this function gets called by the processor, and when complete execution resumes where it left off. See stm32f1xx_startup.s

This all seems very basic micro-controller stuff, might I suggest something along the lines of the Joseph Yiu Essential Book on the Cortex-Mx

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Francesco_
Associate II

@Community member​ if it is a function that contains the address of the vector table why is it called USART1_IRQHandler? Is there a vector table only usart1?

The vector *table* has multiple entries, one for each interrupt source managed by the NVIC

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler
 
                ; External Interrupts
                DCD     WWDG_IRQHandler            ; Window Watchdog
                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler          ; Tamper
                DCD     RTC_IRQHandler             ; RTC
                DCD     FLASH_IRQHandler           ; Flash
                DCD     RCC_IRQHandler             ; RCC
                DCD     EXTI0_IRQHandler           ; EXTI Line 0
                DCD     EXTI1_IRQHandler           ; EXTI Line 1
                DCD     EXTI2_IRQHandler           ; EXTI Line 2
                DCD     EXTI3_IRQHandler           ; EXTI Line 3
                DCD     EXTI4_IRQHandler           ; EXTI Line 4
                DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                DCD     ADC1_2_IRQHandler          ; ADC1_2
                DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                DCD     TIM2_IRQHandler            ; TIM2
                DCD     TIM3_IRQHandler            ; TIM3
                DCD     TIM4_IRQHandler            ; TIM4
                DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                DCD     SPI1_IRQHandler            ; SPI1
                DCD     SPI2_IRQHandler            ; SPI2
                DCD     USART1_IRQHandler          ; USART1
                DCD     USART2_IRQHandler          ; USART2
                DCD     USART3_IRQHandler          ; USART3
                DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                DCD     RTC_Alarm_IRQHandler        ; RTC Alarm through EXTI Line
                DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
__Vectors_End

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Look at your toolchain. You have somewhere a file like this https://github.com/STMicroelectronics/STM32CubeF1/blob/master/Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xb.s , and the toolchain is set up so that it compiles it and links to your project. IDEs tend to hide this detail into some "magic" they perform, but if you look closer, you'll find it. You don't need to do anything with this file, but that's where the interrupt vector table is, under g_pfnVectors . (There are also prototype ISRs there, doing nothing and tagged "weak"; you override any of them by writing a "true" ISR in your code).

The ordering in that table is not random, it's given by hardware, read the Interrupts chapter in RM0008.\

For the interrupt to be called, you need not only to enable it in the peripheral (here by setting the RXNEIE bit in USART), but also in the NVIC module; you do that by calling

NVIC_EnableIRQ(USART1_IRQn);

(that's a nothing else just a write to a bitfield in one of the NVIC registers, too, but it's not worth going to the details for now, just use it as it is).

The example I gave is for 'F0 and the USART there is slightly different than the one in 'F1 (the overrun interrupt is cleared somewhat differently, by reading the data register), so you can't use it as it is now - read the USART chapter in RM0008 for the details.

JW

turboscrew
Senior III

Maybe this is of help.

https://github.com/turboscrew/blue_pill_init

Search for "init_usart1".

There the USART is used in a "terminal" way - no predefined messages (message lengths).

I did use stdint.h, though, but that's the only file not written by me.

Everything (except vectors in start.S) are in one file. Terrible for a program structure, but convenient for searching without downloading.

Oh, and in Cortex-M series, the interrupts work in a half-different way from any other architectures. In Cortex-A series the interrupts work in a totally different way from any other architectures. I highly recommend checking out ARM ARM (the ARM Architecture Reference Manual for yout chip - probably ARMv7-M.