STM32之EXTI


簡介:

exti--外部中斷/事件控制器,控制器由20個邊沿檢測器組成,每個檢測器都連接了所有端口對應引腳,每個輸入線都可以獨立的配置輸入類型可觸發事件(上升沿/下降沿/雙邊沿觸發)。

功能框圖;

圖中黃色部分表示每個寄存器都有20個輸入線與之相對應

如:中斷屏蔽寄存器

寄存器中有20個外部輸入線的中斷屏蔽標志位。

紅色虛線部分為中斷部分:邊沿檢測電路通過上升/下降沿邊沿觸發選擇寄存器對輸入線輸入的信號進行檢測,當檢測條件滿足時(如:設置上升沿觸發,則信號線來了一個上升沿),邊沿檢測電路輸出1給圖中的3(或門),或門輸出信號傳給圖中4(與門),如果設置了中斷屏蔽寄存器的值為1(表示開發中斷請求),則與門輸出電平1,請求掛起寄存器對應位置1,圖中的5從請求掛起寄存器中取出值給NVIC,從而實現中斷控制。

綠色虛線部分為事件部分:圖中1 2 3與產生中斷一樣。圖3產生的信號此時電平為1與6(與門)另一個輸入信號事件屏蔽寄存器值進行與操作,如果事件屏蔽寄存器的對應位也為1,則輸出電平1給脈沖發生器,脈沖發生器接收到電平1后,產生脈沖從圖中8輸出出去。

中斷/事件線:

 exti0~15可以對應多個io引腳,通過AFIO寄存器選擇具體的引腳。

外部中斷初始化結構體:

EXTI_Line:中斷線選擇,可以選擇EXTI0~EXTI19

EXTI_Mode:模式 是產生中斷還是事件

EXTI_Trigger:觸發類型 是上升沿 下降沿還是雙邊沿觸發

EXTI_LineCmd:是 使能還是失能中斷線

實驗:

通過開發板上的四個按鍵對4個LED控制。按下按鍵LED亮,再按下,LED滅

原理圖:

編程思路:

1.初始化4個led端口 和4個按鍵其中key_up配置成下拉輸入,其他按鍵配置成上拉輸入

2.配置中斷優先級

3.配置外部中斷,在里面記得開啟AFIO時鍾

4.編寫中斷程序

exti頭文件:

#ifndef _EXTI_H
#define _EXTI_H

#include "stm32f10x.h"
//上鍵宏定義
#define KEY_UP_CLK   RCC_APB2Periph_GPIOA
#define KEY_UP_PIN   GPIO_Pin_0
#define KEY_UP_PORT  GPIOA
//左鍵
#define KEY_LEFT_CLK RCC_APB2Periph_GPIOE
#define KEY_LEFT_PIN GPIO_Pin_2
#define KEY_LEFT_PORT GPIOE
//下鍵
#define KEY_DOWN_CLK RCC_APB2Periph_GPIOE
#define KEY_DOWN_PIN GPIO_Pin_3
#define KEY_DOWN_PORT GPIOE
//右鍵
#define KEY_RIGHT_CLK RCC_APB2Periph_GPIOE
#define KEY_RIGHT_PIN GPIO_Pin_4
#define KEY_RIGHT_PORT GPIOE

//LED
#define      LED_CLK    RCC_APB2Periph_GPIOC
#define   LED_PORT   GPIOC

#define   LED1_PIN    GPIO_Pin_0
#define   LED2_PIN    GPIO_Pin_1
#define   LED3_PIN    GPIO_Pin_2
#define   LED4_PIN    GPIO_Pin_3



void EXTI_Config(void);
#endif

exti源文件

