Author Topic: How do interrupts work stm32f0 discovery board, coming from PIC background  (Read 1567 times)

0 Members and 1 Guest are viewing this topic.

Offline EteslaTopic starter

  • Regular Contributor
  • *
  • Posts: 149
  • Country: us
Hi all,
I come from a PIC microcontroller background. On a PIC, in C, you use a function called "void __interrupt () isr(void)" to catch all interrupts. You then have a bunch of if statements inside of this function to determine which interrupt has occurred. As far as I understand from some quick googling, this is not how interrupts work with these newfangled arm micros. It seems as though each possible interrupt triggers its own function to be called, like a timer1 overflow interrupt would have a function associated with it called something like tmr1Overflow_handler(), and an ADC ready interrupt would have a function called something like ADCReady_handler(). My question is twofold. Am I understanding this correctly, and how do you know what these pre-associated functions are named to begin with? I learn best through examples, so if someone would be willing to write out the C code to set up a timer compare match interrupt or something super simple like that, that would be great. Thank you in advance!
 

Offline jhpadjustable

  • Frequent Contributor
  • **
  • Posts: 295
  • Country: us
  • Salt 'n' pepper beard
Quote
this is not how interrupts work with these newfangled arm micros
That's a library layer you can often mostly ignore, if you would prefer. Take a look at the assembler startup file for your build environment or skeleton project. In a project generated by STM32CubeMX for an F103, for example, the vector table is placed at the correct flash address by the linker script and looks a bit like:
Code: [Select]
  .word _estack
  .word Reset_Handler
  .word NMI_Handler
  .word HardFault_Handler
  .word MemManage_Handler
  .word BusFault_Handler
  .word UsageFault_Handler
...
  .word USB_HP_CAN1_TX_IRQHandler
  .word USB_LP_CAN1_RX0_IRQHandler
  .word CAN1_RX1_IRQHandler
  .word CAN1_SCE_IRQHandler
  .word EXTI9_5_IRQHandler
  .word TIM1_BRK_IRQHandler
  .word TIM1_UP_IRQHandler
  .word TIM1_TRG_COM_IRQHandler
  .word TIM1_CC_IRQHandler
  .word TIM2_IRQHandler
  .word TIM3_IRQHandler
  .word TIM4_IRQHandler
  .word I2C1_EV_IRQHandler
...
where each name refers to a void function returning void, no pragmas required:
Code: [Select]
void
TIM1_TRG_COM_IRQHandler(void)
{
  if (TIM1->DIFR & CC1IF) { // made up names just for illustration
    tmr1CaptureCompare_Handler();
    TIM1->DIFR = CC1IF;
  }
    ...
}
The documentation for ST's HAL for the 32F0 is available as ST document UM1785. Each HAL chapter lists the names of the callbacks which it allows you to implement, e. g. HAL_TIM_IC_CaptureCallback(). You could also provide your own implementation for the IRQHandler functions if you want to do it by hand, the old fashioned way. I usually use the ST HAL, because it's free, saves a bit of effort, and it hasn't gotten too much in the way yet. :)
"There are more things in heaven and earth, Arduino, than are dreamt of in your philosophy."
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Google for 'stm32f0 timer interrupt example' - there are many responses.

There is no comparison between the interrupt structure of a PIC and that of the modern ARM.  The good news is that you don't have to tell the compiler that the function is an interrupt handler on these newer Cortex chips.  All interrupt handlers are just void functions with void parameters.

http://eleceng.dit.ie/frank/arm/BareMetalSTM32F0Discovery/timerirq.html

Notice in the vector table at the bottom of the page that all vectors are branching to DefaultHandler + 1 (which isn't shown) except for the active vector that points to Timer1ISR.  This means every time you add an interrupt handler, you have to modify the startup code.

Sometimes the vector table has code to branch to actual functions for every interrupt, each function has a specific name.  Later on in the code, all of those functions will be defined at a single entry point like DefaultHandler except that they are labeled as 'weak'.  The target address in the vector can be overridden at link time when a real handler is defined.  As a result, you never have to modify the startup code, the existence of a named function will override the 'weak' definition.
 

Offline emece67

  • Frequent Contributor
  • **
  • !
  • Posts: 614
  • Country: 00
.
« Last Edit: August 19, 2022, 02:28:50 pm by emece67 »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf