stm32学习笔记——按键(外部中断)

stm32学习笔记——按键(外部中断)

目的:使用外部中断方式触发按键,会使用外部中断的操作

配置文件:#include "stm32f10x_gpio.h" 

  #include "stm32f10x_rcc.h"

#include "stm32f10x_exti.h" 

寄存器:EXTI_IMR:13位保留,低19位对应19个中断线编号,置1时开放该线上外部 中断

EXTI_EMR:高13位保留,低19位对应19个中断线编号,置1时开放该线上事 件中断

EXTI_RTSR:高13位保留,低19位对应19个中断线编号,置1时允许上升沿触 发事件和外部中断

EXTI_FTSR:高13位保留,低19位对应19个中断线编号,置1时允许下降沿触 发事件和外部中断

EXTI_SWIER:高13位保留,低19位对应19个中断线编号,置1时允许软件中 断,引起EXTI_PR挂起位置1,在IMREMR允许时产生中断

EXTI_PR:发生触发请求时置1,向该位写1可清除标志位

结构体定义:

 

中断向量初始化结构体:

 

typedef struct

{

  uint8_t NVIC_IRQChannel;   //中断通道

    

  uint8_t NVIC_IRQChannelPreemptionPriority;  //抢占优先级

 

  uint8_t NVIC_IRQChannelSubPriority; //次优先级

 

  FunctionalState NVIC_IRQChannelCmd;        / /使能中断

} NVIC_InitTypeDef;

 

其中宏定义有

 

typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;//使能宏定义

 

中断通道宏定义(注意中断线5以后的标号有变化)

 

  EXTI0_IRQn                  = 6,      /*!< EXTI Line0 Interrupt                                 */

  EXTI1_IRQn                  = 7,      /*!< EXTI Line1 Interrupt                                 */

  EXTI2_IRQn                  = 8,      /*!< EXTI Line2 Interrupt                                 */

  EXTI3_IRQn                  = 9,      /*!< EXTI Line3 Interrupt                                 */

  EXTI4_IRQn                  = 10,     /*!< EXTI Line4 Interrupt                                 */

 

EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */

 

 EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */

 

 

中断优先级设置表

 

 

 

中断初始化结构体

 

typedef struct

{

  uint32_t EXTI_Line;    //无符号32位变量设置中断线           

   

  EXTIMode_TypeDef EXTI_Mode;    //中断模式  

 

  EXTITrigger_TypeDef EXTI_Trigger;  //中断触发方式

 

  FunctionalState EXTI_LineCmd;     //中断使能

 

}EXTI_InitTypeDef;

 

其中有几个宏定义枚举量:

typedef enum  //中断模式选择,外部中断和事件中断

{

  EXTI_Mode_Interrupt = 0x00,

  EXTI_Mode_Event = 0x04

}EXTIMode_TypeDef;

 

typedef enum    //下降沿,上升沿,两者兼有

{

  EXTI_Trigger_Rising = 0x08,

  EXTI_Trigger_Falling = 0x0C,  

  EXTI_Trigger_Rising_Falling = 0x10

}EXTITrigger_TypeDef;

 

中断线定义

#define EXTI_Line0       ((uint32_t)0x00001)  /*!< External interrupt line 0 */

#define EXTI_Line1       ((uint32_t)0x00002)  /*!< External interrupt line 1 */

#define EXTI_Line2       ((uint32_t)0x00004)  /*!< External interrupt line 2 */

#define EXTI_Line3       ((uint32_t)0x00008)  /*!< External interrupt line 3 */

#define EXTI_Line4       ((uint32_t)0x00010)  /*!< External interrupt line 4 */

#define EXTI_Line5       ((uint32_t)0x00020)  /*!< External interrupt line 5 */

#define EXTI_Line6       ((uint32_t)0x00040)  /*!< External interrupt line 6 */

#define EXTI_Line7       ((uint32_t)0x00080)  /*!< External interrupt line 7 */

#define EXTI_Line8       ((uint32_t)0x00100)  /*!< External interrupt line 8 */

#define EXTI_Line9       ((uint32_t)0x00200)  /*!< External interrupt line 9 */

#define EXTI_Line10      ((uint32_t)0x00400)  /*!< External interrupt line 10 */

#define EXTI_Line11      ((uint32_t)0x00800)  /*!< External interrupt line 11 */

#define EXTI_Line12      ((uint32_t)0x01000)  /*!< External interrupt line 12 */

#define EXTI_Line13      ((uint32_t)0x02000)  /*!< External interrupt line 13 */

#define EXTI_Line14      ((uint32_t)0x04000)  /*!< External interrupt line 14 */

#define EXTI_Line15      ((uint32_t)0x08000)  /*!< External interrupt line 15 */

#define EXTI_Line16      ((uint32_t)0x10000)  /*!< External interrupt line 16 Connected to the PVD Output */

#define EXTI_Line17      ((uint32_t)0x20000)  /*!< External interrupt line 17 Connected to the RTC Alarm event */

#define EXTI_Line18      ((uint32_t)0x40000)  /*!< External interrupt line 18 Connected to the USB Device/USB OTG FS

                                                   Wakeup from suspend event */                                    

#define EXTI_Line19      ((uint32_t)0x80000)  /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */

 

库函数:

 

NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup) 

NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) //中断向量初始化函数,参数:中断向量初始化结构体

 