#include "exti.h"
static void LED_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(LED_CLK,ENABLE);
    //LED1 LED2 LED3 LED4初始化
    GPIO_InitStruct.GPIO_Pin=LED1_PIN|LED2_PIN|LED3_PIN|LED4_PIN;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽輸出
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(LED_PORT,&GPIO_InitStruct);
    //默認熄滅
    GPIO_SetBits(LED_PORT,LED1_PIN|LED2_PIN|LED3_PIN|LED4_PIN);
}
static void KEY_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    //開啟四個鍵所對應io端口時鍾
    RCC_APB2PeriphClockCmd(KEY_UP_CLK|KEY_LEFT_CLK|KEY_DOWN_CLK|KEY_RIGHT_CLK,ENABLE);
    //上鍵
    GPIO_InitStruct.GPIO_Pin=KEY_UP_PIN;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;//下拉輸入模式
    GPIO_Init(KEY_UP_PORT,&GPIO_InitStruct);
    //左鍵
    GPIO_InitStruct.GPIO_Pin=KEY_LEFT_PIN;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//上拉輸入模式
    GPIO_Init(KEY_LEFT_PORT,&GPIO_InitStruct);
    //下鍵
    GPIO_InitStruct.GPIO_Pin=KEY_DOWN_PIN;
    GPIO_Init(KEY_DOWN_PORT,&GPIO_InitStruct);
    //右鍵
    GPIO_InitStruct.GPIO_Pin=KEY_RIGHT_PIN;
    GPIO_Init(KEY_RIGHT_PORT,&GPIO_InitStruct);
}
static void KEY_EXTI_Config(void)
{
    EXTI_InitTypeDef   EXTI_InitStruct;
    //使用外部中斷 端口復用 重映射需要開啟AFIO時鍾
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    //上鍵外部中斷配置
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//外部中斷線配置
    EXTI_InitStruct.EXTI_Line=EXTI_Line0;//中斷線
    EXTI_InitStruct.EXTI_LineCmd=ENABLE;
    EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;//中斷模式
    EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;//上升沿檢測
    EXTI_Init(&EXTI_InitStruct);
    //左鍵外部中斷配置
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);//外部中斷線配置
    EXTI_InitStruct.EXTI_Line=EXTI_Line2;//中斷線
    EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿檢測
    EXTI_Init(&EXTI_InitStruct);
    //下鍵外部中斷配置
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);//外部中斷線配置
    EXTI_InitStruct.EXTI_Line=EXTI_Line3;//中斷線
    EXTI_Init(&EXTI_InitStruct);
    //右鍵外部中斷配置
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);//外部中斷線配置
    EXTI_InitStruct.EXTI_Line=EXTI_Line4;//中斷線
    EXTI_Init(&EXTI_InitStruct);
}

static void NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStruct;
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中斷優先級分組
    //上鍵
    NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;//中斷源
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
    NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStruct);
    //左鍵
    NVIC_InitStruct.NVIC_IRQChannel=EXTI2_IRQn;//中斷源
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;
    NVIC_Init(&NVIC_InitStruct);
    //下鍵
    NVIC_InitStruct.NVIC_IRQChannel=EXTI3_IRQn;//中斷源
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;
    NVIC_Init(&NVIC_InitStruct);
    //右鍵
    NVIC_InitStruct.NVIC_IRQChannel=EXTI4_IRQn;//中斷源
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority=3;
    NVIC_Init(&NVIC_InitStruct);
}
void EXTI_Config(void)
{
    LED_GPIO_Config();
    KEY_GPIO_Config();
    NVIC_Config();
    KEY_EXTI_Config();
}
//上鍵中斷
void EXTI0_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0)==SET)
    {
        if(GPIO_ReadOutputDataBit(LED_PORT,LED1_PIN))
            GPIO_ResetBits(LED_PORT,LED1_PIN);
        else
            GPIO_SetBits(LED_PORT,LED1_PIN);
        EXTI_ClearITPendingBit(EXTI_Line0);
    }
}
//左鍵中斷
void EXTI2_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line2)==SET)
    {
        if(GPIO_ReadOutputDataBit(LED_PORT,LED2_PIN))
            GPIO_ResetBits(LED_PORT,LED2_PIN);
        else
            GPIO_SetBits(LED_PORT,LED2_PIN);
        EXTI_ClearITPendingBit(EXTI_Line2);
    }
}
//下鍵中斷
void EXTI3_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line3)==SET)
    {
        if(GPIO_ReadOutputDataBit(LED_PORT,LED3_PIN))
            GPIO_ResetBits(LED_PORT,LED3_PIN);
        else
            GPIO_SetBits(LED_PORT,LED3_PIN);
        EXTI_ClearITPendingBit(EXTI_Line3);
    }
}
//右鍵中斷
void EXTI4_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line4)==SET)
    {
        if(GPIO_ReadOutputDataBit(LED_PORT,LED4_PIN))
            GPIO_ResetBits(LED_PORT,LED4_PIN);
        else
            GPIO_SetBits(LED_PORT,LED4_PIN);
        EXTI_ClearITPendingBit(EXTI_Line4);
    }
}

main 文件:

#include "stm32f10x.h"
#include "exti.h"
int main(void)
{
    EXTI_Config();
    while(1);
}

 


免責聲明!

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



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