【STM32】EXTI---外部中斷/事件控制器

2020-10-11 15:00:18

Author:AXYZdong 自動化專業 工科男
有一點思考,有一點想法,有一點理性!
定個小小目標,努力成為習慣!在最美的年華遇見更好的自己!
CSDN@AXYZdong,CSDN首發,AXYZdong原創
唯一部落格更新的地址為: 👉 AXYZdong的部落格 👈

在這裡插入圖片描述


  • 開發板:stm32f407VET6
  • 開發環境:keil5 MDK

插播一條反爬蟲資訊,讀者可以忽略:


在這裡插入圖片描述

2020電賽前夜的一篇文章,明天8點開題,加油!


一、EXTI 簡介

外部中斷/事件控制器(EXTI)管理了控制器的 23箇中斷/事件線。每個中斷/事件線都對應有一個邊沿檢測器,可以實現輸入訊號的上升沿檢測和下降沿的檢測。EXTI 可以實現對每個中斷/事件線進行單獨設定,可以單獨設定為中斷或者事件,以及觸發事件的屬性。


二、EXTI 功能框圖


在這裡插入圖片描述

  • 訊號線上斜槓並標註 「23」 字樣 :表示在控制器內部類似的訊號線路有23個。
  • EXTI 是掛靠在 APB2 匯流排上的。

三、中斷/事件線


中斷/事件線輸入源
EXTI0PX0(X 可為 A,B,C,D,E,F,G,H,I)
EXTI1PX1(X 可為 A,B,C,D,E,F,G,H,I)
EXTI2PX2(X 可為 A,B,C,D,E,F,G,H,I)
EXTI3PX3(X 可為 A,B,C,D,E,F,G,H,I)
EXTI4PX4(X 可為 A,B,C,D,E,F,G,H,I)
EXTI5PX5(X 可為 A,B,C,D,E,F,G,H,I)
EXTI6PX6(X 可為 A,B,C,D,E,F,G,H,I)
EXTI7PX7(X 可為 A,B,C,D,E,F,G,H,I)
EXTI8PX8(X 可為 A,B,C,D,E,F,G,H,I)
EXTI9PX9(X 可為 A,B,C,D,E,F,G,H,I)
EXTI10PX10(X 可為 A,B,C,D,E,F,G,H,I)
EXTI11PX11(X 可為 A,B,C,D,E,F,G,H,I)
EXTI12PX12(X 可為 A,B,C,D,E,F,G,H,I)
EXTI13PX13(X 可為 A,B,C,D,E,F,G,H,I)
EXTI14PX14(X 可為 A,B,C,D,E,F,G,H,I)
EXTI15PX15(X 可為 A,B,C,D,E,F,G,H,I)
EXTI16可程式化電壓檢測器(PVD)輸出
EXTI17RTC 鬧鐘事件
EXTI18USB OTG FS 喚醒事件
EXTI19乙太網喚醒事件
EXTI20USB OTG HS(在 FS 中設定)喚醒事件
EXTI21RTC 入侵和時間戳事件
EXTI22RTC 喚醒事件
  • EXTI0至 EXTI15用於 GPIO,通過程式設計控制可以實現任意一個 GPIO作為EXTI 的輸入源
  • SYSCFG 外部中斷設定暫存器 1 設定EXTI0

在這裡插入圖片描述

▲ EXTI0輸入源選擇


四、EXTI 初始化結構體

typedef struct
{
   //中斷/事件線
  uint32_t EXTI_Line;               /*!< Specifies the EXTI lines to be enabled or disabled.
                                         This parameter can be any combination value of @ref EXTI_Lines */
   //EXTI 模式
  EXTIMode_TypeDef EXTI_Mode;       /*!< Specifies the mode for the EXTI lines.
                                         This parameter can be a value of @ref EXTIMode_TypeDef */
   //觸發型別
  EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
                                         This parameter can be a value of @ref EXTITrigger_TypeDef */
   //EXTI 控制
  FunctionalState EXTI_LineCmd;     /*!< Specifies the new state of the selected EXTI lines.
                                         This parameter can be set either to ENABLE or DISABLE */ 
}EXTI_InitTypeDef;

4.1. 中斷/事件線

#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 OTG FS Wakeup from suspend event */                                    
#define EXTI_Line19      ((uint32_t)0x80000)     /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */
#define EXTI_Line20      ((uint32_t)0x00100000)  /*!< External interrupt line 20 Connected to the USB OTG HS (configured in FS) Wakeup event  */
#define EXTI_Line21      ((uint32_t)0x00200000)  /*!< External interrupt line 21 Connected to the RTC Tamper and Time Stamp events */                                               
#define EXTI_Line22      ((uint32_t)0x00400000)  /*!< External interrupt line 22 Connected to the RTC Wakeup event */ 

4.2. EXTI 模式

typedef enum
{
  EXTI_Mode_Interrupt = 0x00,  //產生中斷
  EXTI_Mode_Event = 0x04       //產生事件
}EXTIMode_TypeDef;

4.3. 觸發型別

