STM32F4 External interrupts

STM32F4 External interrupts

Each STM32F4 device has 23 external interrupt or event sources.

They are split into 2 sections.

First interrupt section is for external pins (P0 to P15) on each port,

and other section is for other events, like RTC interrupt, Ethernet interrupt, USB interrupt and so on.

GPIO as Interrupt

Interrupt lines

I will show now how to configure GPIO pin to be an interrupt and how to handle it in your code with CMSIS function.

In section one (GPIOs) we have 16 interrupt lines.

They are line0 to line15 and they also represent pin number.

This means, PA0 is connected to Line0and PA13 is connected to Line13.

You have to know that PB0 is also connected to Line0 and PC0 also and so on.

This is for all pins on board, All Px0 (where x is GPIO name) pins are connected to Line0

and let’s say all Px3 are connected to Line3 on the Interrupt channel.

All pins with same number are connected to line with same number.

They are multiplexed to one line.

IMPORTANT: You can not use two pins on one line simultaneously:

  • PA0 and PB0 and PC0 and so on, are connected to Line0,
    so you can use only one pin at one time to handle interrupt from there.
  • PA0 and PA5 are connected to different lines, they can be used at the same time.

Each line can trigger an interrupt on rising, falling or rising_falling enge on signal.

Interrupt handlers

OK, now you have selected your pin you want to use.

But you have to handle interrupt somehow.

This process is described below.

STM32F4 has 7 interrupt handlers for GPIO pins.

They are in table below:

Irq Handler Description
EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0
EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1
EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2
EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3
EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4
EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9
EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15

This table show you which IRQ you have to set for NVIC (first column)

and function names to handle your interrupts (second column).

You have probably also figured, that only lines 0 to 4 have own IRQ handler.

Yes, lines 5-9 have the same interrupt handler and this is also for lines 10 to 15.

After you set settings for EXTI, you have to add them into NVIC.

Example

In this example, we will set pin PD0 and PB12 to be a GPIO interrupts.

Code below should be well documented to understand how it works.

/**
 *    External interrupts example
 *
 *    @author     Tilen Majerle
 *    @email        [email protected]
 *    @website    http://stm32f4-discovery.com
 *    @ide        Keil uVision 5
 */
#include "stm32f4xx.h"
#include "stm32f4xx_exti.h"
#include "stm32f4xx_syscfg.h"
#include "misc.h"

/* Configure pins to be interrupts */
void Configure_PD0(void) {
    /* Set variables used */
    GPIO_InitTypeDef GPIO_InitStruct;
    EXTI_InitTypeDef EXTI_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;

    /* Enable clock for GPIOD */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    /* Enable clock for SYSCFG */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Set pin as input */
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOD, &GPIO_InitStruct);

    /* Tell system that you will use PD0 for EXTI_Line0 */
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);

    /* PD0 is connected to EXTI_Line0 */
    EXTI_InitStruct.EXTI_Line = EXTI_Line0;
    /* Enable interrupt */
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    /* Interrupt mode */
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    /* Triggers on rising and falling edge */
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    /* Add to EXTI */
    EXTI_Init(&EXTI_InitStruct);

    /* Add IRQ vector to NVIC */
    /* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
    /* Set priority */
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
    /* Set sub priority */
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
    /* Enable interrupt */
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    /* Add to NVIC */
    NVIC_Init(&NVIC_InitStruct);
}

void Configure_PB12(void) {
    /* Set variables used */
    GPIO_InitTypeDef GPIO_InitStruct;
    EXTI_InitTypeDef EXTI_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;

    /* Enable clock for GPIOB */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    /* Enable clock for SYSCFG */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Set pin as input */
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Tell system that you will use PB12 for EXTI_Line12 */
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12);

    /* PB12 is connected to EXTI_Line12 */
    EXTI_InitStruct.EXTI_Line = EXTI_Line12;
    /* Enable interrupt */
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    /* Interrupt mode */
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    /* Triggers on rising and falling edge */
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    /* Add to EXTI */
    EXTI_Init(&EXTI_InitStruct);

    /* Add IRQ vector to NVIC */
    /* PB12 is connected to EXTI_Line12, which has EXTI15_10_IRQn vector */
    NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
    /* Set priority */
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
    /* Set sub priority */
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
    /* Enable interrupt */
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    /* Add to NVIC */
    NVIC_Init(&NVIC_InitStruct);
}

/* Set interrupt handlers */
/* Handle PD0 interrupt */
void EXTI0_IRQHandler(void) {
    /* Make sure that interrupt flag is set */
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
        /* Do your stuff when PD0 is changed */

        /* Clear interrupt flag */
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}

