STM32外部中斷(實現按鍵控制LED)


引言

“中斷” 這個概念,指的是在單片機運行過程中,在指定條件發生時,停下當前所有工作,去執行中斷處理函數內的內容。就像我們在教室上課時,突然地震了,不出意外的話我們都需要停下手中學習任務,去進行一系列的避險動作。

這一節我們通過中斷的方式,完成通過按鍵控制LED亮滅的操作。




准備環節

中斷相關知識

STM32的中斷控制器支持19個外部中斷/事件請求。這十九個外部中斷為:

  • 線0~15:對應外部IO口的輸入中斷。
  • 線16:連接到PVD輸出。
  • 線17:連接到連接到RTC時鍾事件。
  • 線18:連接到USB喚醒事件。

配置使用時,需要先將IO口與相應中斷線的映射關系建立,再對其進行使用。那映射關系是怎樣的呢?

GPIOx.0 ~ GPIOx.15(x = A,B,C,D,E,F,G)分別對應中斷線0 ~ 15

配置GPIO與中斷線關系的函數是 void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)

eg:GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);

把GPIO作為EXTI外部中斷時,需要打開AFIO時鍾。

APIO時鍾何時需要打開,具體可以參考這篇文章:

STM32的AFIO時鍾什么時候需要開啟

嵌套向量中斷控制器(NVIC)

初始化完線上中斷和中斷條件等內容,還需要配置中斷分組。配置中斷分組之前,我們需要先確定如何進行分組。這里就需要用到NVIC。

關於NVIC的具體內容可查看這篇博文:嵌套向量中斷控制器(NVIC)詳解




編碼環節

步驟

  • 初始化IO口輸入
  • 開啟AFIO時鍾
  • 設置IO口與中斷線的映射關系
  • 初始化線上中斷、設置觸發條件等
  • 配置中斷分組,並使能中斷
  • 編寫中斷服務函數

main.c(以下內容均省略頭文件)

int main(void){
	delay_init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//設置NVIC終端分組2
	LED_Init();
	KEY_Init();
	EXTIX_Init();	//外部中斷初始化
	LED1 = 0;
}

exti.h

#ifndef __EXTI_H
#define __EXIT_H	 
#include "sys.h"

void EXTIX_Init(void);	//外部中斷初始化

#endif

exti.c

void EXTIX_Init(void)
{

	EXTI_InitTypeDef EXTI_InitStructure;	//外部中斷結構體初始化
	NVIC_InitTypeDef NVIC_InitStructure;	//中斷分組結構體初始化

	KEY_Init();

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);	//開啟AFIO時鍾

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);	//映射IO口與中斷線
	
    //以下為配置中斷線初始化
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//中斷模式
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;				//使能中斷線
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;				//中斷線標號
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;	//觸發方式

	EXTI_Init(&EXTI_InitStructure);

	//以下為中斷優先級的配置
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;		//聲明使用的中斷是哪一個
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//設置搶占優先級為2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;	//設置子優先級為3
	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);		//清除中斷位
}




補充

中斷服務函數

中斷服務函數的名稱是固定的,寫錯會導致無法中斷。

STM32的IO口外部中斷函數只有六個。分別為:

  • EXTI0_IRQHandler
  • EXTI1_IRQHandler
  • EXTI2_IRQHandler
  • EXTI3_IRQHandler
  • EXTI4_IRQHandler
  • EXTI9_5_IRQHandler
  • EXTI15_10_IRQHandler

中斷線0 ~ 4各對應一個中斷服務函數,中斷線5 ~ 9共用 EXTI9_5_IRQHandler,中斷線10 ~ 15共用 EXTI15_10_IRQHandler

中斷服務函數常規格式

void EXTI3_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line3)!=RESET)		//判斷中斷線上的中斷是否發生
	{
		//這里寫需要執行的服務
		EXTI_ClearITPendingBit(EXTI_Line3);		//清除中斷標志位
	}
}


免責聲明!

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



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