How could I create an interrupt for a blue pill from scratch?
I do not want to use any sort of special library. Also, I use Keil IDE, thus, by "building from scratch" I refer rather not to use any extra library than to assemble the project without the help of an IDE.
I tried to find resources, but no success. Could anybody help me and at least provide some information/bibliography for me? I would be grateful.
Moreover, by "strange library" I mean any other library than the stmf32f1xx.h header. I would like to fire an interrupt when one of the pins' input value toggles. In order to do this, on AVR MCUs it was very simple as long as only a few register values should be changed. Unfortunately, I don't know how an interrupt within an ARM MCU functions and in which registers should I write what values.
Also, a better understanding of the ARM MCU's interrupt mechanism would make me more prepared for tackling debouncing issues.
I am not going to take you entirely literally when you mandate "no libraries", because no one who wants to get work done and knows what they are doing on Cortex-M would do that - and I will assume at least that you will use the CMSIS - a common API provided for all ARM Cortex-M devices, and which makes your code more, not less portable.
All the CMSIS code is provided as source, rather than static library, so there is nothing hidden and if you chose not to use it, you can see how it works and replicate that functionality (needlessly) if you wish.
In the CMSIS default implementations are provided as "weak-links" that can be overridden by user code simply by defining a function of the pre-defined name to override the default. The default implementation is generally an infinite loop - so that unhandled interrupts are "trapped" so you can intervene with your debugger or wait for a watchdog reset for example.
The Cortex-M core interrupt handlers and exception handlers have common names across all Cortex-M parts:
Peripheral interrupt handlers have names defined by the vendor, but the naming convention is
<interrupt_source>_IRQHandler
. For example on STM32F1xxEXTI0_IRQHandler
is the shared external interrupt assigned to bit zero of GPIO ports.To implement an CMSIS interrupt handler, all you need do is:
There other are things you might do such as assign the interrupt priority scheme (the split between preempt priorities and subpriorities), but lets keep it simple for the time being.
Because it is ubiquitous to all Cortex-M parts, and because it is useful in almost any non-trivial application an illustration using the SYSTICK interrupt is useful as a starting point.
SysTick_Config()
is another CMSIS function. In core_cm3.h it looks like this:So let's say you have a external interrupt source on the falling edge of GPIOA pin 0, then you would use the STM32 EXTI0 interrupt. The minimal handler would look like:
Setting up the EXTI requires enabling the GPIO and the EXTI itself as well as the NVIC:
The peripheral registers and structures are defined in stm32f10weakx.h, and the "weak" default peripheral handlers to be overridden are in startup_stm32f10x_cl.s for your specific part. Any handlers you override must match these symbol names exactly.
All the peripheral interrupt sources and how to configure them is defined un the ST Reference Manual RM0008.
All the Cortex-M core specific stuff - systtick, NVIC, exception handlers etc. is provided by ARM at https://developer.arm.com/ip-products/processors/cortex-m/cortex-m3
CMSIS for CM3 is documented at https://developer.arm.com/documentation/dui0552/a/