目的:使用外部中斷方式觸發按鍵,會使用外部中斷的操作
配置文件:#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,在IMR或EMR允許時產生中斷
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,
EXTI1_IRQn = 7,
EXTI2_IRQn = 8,
EXTI3_IRQn = 9,
EXTI4_IRQn = 10,
EXTI9_5_IRQn = 23,
EXTI15_10_IRQn = 40,
中斷優先級設置表
中斷初始化結構體
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)
#define EXTI_Line1 ((uint32_t)0x00002)
#define EXTI_Line2 ((uint32_t)0x00004)
#define EXTI_Line3 ((uint32_t)0x00008)
#define EXTI_Line4 ((uint32_t)0x00010)
#define EXTI_Line5 ((uint32_t)0x00020)
#define EXTI_Line6 ((uint32_t)0x00040)
#define EXTI_Line7 ((uint32_t)0x00080)
#define EXTI_Line8 ((uint32_t)0x00100)
#define EXTI_Line9 ((uint32_t)0x00200)
#define EXTI_Line10 ((uint32_t)0x00400)
#define EXTI_Line11 ((uint32_t)0x00800)
#define EXTI_Line12 ((uint32_t)0x01000)
#define EXTI_Line13 ((uint32_t)0x02000)
#define EXTI_Line14 ((uint32_t)0x04000)
#define EXTI_Line15 ((uint32_t)0x08000)
#define EXTI_Line16 ((uint32_t)0x10000)
#define EXTI_Line17 ((uint32_t)0x20000)
#define EXTI_Line18 ((uint32_t)0x40000)
#define EXTI_Line19 ((uint32_t)0x80000)
庫函數:
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; //結構體定義中斷向量結構體
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; //結構體定義中斷結構體
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE); //開啟GPIOA時鐘和第二功能時鐘
NVIC_Configuration();//中斷向量配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉輸入
GPIO_Init(GPIOA, &GPIO_InitStructure);
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、Stm32有19個中斷線,其中16個為IO口外部中斷,每一個對應IO口編號(A...E), 一共有80個中斷,其它的3個 EXTI線16連接到PVD輸出 EXTI線17連接到 RTC鬧鐘事件 EXTI線18連接到USB喚醒事件
4、中斷掛起寄存器實際上就是中斷標志位寄存器
5、中斷服務函數在stm32f10x_it.c 文件中定義,這里定義了一些基本的中斷服務函數
aw1202 發表于 2016-4-12 10:45
看著好高深的樣子
歡迎光臨 (http://m.zg4o1577.cn/bbs/) | Powered by Discuz! X3.1 |