EXTI_DeInit(void) 中断初始化为缺省值

 

EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct) 中断初始化为中断初始化结构体中的指定值

参数:中断初始化结构体

 

EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct)中断初始化为复位值 参数:中断初始化结构体

 

 

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line) 查询中断标志位,参数,无符号32位中断线标号,返回该中断线的中断标志位是否置1

 

EXTI_ClearFlag(uint32_t EXTI_Line) 清除中断标志位,参数,无符号32位中断线标号

 

 

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)查询中断标志位并查看是否被屏蔽,参数,无符号32位中断线标号,返回中断线上标志位是否置1而且未被屏蔽

 

 

EXTI_ClearITPendingBit(uint32_t EXTI_Line)清空中断标志位,与之前那个完全相同,参数,无符号32位中断线标号

 

 GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource),这个函数属于GPIO的配置,所以单独列写,用于指定IO口作为中断的输入口,这个函数的参数有如下宏定义:

 

#define GPIO_PinSource0            ((uint8_t)0x00)

#define GPIO_PinSource1            ((uint8_t)0x01)

#define GPIO_PinSource2            ((uint8_t)0x02)

#define GPIO_PinSource3            ((uint8_t)0x03)

#define GPIO_PinSource4            ((uint8_t)0x04)

#define GPIO_PinSource5            ((uint8_t)0x05)

#define GPIO_PinSource6            ((uint8_t)0x06)

#define GPIO_PinSource7            ((uint8_t)0x07)

#define GPIO_PinSource8            ((uint8_t)0x08)

#define GPIO_PinSource9            ((uint8_t)0x09)

#define GPIO_PinSource10           ((uint8_t)0x0A)

#define GPIO_PinSource11           ((uint8_t)0x0B)

#define GPIO_PinSource12           ((uint8_t)0x0C)

#define GPIO_PinSource13           ((uint8_t)0x0D)

#define GPIO_PinSource14           ((uint8_t)0x0E)

#define GPIO_PinSource15           ((uint8_t)0x0F)

 

#define GPIO_PortSourceGPIOA       ((uint8_t)0x00)

#define GPIO_PortSourceGPIOB       ((uint8_t)0x01)

#define GPIO_PortSourceGPIOC       ((uint8_t)0x02)

#define GPIO_PortSourceGPIOD       ((uint8_t)0x03)

#define GPIO_PortSourceGPIOE       ((uint8_t)0x04)

#define GPIO_PortSourceGPIOF       ((uint8_t)0x05)

#define GPIO_PortSourceGPIOG       ((uint8_t)0x06)

 

 

注意:FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)只是检测是否产生了中断标志位,   并不一定响应中断

  ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)出了检测是否中断标志位是否置1外   还确认是不是中断不被屏蔽,会响应中断

      EXTI_ClearITPendingBit(uint32_t EXTI_Line)EXTI_ClearFlag(uint32_t EXTI_Line)             功能是相同的,都是清除中断标志位的。

 

程序代码分析(代码出自FIRE

 

static void NVIC_Configuration(void) // 配置中断向量

{

  NVIC_InitTypeDef NVIC_InitStructure; //结构体定义中断向量结构体

  

  /* Configure one bit for preemption priority */

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//设置中断向量通道

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//设置抢占优先级

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//设置子优先级

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//中断向量通道使能

  NVIC_Init(&NVIC_InitStructure);

}

 

void EXTI_PA0_Config(void)//中断配置函数

{

GPIO_InitTypeDef GPIO_InitStructure; 

EXTI_InitTypeDef EXTI_InitStructure;  //结构体定义中断结构体

 

/* config the extiline clock and AFIO clock */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE); //开启GPIOA时钟和第二功能时钟

/* config the NVIC */

NVIC_Configuration();//中断向量配置

 

/* EXTI line gpio config*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;       

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // 上拉输入

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

/* EXTI line mode config */

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //选择A0为中断口

  EXTI_InitStructure.EXTI_Line = EXTI_Line0;//中断线0

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿中断

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断使能

  EXTI_Init(&EXTI_InitStructure); //调用中断初始化函数

}

 

开放总中断和关闭总中断的宏定义,中断前需调用

#define CLI()      __set_PRIMASK(1) / 

#define SEI() __set_PRIMASK(0) /

 

中断服务函数

void EXTI0_IRQHandler(void)

{

if(EXTI_GetITStatus(EXTI_Line0) != RESET) //检查中断是否开启

{

LED1_TOGGLE;//进入中断则led取反

EXTI_ClearITPendingBit(EXTI_Line0);     //清除中断标志位

}  

}

 

 

小总结:1、配置中断首先配置中断向量,再配置中断,配置中断时要调用中断向量的配置, 并在GPIO中配置中断口的选择

2、中断函数开始时需确认中断是否响应,结束时需要清除中断标志位

3、Stm3219个中断线,其中16个为IO口外部中断,每一个对应IO口编号(A...E, 一共有80个中断,其它的3个 EXTI线16连接到PVD输出 EXTI线17连接到 RTC闹钟事件 EXTI线18连接到USB唤醒事件

4、中断挂起寄存器实际上就是中断标志位寄存器

5、中断服务函数在stm32f10x_it.c 文件中定义,这里定义了一些基本的中断服务 函数

你可能感兴趣的:(stm32学习笔记——按键(外部中断))