[組み込み] STM32-外部割り込み/イベントコントローラ(EXTI)の詳細な説明「例:LEDのオフを実現するための外部割り込み」

1.EXTIの紹介

EXTI(外部割り込み/イベントコントローラー) —外部割り込み/イベントコントローラー。コントローラーの20の割り込み/イベントラインを管理します。各割り込み/イベントラインはエッジ検出器に対応しており
入力信号の立ち上がりエッジと立ち下がりエッジを検出できます。EXTIは、各割り込み/イベントラインの個別の構成を実現できます。これは、
割り込みまたはイベントとして個別に構成できるほか、トリガーイベントの属性も実現できます

2.EXTI機能ブロック図

ここに画像の説明を挿入

1. EXTIは、割り込みを生成する機能とイベントを生成する機能の2つの主要な機能に分けることができます。
2. EXTIコントローラには19個の割り込み/イベント入力ラインがあります。これらの入力ラインは、レジスタを介してペリフェラルの任意のGPIOまたはその他のイベントに設定できます
3.エッジ検出回路の場合立ち上がりエッジトリガー選択レジスタ(EXTI_RTSR)と立ち下がりエッジトリガー選択レジスタ(EXTI_FTSR)の対応するビットを制御して、トリガーモードを設定します。
4.割り込みトリガーは、外部入力ラインとソフトウェア割り込みイベントレジスタ(EXTI_SWIER)からそれぞれ取得できます。構造図から、それらはORゲートを介して接続されています。
5.保留中のレジスタ(EXTI_PR)で割り込みが発生した場合、対応するレジスタは1です。6
。割り込みマスクレジスタ(EXTI_IMR)は、割り込みをマスクできます。
7.最後に、EXTI_PRレジスタの内容をNVIC出力して、システム割り込みイベント制御を実現します。8
。同様にイベントを生成します。パルス信号は、イベントを生成する回路の最終生成物です。このパルス信号は、タイマーTIM、アナログ-デジタルコンバータADCなどの他の周辺回路で使用できます。このようなパルス信号は、通常、TIMをトリガーするために使用されます。またはADCで変換を開始します。

三、プログラミング

次の点を把握してください。

1. EXTIには20の割り込み/イベントラインがあり、各GPIOを入力ラインとして設定できます。
2. EXTI0EXTI15であるために使用されるGPIO、及び任意のGPIOは、プログラミング制御によりEXTIの入力ソースとして使用することができます。
3. EXTIが設定されている場合、多重化クロック(RCC_AFIOをオンにする必要があります
。4。EXTI割り込み/イベントライン
ここに画像の説明を挿入
ここに画像の説明を挿入

上の図では、EXTI nを表すのは入力であり、P X n(X = A、B、C、D、E、F、G)(n = 1,2…15)になります。

1.プログラミングポイント
1)割り込みの生成に使用されるGPIOの初期化;
2)EXTIの初期化;
3)NVICの構成;
4)割り込みサービス機能の書き込み;

ボタンと同様に、フローティング入力モードのみでGPIOを構成します。

4.例:

「ボタン制御LEDのオン/オフを実現」

1)割り込みの生成に使用されるGPIOを初期化します。

void KEY_GPIO_Config(void)
{
    
    
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(GPIO_KEY1_CLK|
						   GPIO_KEY2_CLK|
	                       GPIO_KEY3_CLK|
	                       GPIO_KEY4_CLK|
						   RCC_APB2Periph_AFIO,ENABLE);
												//RCC_APB2Periph_AFIO
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	
	GPIO_InitStruct.GPIO_Pin = GPIO_KEY1_PIN;
	GPIO_Init(GPIO_KEY1_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = GPIO_KEY2_PIN;
	GPIO_Init(GPIO_KEY2_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = GPIO_KEY3_PIN;
	GPIO_Init(GPIO_KEY3_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = GPIO_KEY4_PIN;
	GPIO_Init(GPIO_KEY4_PORT,&GPIO_InitStruct);
	
}

2)EXTIを初期化します。

void EXTI_Config(void)
{
    
    
	EXTI_InitTypeDef EXTI_InitStruct;
	
	NVIC_Config();
	
	//为什么我额外使能一下RCC_AFIO 程序会出错,  PS现在好像不错了
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

	//配置EXTI结构体
	GPIO_EXTILineConfig( KEY1_INT_EXTI_PortSourse, KEY1_INT_EXTI_PinSourse);//选择EXTI的信号源
	
	EXTI_InitStruct.EXTI_Line = KEY1_INT_EXTI_Line;
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;		//KEY1
	EXTI_Init(&EXTI_InitStruct);
	
	GPIO_EXTILineConfig(KEY2_INT_EXTI_PortSourse, KEY2_INT_EXTI_PinSourse);//选择EXTI的信号源
	EXTI_InitStruct.EXTI_Line = KEY2_INT_EXTI_Line; 		//KEY2
	EXTI_Init(&EXTI_InitStruct);
	
	GPIO_EXTILineConfig(KEY3_INT_EXTI_PortSourse, KEY3_INT_EXTI_PinSourse);//选择EXTI的信号源
	EXTI_InitStruct.EXTI_Line = KEY3_INT_EXTI_Line; 		//KEY3
	EXTI_Init(&EXTI_InitStruct);
	
	GPIO_EXTILineConfig(KEY4_EXTI_PortSourse, KEY4_EXTI_PinSourse);//选择EXTI的信号源
	EXTI_InitStruct.EXTI_Line = KEY4_EXTI_Line; 			//KEY4
	EXTI_Init(&EXTI_InitStruct);
}

3)NVICを構成します。

void NVIC_Config(void)
{
    
    
	NVIC_InitTypeDef NVIC_InitStruct;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//配置NVIC为优先级组1
	
	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;				//KEY1
	NVIC_Init(&NVIC_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;  			//KEY2
	NVIC_Init(&NVIC_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;  				//KEY3
	NVIC_Init(&NVIC_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel = EXTI2_IRQn;  				//KEY4
	NVIC_Init(&NVIC_InitStruct);
}

4)割り込みサービス関数を記述します。

void EXTI0_IRQHandler(void)						//KEY1
{
    
    
	if(EXTI_GetITStatus(KEY1_INT_EXTI_Line))
	{
    
    
		LED_1_TOGGLE;
		EXTI_ClearITPendingBit(KEY1_INT_EXTI_Line);
	}

	
}
void EXTI9_5_IRQHandler(void)					//KEY2
{
    
    

	if(EXTI_GetITStatus(KEY2_INT_EXTI_Line))
	{
    
    
		LED_2_TOGGLE;
		EXTI_ClearITPendingBit(KEY2_INT_EXTI_Line);
	}

	
}
void EXTI1_IRQHandler(void)						//KEY3
{
    
    
	
	if(EXTI_GetITStatus(KEY3_INT_EXTI_Line))
	{
    
    
		LED_3_TOGGLE;
		EXTI_ClearITPendingBit(KEY3_INT_EXTI_Line);
	}
	
	
}
void EXTI2_IRQHandler(void)						//KEY4
{
    
    
	
	if(EXTI_GetITStatus(KEY4_EXTI_Line))
	{
    
    
		LED_4_TOGGLE;
		EXTI_ClearITPendingBit(KEY4_EXTI_Line);
	}
	
}

ご不明な点がございましたら、メッセージを残して、交換と議論を歓迎します!

おすすめ

転載: blog.csdn.net/qq_45689790/article/details/113847739