A programmable priority level of 0-15 for each interrupt. A higher level corresponds to a
lower priority
• stack top address
• reset routine location
• NMI ISR location
• Hard Fault ISR location.
Hardware interrupt selection
To configure the 23 lines as sources, use the following procedure:
• Configure the mask bits of the 23 interrupt lines (EXTI_IMR)
• Configure the bits of the interrupt lines (EXTI_RTSR and EXTI_FTSR)
If you’ve been on 23 lines, you’ll be able to verify the correct mode.
// Enable the IAR extensions for this source file. #pragma language=extended #pragma segment="CSTACK" // Forward declaration of the default fault handlers. void ResetISR(void); static void NmiSR(void); static void FaultISR(void); static void IntDefaultHandler(void); // The entry point for the application startup code. extern void __iar_program_start(void); extern void EXTI_Line0_IntHandler(void); extern void EXTI_Line6_IntHandler(void); // A union that describes the entries of the vector table. The union is needed // since the first entry is the stack pointer and the remainder are function // pointers. typedef union { void (*pfnHandler)(void); void * ulPtr; } uVectorEntry; // The vector table. Note that the proper constructs must be placed on this to // ensure that it ends up at physical address 0x0000.0000. __root const uVectorEntry __vector_table[] @ ".intvec" = { { .ulPtr = __sfe( "CSTACK" ) }, // The initial stack pointer ResetISR, // The reset handler NmiSR, // The NMI handler FaultISR, // The hard fault handler IntDefaultHandler, // MPU Fault Handler IntDefaultHandler, // Bus Fault Handler IntDefaultHandler, // Usage Fault Handler IntDefaultHandler, // Reserved IntDefaultHandler, // Reserved IntDefaultHandler, // Reserved IntDefaultHandler, // Reserved IntDefaultHandler, // SVCall Handler IntDefaultHandler, // Debug Monitor Handler IntDefaultHandler, // Reserved IntDefaultHandler, // PendSV Handler IntDefaultHandler, // SysTick Handler //External Interrupts IntDefaultHandler, // Window WatchDog IntDefaultHandler, // PVD through EXTI Line detection IntDefaultHandler, // Tamper and TimeStamps through the EXTI line IntDefaultHandler, // RTC Wakeup through the EXTI line IntDefaultHandler, // FLASH IntDefaultHandler, // RCC EXTI_Line0_IntHandler, // EXTI Line0 IntDefaultHandler, // EXTI Line1 IntDefaultHandler, // EXTI Line2 IntDefaultHandler, // EXTI Line3 IntDefaultHandler, // EXTI Line4 IntDefaultHandler, // DMA1 Stream 0 IntDefaultHandler, // DMA1 Stream 1 IntDefaultHandler, // DMA1 Stream 2 IntDefaultHandler, // DMA1 Stream 3 IntDefaultHandler, // DMA1 Stream 4 IntDefaultHandler, // DMA1 Stream 5 IntDefaultHandler, // DMA1 Stream 6 IntDefaultHandler, // ADC1, ADC2 and ADC3s IntDefaultHandler, // CAN1 TX IntDefaultHandler, // CAN1 RX0 IntDefaultHandler, // CAN1 RX1 IntDefaultHandler, // CAN1 SCE EXTI_Line6_IntHandler, // External Line[9:5]s IntDefaultHandler, // TIM1 Break and TIM9 IntDefaultHandler, // TIM1 Update and TIM10 IntDefaultHandler, // TIM1 Trigger and Commutation and TIM11 IntDefaultHandler, // TIM1 Capture Compare IntDefaultHandler, // TIM2 IntDefaultHandler, // TIM3 IntDefaultHandler, // TIM4 IntDefaultHandler, // I2C1 Event IntDefaultHandler, // I2C1 Error IntDefaultHandler, // I2C2 Event IntDefaultHandler, // I2C2 Error IntDefaultHandler, // SPI1 IntDefaultHandler, // SPI2 IntDefaultHandler, // USART1 IntDefaultHandler, // USART2 IntDefaultHandler, // USART3 IntDefaultHandler, // External Line[15:10]s IntDefaultHandler, // RTC Alarm (A and B) through EXTI Line IntDefaultHandler, // USB OTG FS Wakeup through EXTI line IntDefaultHandler, // TIM8 Break and TIM12 IntDefaultHandler, // TIM8 Update and TIM13 IntDefaultHandler, // TIM8 Trigger and Commutation and TIM14 IntDefaultHandler, // TIM8 Capture Compare IntDefaultHandler, // DMA1 Stream7 IntDefaultHandler, // FSMC IntDefaultHandler, // SDIO IntDefaultHandler, // TIM5 IntDefaultHandler, // SPI3 IntDefaultHandler, // UART4 IntDefaultHandler, // UART5 IntDefaultHandler, // TIM6 and DAC1&2 underrun errors IntDefaultHandler, // TIM7 IntDefaultHandler, // DMA2 Stream 0 IntDefaultHandler, // DMA2 Stream 1 IntDefaultHandler, // DMA2 Stream 2 IntDefaultHandler, // DMA2 Stream 3 IntDefaultHandler, // DMA2 Stream 4 IntDefaultHandler, // Ethernet IntDefaultHandler, // Ethernet Wakeup through EXTI line IntDefaultHandler, // CAN2 TX IntDefaultHandler, // CAN2 RX0 IntDefaultHandler, // CAN2 RX1 IntDefaultHandler, // CAN2 SCE IntDefaultHandler, // USB OTG FS IntDefaultHandler, // DMA2 Stream 5 IntDefaultHandler, // DMA2 Stream 6 IntDefaultHandler, // DMA2 Stream 7 IntDefaultHandler, // USART6 IntDefaultHandler, // I2C3 event IntDefaultHandler, // I2C3 error IntDefaultHandler, // USB OTG HS End Point 1 Out IntDefaultHandler, // USB OTG HS End Point 1 In IntDefaultHandler, // USB OTG HS Wakeup through EXTI IntDefaultHandler, // USB OTG HS IntDefaultHandler, // DCMI IntDefaultHandler, // CRYP crypto IntDefaultHandler, // Hash and Rng IntDefaultHandler, // FPU }; // This is the code that gets called when the processor first starts execution // following a reset event. Only the absolutely necessary set is performed, // after which the application supplied entry() routine is called. Any fancy // actions (such as making decisions based on the reset cause register, and // resetting the bits in that register) are left solely in the hands of the // application. void ResetISR(void) { // // Call the application's entry point. // __iar_program_start(); } // This is the code that gets called when the processor receives a NMI. This // simply enters an infinite loop, preserving the system state for examination // by a debugger. static void NmiSR(void) { // // Enter an infinite loop. // while(1) { } } // This is the code that gets called when the processor receives a fault // interrupt. This simply enters an infinite loop, preserving the system state // for examination by a debugger. static void FaultISR(void) { // // Enter an infinite loop. // while(1) { } } // This is the code that gets called when the processor receives an unexpected // interrupt. This simply enters an infinite loop, preserving the system state // for examination by a debugger. static void IntDefaultHandler(void) { // // Go into an infinite loop. // while(1) { } }
@ ".intvec"
Places the __vector_table table at the beginning of the section declared in the linker file. The file itself can be found here: #pragma segment="CSTACK" __sfe( "CSTACK" )
Writes a pointer to the top of the stack at the beginning of the flush. extern void EXTI_Line0_IntHandler(void); extern void EXTI_Line6_IntHandler(void);
extern void __iar_program_start(void);
This function is main (). The symbol itself can be redefined if a desire arises: //Definitions for SCB_AIRCR register #define SCB_AIRCR (*(unsigned volatile long*)0xE000ED0C) //acces to SCB_AIRCR #define SCB_AIRCR_GROUP22 0x05FA0500 //change priority data //Definitions for RCC_AHB1_ENR register #define RCC_AHB1_ENR (*(unsigned volatile long *)(0x40023830)) //acces to RCC_AHB1ENR reg #define RCC_AHB1_ENR_GPIOA 0x1 //GPIOA bitfield #define RCC_AHB1_ENR_GPIOC 0x4 //GPIOC bitfield #define RCC_AHB1_ENR_GPIOD 0x8 //GPIOD bitfield //Definitions for RCC_APB2_ENR register #define RCC_APB2_ENR (*(unsigned volatile long *)(0x40023844)) //acces to RCC_APB2ENR reg #define RCC_APB2_ENR_SYSCFG 0x4000 //SYSCFG bitfield //Definitions for GPIO MODE registers #define GPIOA_MODER (*(unsigned volatile long*)(0x40020000)) //acces to GPIOA_MODER reg #define GPIOC_MODER (*(unsigned volatile long*)(0x40020800)) //acces to GPIOC_MODER reg #define GPIOD_MODER (*(unsigned volatile long*)(0x40020C00)) //acces to GPIOD_MODER reg //GPIO ODR register definition #define GPIOD_ODR (*(unsigned volatile long*)(0x40020C14)) //acces to GPIOD_MODER reg #define GPIO_ODR_13PIN 0x2000 #define GPIO_ODR_14PIN 0x4000 //Bitfields definitions #define GPIO_MODER_0BITS 0x3 //Pin 0 mode bits #define GPIO_MODER_0IN 0x0 //Pin 0 input mode #define GPIO_MODER_6BITS 0x300 //Pin 6 mode bits #define GPIO_MODER_6IN 0x000 //Pin 6 input mode #define GPIO_MODER_13BITS 0xC000000 //Pin 13 mode bits #define GPIO_MODER_13OUT 0x4000000 //Pin 13 output mode #define GPIO_MODER_14BITS 0x30000000 //Pin 14 mode bits #define GPIO_MODER_14OUT 0x10000000 //Pin 14 output mode //GPIOC_PUPDR register definition #define GPIOC_PUPDR (*(unsigned volatile long*)(0x4002080C)) //acces to GPIOC_PUPDR reg #define GPIOC_PUPDR_6BITS 0x3000 //PC6 bitfield #define GPIOC_PUPDR_6PU 0x1000 //PC6 pull-up enable //SYSCFG_EXTIx registers definitions #define SYSCFG_EXTICR1 (*(unsigned volatile long*)0x40013808) //SYSCFG_EXTICR1 acces #define SYSCFG_EXTICR1_0BITS 0xF //EXTI 0 bits #define SYSCFG_EXTICR1_0PA 0x0 //EXTI 0 - port A #define SYSCFG_EXTICR2 (*(unsigned volatile long*)0x4001380C) //SYSCFG_EXTICR2 acces #define SYSCFG_EXTICR2_6BITS 0xF00 //EXTI 6 bits #define SYSCFG_EXTICR2_6PC 0x200 //EXTI 6 - port C //EXTI definitions #define EXTI_IMR (*(unsigned volatile long*)0x40013C00) //EXTI_IMR reg acces #define EXTI_LINE0 0x1 //LINE 0 definition #define EXTI_LINE6 0x40 //LINE 6 definition #define EXTI_RTSR (*(unsigned volatile long*)0x40013C08) //EXTI_RTSR reg acces #define EXTI_FTSR (*(unsigned volatile long*)0x40013C0C) //EXTI_FTSR reg acces #define EXTI_PR (*(unsigned volatile long*)0x40013C14) //EXTI_PR reg acces //NVIC registers and bits definitions #define NVIC_ISER0_REG (*(unsigned volatile long*)0xE000E100) //NVIC_ISER0 reg acces #define NVIC_ISER0_6VECT 0x40 //vect 6 definition #define NVIC_ISER0_23VECT 0x800000 //vect 30 definition #define NVIC_IPR0_ADD (0xE000E400) #define NVIC_IPR23_REG (*(unsigned volatile char*)(NVIC_IPR0_ADD + 23)) #define NVIC_IPR6_REG (*(unsigned volatile char*)(NVIC_IPR0_ADD + 6))
SCB_AIRCR = SCB_AIRCR_GROUP22;
This action must be performed only once. In complex projects using third-party libraries, it is worth checking this fact. Changing the division of priorities into groups can lead to incorrect operation of the firmware. //Enable SYSCFG , GPIO port A and D clocking RCC_AHB1_ENR |= RCC_AHB1_ENR_GPIOA|RCC_AHB1_ENR_GPIOC|RCC_AHB1_ENR_GPIOD; RCC_APB2_ENR |= RCC_APB2_ENR_SYSCFG;
//LED3 and LED5 initialization GPIOD_MODER = (GPIOD_MODER & (~GPIO_MODER_13BITS)) | GPIO_MODER_13OUT; GPIOD_MODER = (GPIOD_MODER & (~GPIO_MODER_14BITS)) | GPIO_MODER_14OUT;
//PA0 and PC6 pins initialization GPIOA_MODER = (GPIOA_MODER & (~GPIO_MODER_0BITS)) | GPIO_MODER_0IN; GPIOC_MODER = (GPIOC_MODER & (~GPIO_MODER_6BITS)) | GPIO_MODER_6IN;
//Enable PC6 pull-up GPIOC_PUPDR = (GPIOC_PUPDR & (~GPIOC_PUPDR_7BITS)) | GPIOC_PUPDR_6PU;
//Set up EXTI EXTI_RTSR |= EXTI_LINE0; EXTI_FTSR |= EXTI_LINE6; EXTI_IMR = EXTI_LINE0|EXTI_LINE6;
//EXTI to port connection SYSCFG_EXTICR1 = (SYSCFG_EXTICR1&(~SYSCFG_EXTICR1_0BITS)) | SYSCFG_EXTICR1_0PA; SYSCFG_EXTICR2 = (SYSCFG_EXTICR2&(~SYSCFG_EXTICR2_6BITS)) | SYSCFG_EXTICR2_6PC;
//Set interrupts priority NVIC_IPR6_REG = 0xF0; NVIC_IPR23_REG = 0x0;
//Enable interrupts NVIC_ISER0_REG |= NVIC_ISER0_6VECT | NVIC_ISER0_23VECT;
void EXTI_Line0_IntHandler(void) { //Clear interrupt EXTI_PR = EXTI_LINE0; //Turn on LED 3 GPIOD_ODR |= GPIO_ODR_13PIN; } void EXTI_Line6_IntHandler(void) { //Clear interrupt EXTI_PR = EXTI_LINE6; //Turn LED4 GPIOD_ODR |= GPIO_ODR_14PIN; while(1); }
//Definitions for SCB_AIRCR register #define SCB_AIRCR (*(unsigned volatile long*)0xE000ED0C) //acces to SCB_AIRCR #define SCB_AIRCR_GROUP22 0x05FA0500 //change priority data //Definitions for RCC_AHB1_ENR register #define RCC_AHB1_ENR (*(unsigned volatile long *)(0x40023830)) //acces to RCC_AHB1ENR reg #define RCC_AHB1_ENR_GPIOA 0x1 //GPIOA bitfield #define RCC_AHB1_ENR_GPIOC 0x4 //GPIOC bitfield #define RCC_AHB1_ENR_GPIOD 0x8 //GPIOD bitfield //Definitions for RCC_APB2_ENR register #define RCC_APB2_ENR (*(unsigned volatile long *)(0x40023844)) //acces to RCC_APB2ENR reg #define RCC_APB2_ENR_SYSCFG 0x4000 //SYSCFG bitfield //Definitions for GPIO MODE registers #define GPIOA_MODER (*(unsigned volatile long*)(0x40020000)) //acces to GPIOA_MODER reg #define GPIOC_MODER (*(unsigned volatile long*)(0x40020800)) //acces to GPIOC_MODER reg #define GPIOD_MODER (*(unsigned volatile long*)(0x40020C00)) //acces to GPIOD_MODER reg //GPIO ODR register definition #define GPIOD_ODR (*(unsigned volatile long*)(0x40020C14)) //acces to GPIOD_MODER reg #define GPIO_ODR_13PIN 0x2000 #define GPIO_ODR_14PIN 0x4000 //Bitfields definitions #define GPIO_MODER_0BITS 0x3 //Pin 0 mode bits #define GPIO_MODER_0IN 0x0 //Pin 0 input mode #define GPIO_MODER_6BITS 0x300 //Pin 6 mode bits #define GPIO_MODER_6IN 0x000 //Pin 6 input mode #define GPIO_MODER_13BITS 0xC000000 //Pin 13 mode bits #define GPIO_MODER_13OUT 0x4000000 //Pin 13 output mode #define GPIO_MODER_14BITS 0x30000000 //Pin 14 mode bits #define GPIO_MODER_14OUT 0x10000000 //Pin 14 output mode //GPIOC_PUPDR register definition #define GPIOC_PUPDR (*(unsigned volatile long*)(0x4002080C)) //acces to GPIOC_PUPDR reg #define GPIOC_PUPDR_6BITS 0x3000 //PC6 bitfield #define GPIOC_PUPDR_6PU 0x1000 //PC6 pull-up enable //SYSCFG_EXTIx registers definitions #define SYSCFG_EXTICR1 (*(unsigned volatile long*)0x40013808) //SYSCFG_EXTICR1 acces #define SYSCFG_EXTICR1_0BITS 0xF //EXTI 0 bits #define SYSCFG_EXTICR1_0PA 0x0 //EXTI 0 - port A #define SYSCFG_EXTICR2 (*(unsigned volatile long*)0x4001380C) //SYSCFG_EXTICR2 acces #define SYSCFG_EXTICR2_6BITS 0xF00 //EXTI 6 bits #define SYSCFG_EXTICR2_6PC 0x200 //EXTI 6 - port C //EXTI definitions #define EXTI_IMR (*(unsigned volatile long*)0x40013C00) //EXTI_IMR reg acces #define EXTI_LINE0 0x1 //LINE 0 definition #define EXTI_LINE6 0x40 //LINE 6 definition #define EXTI_RTSR (*(unsigned volatile long*)0x40013C08) //EXTI_RTSR reg acces #define EXTI_FTSR (*(unsigned volatile long*)0x40013C0C) //EXTI_FTSR reg acces #define EXTI_PR (*(unsigned volatile long*)0x40013C14) //EXTI_PR reg acces //NVIC registers and bits definitions #define NVIC_ISER0_REG (*(unsigned volatile long*)0xE000E100) //NVIC_ISER0 reg acces #define NVIC_ISER0_6VECT 0x40 //vect 6 definition #define NVIC_ISER0_23VECT 0x800000 //vect 30 definition #define NVIC_IPR0_ADD (0xE000E400) #define NVIC_IPR23_REG (*(unsigned volatile char*)(NVIC_IPR0_ADD + 23)) #define NVIC_IPR6_REG (*(unsigned volatile char*)(NVIC_IPR0_ADD + 6)) void EXTI_Line0_IntHandler(void); void EXTI_Line6_IntHandler(void); void main() { //NVIC SCB_AIRCR = SCB_AIRCR_GROUP22; //Enable SYSCFG , GPIO port A,C and D clocking RCC_AHB1_ENR |= RCC_AHB1_ENR_GPIOA|RCC_AHB1_ENR_GPIOC|RCC_AHB1_ENR_GPIOD; RCC_APB2_ENR |= RCC_APB2_ENR_SYSCFG; //LED3 and LED5 initialization GPIOD_MODER = (GPIOD_MODER & (~GPIO_MODER_13BITS)) | GPIO_MODER_13OUT; GPIOD_MODER = (GPIOD_MODER & (~GPIO_MODER_14BITS)) | GPIO_MODER_14OUT; //PA0 and PC6 pins initialization GPIOA_MODER = (GPIOA_MODER & (~GPIO_MODER_0BITS)) | GPIO_MODER_0IN; GPIOC_MODER = (GPIOC_MODER & (~GPIO_MODER_6BITS)) | GPIO_MODER_6IN; //Enable PC7 pull-up GPIOC_PUPDR = (GPIOC_PUPDR & (~GPIOC_PUPDR_6BITS)) | GPIOC_PUPDR_6PU; //Set up EXTI EXTI_RTSR |= EXTI_LINE0; EXTI_FTSR |= EXTI_LINE6; EXTI_IMR = EXTI_LINE0|EXTI_LINE6; //EXTI to port connection SYSCFG_EXTICR1 = (SYSCFG_EXTICR1&(~SYSCFG_EXTICR1_0BITS)) | SYSCFG_EXTICR1_0PA; SYSCFG_EXTICR2 = (SYSCFG_EXTICR2&(~SYSCFG_EXTICR2_6BITS)) | SYSCFG_EXTICR2_6PC; //Set interrupts priority NVIC_IPR6_REG = 0xF0; NVIC_IPR23_REG = 0x00; //Enable interrupts NVIC_ISER0_REG |= NVIC_ISER0_6VECT | NVIC_ISER0_23VECT; while(1) { } } void EXTI_Line0_IntHandler(void) { //Clear interrupt EXTI_PR = EXTI_LINE0; //Turn on LED 3 GPIOD_ODR |= GPIO_ODR_13PIN; } void EXTI_Line6_IntHandler(void) { //Clear interrupt EXTI_PR = EXTI_LINE6; //Turn LED4 GPIOD_ODR |= GPIO_ODR_14PIN; while(1); }
Source: https://habr.com/ru/post/218825/
All Articles