typedef enum
{
  EXTI_Trigger_Rising = 0x08,         //上升沿
  EXTI_Trigger_Falling = 0x0C,        //下降沿
  EXTI_Trigger_Rising_Falling = 0x10  //上升沿和下降沿都觸發
}EXTITrigger_TypeDef;

4.4. EXTI 控制

使能 EXTI ,一般都是使能,ENABLE

五、外部中斷控制實驗

按鍵作為外部輸入,按下按鍵觸發外部中斷,進入中斷服務函數。

程式設計要點

  • 初始化LED的GPIO
  • 開啟按鍵GPIO時鐘和SYSCFG時鐘
  • 設定按鍵GPIO為輸入模式
  • 設定NVIC
  • 按鍵GPIO連線到EXTI輸入
  • 設定EXTI中斷/事件線
  • EXTI中斷服務函數

EXTI.h

// =============================================
# @Time    : 2020-10-09
# @Author  : AXYZdong
# @CSDN    : https://blog.csdn.net/qq_43328313
# @FileName: exti.h
# @Software: keil5 MDK
// =============================================

#ifndef _EXTI_H
#define _EXTI_H

//引腳宏定義  
/*******************************************************/ 
#define KEY1_EXTI_PORTSOURCE   EXTI_PortSourceGPIOE
#define KEY1_EXTI_PINSOURCE    EXTI_PinSource3
#define KEY1_EXTI_LINE         EXTI_Line3
#define KEY1_EXTI_IRQ          EXTI3_IRQn

#define KET1_IRQHandler        EXTI3_IRQHandler

void EXTI_Config(void);

#endif

EXTI.c

// =============================================
# @Time    : 2020-10-09
# @Author  : AXYZdong
# @CSDN    : https://blog.csdn.net/qq_43328313
# @FileName: EXTI.c
# @Software: keil5 MDK
// =============================================

#include "stm32f4xx.h"
#include "exti.h"
#include "bsp_key.h"
#include "delay.h"

uint8_t flag = 0x00;
void EXTI_Config(void)
{	
	EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	/* 使能 SYSCFG 時鐘 ,使用 GPIO 外部中斷時必須使能 SYSCFG 時鐘*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	
  /* 連線 EXTI 中斷源 到 key1 引腳 */ 	
	SYSCFG_EXTILineConfig(KEY1_EXTI_PORTSOURCE, KEY1_EXTI_PINSOURCE);
	
	EXTI_InitStructure.EXTI_Line = KEY1_EXTI_LINE;          //連線中斷源
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;               //使能中斷
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;     //中斷模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitStructure.NVIC_IRQChannel = KEY1_EXTI_IRQ;      //中斷通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;  //搶佔優先順序1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;		 //子優先順序1
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			 //IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	                         //根據指定的引數初始化VIC暫存器
	
}

void KET1_IRQHandler(void)
{
  delay_ms(10);
	if(KEY1 == RESET)
	{
	  flag++;
		flag &= 0x01;
		flag == RESET ? GPIO_SetBits(GPIOA,GPIO_Pin_6) : GPIO_ResetBits(GPIOA,GPIO_Pin_6);
	}
	while(!KEY1);
	EXTI_ClearITPendingBit(KEY1_EXTI_LINE);
}

main.c

// =============================================
# @Time    : 2020-10-09
# @Author  : AXYZdong
# @CSDN    : https://blog.csdn.net/qq_43328313
# @FileName: main.c
# @Software: keil5 MDK
// =============================================

#include "stm32f4xx.h"
#include "bsp_led.h"
#include "bsp_key.h"
#include "sys.h"
#include "delay.h"
#include "exti.h"

int main()
{ 
 	delay_init(168);        //初始化延時函數
	LED_GPIO_Config();      //初始化LED埠 
 	KEY_Init();             //初始化與按鍵連線的硬體介面
	EXTI_Config();          //初始化外部中斷
	while(1)
	{
	}
}

實驗現象

按下 KEY1 並彈開,LED點亮。再按下 KEY1 並彈開,LED熄滅。

六、總結

  • 注意 .h 檔案中 EXTI 中斷/事件線的設定
  • 與 f103 不同,f407需要開啟 SYSCFG 外部中斷設定暫存器的時鐘
  • 宏定義的使用可以便於程式碼移植

【參考文獻】

[1] 《零死角玩轉 STM32—基於野火 F407[霸天虎]開發板 》




  本次的分享就到這裡


11

好書不厭百回讀,熟讀自知其中意。將學習成為習慣,用知識改變命運,用部落格見證成長,用行動證明努力。
如果我的部落格對你有幫助、如果你喜歡我的部落格內容,請 「點贊」 「評論」 「收藏」 一鍵三連哦!
聽說 👉 點贊 👈 的人運氣不會太差,每一天都會元氣滿滿呦!^ _ ^ ❤️ ❤️ ❤️
碼字不易,大家的支援就是我堅持下去的動力。點贊後不要忘了👉關注👈我哦!
更多精彩內容請前往 AXYZdong的部落格


如果以上內容有任何錯誤或者不準確的地方,歡迎在下面👇留個言。或者你有更好的想法,歡迎一起交流學習~~~