/* Handle PB12 interrupt */
void EXTI15_10_IRQHandler(void) {
    /* Make sure that interrupt flag is set */
    if (EXTI_GetITStatus(EXTI_Line12) != RESET) {
        /* Do your stuff when PB12 is changed */

        /* Clear interrupt flag */
        EXTI_ClearITPendingBit(EXTI_Line12);
    }
}

int main(void) {
    /* System init */
    SystemInit();
    /* Configure PD0 as interrupt */
    Configure_PD0();
    /* Configure PB12 as interrupt */
    Configure_PB12();

    while (1) {

    }
}
时间: 2024-08-19 01:09:18

STM32F4 External interrupts的相关文章

STM32F4 External event -- WFE 待机模式

The STM32F4xx are able to handle external or internal events in order to wake up the core (WFE). The wakeup event can be generated either by: (I've removed normal external interrupt mode details) or configuring an external or internal EXTI line in ev

STM32F4启动代码分析

;******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** ;* File Name : startup_stm32f40_41xxx.s ;* Author : MCD Application Team ;* @version : V1.4.0 ;* @date : 04-August-2014 ;* Description : STM32F40xxx/41xxx devices vector

STM32F4XX devices vector table for EWARM toolchain.

;/******************** (C) COPYRIGHT 2015 STMicroelectronics ******************** ;* File Name : startup_stm32f4xx.s ;* Author : MCD Application Team ;* Version : V2.3.2 ;* Date : 26-June-2015 ;* Description : STM32F4xx devices vector table for EWARM

linux设备驱动归纳总结(六):1.中断的实现

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 一.什么是中断 中断分两种: 1)中断,又叫外部中断或异步中断,它的产生是由于外设向处理器发出中断请求.其中外部中断也有两种,这是由配置寄存器设定的:普通中断请求(IRQ)和快速中断请求(FIQ).一般地,linux下很少使用快速中断请求. 2)异常,又叫内部中断或同步中断,它的产生是由于处理器执行指令出错. 在以下的内容我

STM32启动文件详细解析(V3.5.0) 以:startup_stm32f10x_hd.s为例

我用的是IAR,这个貌似是MDK的,不过很有用,大家可以看一下 ;* 文件名 : startup_stm32f10x_hd.s ;* 库版本 : V3.5.0 ;* 说明: 此文件为STM32F10x高密度设备的MDK工具链的启动文件 ;* 该模块执行以下操作: ;* -设置初始堆栈指针(SP) ;* -设置初始程序计数器(PC)为复位向量,并在执行main函数前初始化系统时钟 ;* -设置向量表入口为异常事件的入口地址 ;* -复位之后处理器为线程模式,优先级为特权级,堆栈设置为MSP主堆栈

stm32f407启动文件分析

; Amount of memory (in bytes) allocated for Stack; Tailor this value to your application needs; <h> Stack Configuration; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>; </h> Stack_Size EQU 0x00000400      ;EQU定义栈空间的大小,栈空间由编译器自动分配变量所占

基于tiny4412的Linux内核移植 -- MMA7660驱动移植(九)

作者信息 作者: 彭东林 邮箱:[email protected] QQ:405728433 平台简介 开发板:tiny4412ADK + S700 + 4GB Flash 要移植的内核版本:Linux-4.4.0 (支持device tree) u-boot版本:友善之臂自带的 U-Boot 2010.12 (为支持uImage启动,做了少许改动) busybox版本:busybox 1.25 交叉编译工具链: arm-none-linux-gnueabi-gcc (gcc version 4

Methods and systems to control virtual machines

Methods and systems are provided to control the execution of a virtual machine (VM). A VM Monitor (VMM) accesses VM Control Structures (VMCS) indirectly through access instructions passed to a processor. In one embodiment, the access instructions inc

STM32工程中出现 error: A1163E: Unknown opcode R0, , expecting opcode or Macro错误分析及处理

最近测试以前的一个程序,一般都是打开以前写的程序修改参数直接测试 但是发现以前的编译后出现错误. 奇怪了,以前的出现都是调试好了的啊,一般都是没有错误的,迅速找问题 跳转到错误代码行 代码区域 1 Heap_Size EQU 0x00000000 2 3 AREA HEAP, NOINIT, READWRITE, ALIGN=3 4 __heap_base 5 Heap_Mem SPACE Heap_Size 6 __heap_limit 7 8 PRESERVE8 9 THUMB ;指定为TH