外部中斷的理解


使用 IO 口外部中斷的一般步驟:

1)初始化 IO 口為輸入。
2)開啟 IO 口復用時鍾,設置 IO 口與中斷線的映射關系。
3)初始化線上中斷,設置觸發條件等。
4)配置中斷分組(NVIC),並使能中斷。
5)編寫中斷服務函數。

//初始化
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

//開啟復用時鍾
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//外部中斷,需要使能 AFIO 時鍾
KEY_Init();//初始化按鍵對應 io 模式

//初始化線上中斷,設置觸發條件
//GPIOC.5 中斷線以及中斷初始化配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿觸發
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
//根據 EXTI_InitStruct 中指定的參數初始化外設 EXTI 寄存器

//配置中斷分組,並使能中斷
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
//使能按鍵所在的外部中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //搶占優先級 2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;  //子優先級 1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道
NVIC_Init(&NVIC_InitStructure);

//編寫中斷服務函數
void EXTI0_IRQHandler(void)
{
delay_ms(10); //消抖
if(WK_UP==1)
{ 
LED0=!LED0;
LED1=!LED1; 
}
EXTI_ClearITPendingBit(EXTI_Line0); //清除 EXTI0 線路掛起位
}

//根據 NVIC_InitStruct 中指定的參數初始化外設 NVIC 寄存器

 

STM32供IO口使用的中斷線只有16個,映射關系如下圖所示

 

 

 

配置GPIO與中斷線的映射關系的函數: GPIO_EXTILineConfig()來實現的:

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)

例子:該函數將 GPIO 端口與中斷線映射起來,使用范例是:GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);

中斷線上中斷的初始化是通過函數 EXTI_Init()實現的。EXTI_Init()函數的定義是:
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

typedef struct
{
uint32_t EXTI_Line;//中斷線的標號,取值范圍0~5
EXTIMode_TypeDef EXTI_Mode;
//中斷模式: EXTI_Mode_Interrupt 和事件 EXTI_Mode_Event

EXTITrigger_TypeDef EXTI_Trigger;
//觸發方式:下降沿觸發 EXTI_Trigger_Falling
//上升沿觸發 EXTI_Trigger_Rising,
//任意電平(上升沿和下降沿)觸發EXTI_Trigger_Rising_Falling

FunctionalState EXTI_LineCmd;
//使能
}EXTI_InitTypeDef;

 

例子

EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line4;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根據 EXTI_InitStruct 中指定的
//參數初始化外設 EXTI 寄存器

 

配置完中斷優先級后,要編寫中斷服務函數。

而中斷函數只用6個

EXPORT EXTI0_IRQHandler
EXPORT EXTI1_IRQHandler
EXPORT EXTI2_IRQHandler
EXPORT EXTI3_IRQHandler
EXPORT EXTI4_IRQHandler
EXPORT EXTI9_5_IRQHandler
EXPORT EXTI15_10_IRQHandler

在編寫中斷函數時會經常使用到兩個函數,

第一個函數是判斷某個中斷線上的中斷是否發生(標志位是否置位):

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

這個函數一般使用在中斷服務函數的開頭判斷中斷是否發生。

 

另一個函數是清除某個中斷上的中斷標志位:

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

這個函數一般應用在中斷服務函數結束之前,清除中斷標志位。

 

常用的中斷函數格式

void EXTI2_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line2)!=RESET)//判斷某個線上的中斷是否發生
    {
    中斷邏輯…
    EXTI_ClearITPendingBit(EXTI_Line2); //清除 LINE 上的中斷標志位
    } 
}    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM