国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【STM32】外部中斷實現(xiàn)按鍵實驗

這篇具有很好參考價值的文章主要介紹了【STM32】外部中斷實現(xiàn)按鍵實驗。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??作者:一只大喵咪1201
??專欄:《STM32學(xué)習(xí)》
??格言:你只管努力,剩下的交給時間!
stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件

??描述

在前面的文章控制LED和蜂鳴器的按鍵實驗中詳細的講解了怎樣通過GPIO的輸入模式來控制LED燈和蜂鳴器的狀態(tài)。這篇文章同樣是實現(xiàn)上訴的功能,但是方式是采用外部中斷的方式實現(xiàn)的,也就是4個按鍵分別對應(yīng)一個外部中斷,中斷程序中控制一種狀態(tài)。

??外部中斷概述

本喵使用的STM32F103ZET6芯片有7組GPIO,每一組GPIO又有16個IO口,而STM32的強大之處就在于,它的每一個IO口都支持外部中斷的響應(yīng),這樣來看它共有112個IO口可以實現(xiàn)中斷響應(yīng),這么多IO口同樣也有管理的方式。

  • 該芯片有19根外部中斷線,分別是:
  • 線 0~15:對應(yīng)外部 IO 口的輸入中斷。
  • 線 16:連接到 PVD 輸出。
  • 線 17:連接到 RTC 鬧鐘事件。
  • 線 18:連接到 USB 喚醒事件。

本次實驗只使用到線0到15,也就是外部中斷的中斷線,其他3根中斷線在使用到的時候本喵會詳細的講解。

可以看到,外部中斷線有16根,而IO口有112個,所以它們之間存在一個映射關(guān)系:
stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
可以看到,外部中斷線與GPIO之間的映射關(guān)系為:

  • EXIT0可以映射到PA0,PB0,PC0,PD0,PE0,PF0,PG0
  • EXIT1可以映射到PA1,PB1,PC1,PD1,PE1,PF1,PG1
  • EXIT2可以映射到PA2,PB2,PC2,PD2,PE2,PF2,PG2
  • EXIT3可以映射到PA3,PB0,PC3,PD3,PE3,PF3,PG3
  • EXIT14可以映射到PA14,PB14,PC14,PD14,PE14,PF14,PG14
  • EXIT15可以映射到PA15,PB15,PC15,PD15,PE15,PF15,PG15

也就是IO口對應(yīng)下標的數(shù)字是幾就可以作為對應(yīng)外部中斷線的映射口。
注意:

  • 一根外部中斷線只能映射到一個IO口上,比如EXIT0映射到了PA0口上,此時PB0便不能再作為EXIT0的映射口。
  • IO口作為映射口以后,并不影響讀取該IO口的數(shù)據(jù)。

我們知道,中斷是有中斷服務(wù)函數(shù)的,那么當中斷發(fā)生的時候,是CPU是怎么執(zhí)行對應(yīng)的中斷函數(shù)的呢?

stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
上圖是一個中斷向量表,不同的外部中斷線產(chǎn)生中斷請求并且被響應(yīng)后就會竟如對應(yīng)的中斷程序,該程序的入口在對應(yīng)的向量地址處。

  • EXIT0到EXIT4這5個外部中斷對應(yīng)的5個中斷服務(wù)函數(shù)。中斷發(fā)生并被響應(yīng)后就會去執(zhí)行對應(yīng)的中斷服務(wù)函數(shù)。
  • EXIT5到EXIT9是共用一個中斷服務(wù)函數(shù)的。這5個外部中斷發(fā)生并被響應(yīng)后都會進入同一個外部中斷服務(wù)函數(shù),所以在函數(shù)中需要寫響應(yīng)的判斷代碼,確定是哪個中斷。
  • EXIT10到EXIT15同樣也是共用一個中斷服務(wù)函數(shù)的。這5個中斷發(fā)生并被響應(yīng)后同樣會進入一個中斷服務(wù)函數(shù)。

??外部中斷配置寄存器

外部中斷線與GPIO的映射關(guān)系是通過配置外部中斷配置寄存器實現(xiàn)的,在AFIO(輔助功能寄存器)中配置外部中斷的寄存器有3個。

  1. AFIO_EXTICR1

stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
上圖是它的每一位的分布情況以及具體的控制情況。

  1. AFIO_EXTICR2

stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
上圖是它的每一位的分布情況以及具體的控制情況。

  1. AFIO_EXTICR3

stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
上圖是它的每一位的分布情況以及具體的控制情況。

ST官方同樣提供了相應(yīng)的庫函數(shù)來配置外部中斷線與GPIO的映射關(guān)系

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

使用庫函數(shù)我們就不用去挨個配置每個寄存器了,該函數(shù)的具體使用本喵會文章后面的代碼過程中演示。

??實驗代碼

既然是用外部中斷實現(xiàn)按鍵,那么中斷服務(wù)函數(shù)是必不可少的,又因為用到LED燈,蜂鳴器,按鍵,以及串口,所以還需要這幾個硬件以及串口外設(shè)的初始化函數(shù)。

??LED初始化

stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件

通過原理圖我們可以看到LED0是與PB5相連的,LED1是與PE5相連的。
stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
LED0和LED1是采用的共陽極接法,也就是當PB5口和PE5口是低電平的時候LED0和LED1亮。
代碼如下
led.h中的代碼:

#ifndef __LED_H
#define __LED_H

#include "sys.h"//位操作頭文件引用
#define LED0 PBout(5)
#define LED1 PEout(5)

//為使用方便,直接用硬件名來控制燈的狀態(tài)

void LED_Init(void);//函數(shù)聲明

#endif

led.c中的代碼:

#include "stm32f10x.h"//引用頂級頭文件
#include "led.h"//引用led初始化頭文件


void LED_Init()
{
	GPIO_InitTypeDef GPIO_InitStructe;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);//將GPIOB和GPIOE的時鐘使能
	
	//PB5初始化
	GPIO_InitStructe.GPIO_Mode=GPIO_Mode_Out_PP;//推挽輸出模式
	GPIO_InitStructe.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructe.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructe);
	//PE5初始化
	GPIO_InitStructe.GPIO_Mode=GPIO_Mode_Out_PP;//推挽輸出模式
	GPIO_InitStructe.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructe.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOE,&GPIO_InitStructe);
	
	//初始狀態(tài)為燈全滅
	LED0=1;
	LED1=1;
}

??蜂鳴器初始化

stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
可以看到,蜂鳴器是與PB8相連的。
stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
當PB8是高電平的時候,蜂鳴器發(fā)出響聲。
beep.h中的代碼:

#ifndef __BEEP_H
#define __BEEP_H

#include "sys.h"
#define beep PBout(8)

void BEEP_Init(void);

#endif

beep.c中的代碼:

#include "stm32f10x.h"
#include "beep.h"

void BEEP_Init()
{
	GPIO_InitTypeDef GPIO_InitStructe;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//將GPIOB和GPIOE的時鐘使能
	
	//PB5初始化
	GPIO_InitStructe.GPIO_Mode=GPIO_Mode_Out_PP;//推挽輸出模式
	GPIO_InitStructe.GPIO_Pin=GPIO_Pin_8;
	GPIO_InitStructe.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructe);
	//蜂鳴器初始化為不響
	beep=0;
}

??按鍵初始化

stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
可以看到,KEY0與PE4相連,KEY1與PE3相連,KEY2與PE2相連。

stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
WK_UP按鍵與PA0相連。
stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件

  • KEY0到KEY2的另一端都是與地相連,當按鍵按下的時候是低電平,所以這3個按鍵要設(shè)置成上拉輸入模式。
  • WK_UP與高電平相連,當按鍵按下的時候是高電平,所以這個按鍵要設(shè)置成下拉輸入模式。

key.h中的代碼:

#ifndef __KEY_H

#define __KEY_H
#include "stm32f10x.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
#define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)

#define KEY0_PRES 1
#define KEY1_PRES 2
#define KEY2_PRES 3
#define WK_UP_PRES 4

void KEY_Init(void);


#endif

key.c中的代碼:

#include "stm32f10x.h"
#include "key.h"
#include "delay.h"


void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructe;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//將GPIOA和GPIOE時鐘使能
	
	//KEY0到KEY2設(shè)置成上拉輸入模式
	GPIO_InitStructe.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructe.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_3|GPIO_Pin_2;
	GPIO_Init(GPIOE,&GPIO_InitStructe);
	
	//WK_UP設(shè)置成下拉輸入模式
	GPIO_InitStructe.GPIO_Mode=GPIO_Mode_IPD;
	GPIO_InitStructe.GPIO_Pin=GPIO_Pin_0;
	GPIO_Init(GPIOA,&GPIO_InitStructe);
	
	
}

??串口初始化

stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件
我們可以看到,USART1_TX端口復(fù)用引腳是PA9,USART1_RX端口復(fù)用引腳是PA10。
至于PB6和PB7是端口重映射引腳,一般情況下是使用不到的,有興趣的小伙伴可以看本喵的文章端口復(fù)用和重映像。
知道了串口是哪個引腳后我們需要對串口進行配置,讓CPU知道該引腳此時是當作串口的。
stm32按鍵中斷,STM32學(xué)習(xí),單片機,stm32,嵌入式硬件

  • 如上圖,我們使用的是全雙工模式,需要對將PA9端口配置成推挽復(fù)用輸出。對PA10配置成浮空或者上拉輸入。
  • 進行GPIOA和USART1的時鐘使能
  • 串口初始化配置
  • 中斷優(yōu)先級配置
  • 使能接收中斷
  • 打開串口

將串口配置好后就需要寫串口中斷服務(wù)函數(shù)了。
串口通信的的約定可以看本喵的文章串口實驗——簡單的數(shù)據(jù)收發(fā)。
本喵在這里就不詳細講解如何寫的了,直接上代碼:
usart.h中的代碼:

#include "sys.h"
#include "usart.h"	  
#if SYSTEM_SUPPORT_OS
#include "includes.h"					//ucos 使用	  
#endif
#ifndef __USART_H
#define __USART_H

#include "stdio.h"
#include "sys.h"

#define USART_REC_LEN  			200  	//定義最大接收字節(jié)數(shù) 200
#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收
extern u8  USART_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個字節(jié).末字節(jié)為換行符 
extern u16 USART_RX_STA;         		//接收狀態(tài)標記	
void uart_init(u32 bound);


#endif

usart.c中的代碼:

#if 1
#pragma import(__use_no_semihosting)             
//標準庫需要的支持函數(shù)                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定義_sys_exit()以避免使用半主機模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定義fputc函數(shù) 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循環(huán)發(fā)送,直到發(fā)送完畢   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 

/*使用microLib的方法*/
 /* 
int fputc(int ch, FILE *f)
{
	USART_SendData(USART1, (uint8_t) ch);

	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}	
   
    return ch;
}
int GetKey (void)  { 

    while (!(USART1->SR & USART_FLAG_RXNE));

    return ((int)(USART1->DR & 0x1FF));
}
*/
 
#if EN_USART1_RX   //如果使能了接收
//串口1中斷服務(wù)程序
//注意,讀取USARTx->SR能避免莫名其妙的錯誤   	
u8 USART_RX_BUF[USART_REC_LEN];     //接收緩沖,最大USART_REC_LEN個字節(jié).
//接收狀態(tài)
//bit15,	接收完成標志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字節(jié)數(shù)目
u16 USART_RX_STA=0;       //接收狀態(tài)標記	  
  
void uart_init(u32 bound)
{
	GPIO_InitTypeDef GPIO_InitStructe;
	USART_InitTypeDef USART_InitStructe;
	NVIC_InitTypeDef NVIC_InitStructe;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
	
	//PA9初始化為復(fù)用推挽輸出,復(fù)用為USART1_TX
	GPIO_InitStructe.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStructe.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructe.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA,&GPIO_InitStructe);
	
	//PA10初始化為浮空輸入,復(fù)用為USART1_RX
	GPIO_InitStructe.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStructe.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA,&GPIO_InitStructe);
	
	//USART1初始化
	USART_InitStructe.USART_BaudRate=bound;//波特率
	USART_InitStructe.USART_WordLength=USART_WordLength_8b;//字長為8個字節(jié)
	USART_InitStructe.USART_StopBits=USART_StopBits_1;//停止位1位
	USART_InitStructe.USART_Parity=USART_Parity_No;//沒有奇偶校驗位
	USART_InitStructe.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//接收和發(fā)送
	USART_InitStructe.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//五硬件流控制
	USART_Init(USART1,&USART_InitStructe);
	
	//中斷優(yōu)先級初始化
	NVIC_InitStructe.NVIC_IRQChannel=USART1_IRQn;//USART1通道中斷
	NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority=3;//搶占優(yōu)先級是3
	NVIC_InitStructe.NVIC_IRQChannelSubPriority=3;//響應(yīng)優(yōu)先級是3
	NVIC_InitStructe.NVIC_IRQChannelCmd=ENABLE;//通道使能
	NVIC_Init(&NVIC_InitStructe);
	
	//接收中斷使能
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	//使能USART1
	USART_Cmd(USART1,ENABLE);
}

void USART1_IRQHandler(void)
{
	u8 res=0;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
	OSIntEnter();    
#endif
	//判斷是否發(fā)生接收中斷
	if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
	{
		res=USART_ReceiveData(USART1);//接收讀取到的數(shù)據(jù)
		if((USART_RX_STA&0x8000)==0)//接收是否未完成
		{
			if(USART_RX_STA&0x4000)//是否接收到了0x0d
			{
				//如果接收到的是0x0a
				if(res!=0x0a)
					USART_RX_STA=0;//如果不是,說明接收錯誤,整個標志位清0
				else
					USART_RX_STA|=0x8000;//接收完成了
			}
			else//還沒有接收到0x0d
			{
				//如果接收到的是0x0d
				if(res==0x0d)
					USART_RX_STA|=0x0400;//接收0x0d標志位置1
				else//接收到的不是0x0d
				{
					//將接收到的數(shù)據(jù)存到數(shù)組中
					USART_RX_BUF[USART_RX_STA&0x3FFF]=res;
					USART_RX_STA++;
					//如果數(shù)據(jù)個數(shù)大于最大接收長度
					if(USART_RX_STA>(USART_REC_LEN-1))
						USART_RX_STA=0;//接收錯誤,標志位清0
				}
			}
		}
	}
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
	OSIntExit();  											 
#endif
}
#endif	

??外部中斷初始化

接下來就是最重要的一步了,外部中斷的初始化

  1. 使能用到的GPIO口

這里我們用到與按鍵相連的PE4,PE3,PE2,PA0四個GPIO口

  1. 將使用到的GPIO設(shè)置成輸入模式

  2. 使能AFIO寄存器時鐘

該寄存器控制著中斷線的映射,所以必須使能

  1. 設(shè)置外部中斷線的映射關(guān)系
  • EXIT4映射到PE4
  • EXIT3映射到PE3
  • EXIT2映射到PE2
  • EXIT0映射到PA0
  1. 外部中斷初始化
  • PE4,PE3,PE2這3個IO口采用的是上拉輸入模式,當有按鍵按下時,該IO口是低電平
  • 所以3個IO口要設(shè)置成下降沿觸發(fā)中斷。
  • PA0采用的是下拉輸入模式,當有鍵按下時,該IO口是高電平
  • 所以PA0要設(shè)置成上升沿觸發(fā)中斷。
  1. 中斷優(yōu)先級初始化
  • 中斷通道是EXIT0,EXIT4,EXIT3,EXIT2,一共4個通道
  • 搶占優(yōu)先級全部設(shè)成2
  • 響應(yīng)優(yōu)先級全部設(shè)成2
  • 使能中斷通道
  1. 編寫中斷服務(wù)函數(shù)
  • 外部中斷線0對應(yīng)的是WK_UP鍵的中斷,當鍵按下后蜂鳴器的狀態(tài)發(fā)生反轉(zhuǎn)。
  • 外部中斷線4對應(yīng)的是KEY0鍵的中斷,當鍵按下后倆個LED的狀態(tài)同時發(fā)生反轉(zhuǎn)。
  • 外部中斷線3對應(yīng)的是KEY1鍵的中斷,當鍵按下后LED0的狀態(tài)發(fā)生反轉(zhuǎn)。
  • 外部中斷線2對應(yīng)的是KEY2鍵的中斷,當鍵按下后LED1的狀態(tài)發(fā)生反轉(zhuǎn)。
  1. 清除中斷標志位

外部中斷的中斷標志位在發(fā)生中斷后會由硬件置1,但是在執(zhí)行完中斷服務(wù)函數(shù)后硬件不會自動清零,所以需要我們手動在中斷服務(wù)函數(shù)的最后將標志位清0。

exit.h中的代碼:

#ifndef __EXIT_H
#define __EXIT_H

void EXIT_Init(void);

#endif

exit.c中的代碼:

#include "exit.h"
#include "stm32f10x.h"
#include "led.h"
#include "beep.h"
#include "delay.h"
#include "key.h"

void EXIT_Init(void)
{
	EXTI_InitTypeDef EXTI_InitStructe;
	NVIC_InitTypeDef NVIC_InitStructe;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA和GPIOE組的時鐘
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能AFIO時鐘
	
	KEY_Init();
	
	//外部中斷線4初始化
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);//exit4
	EXTI_InitStructe.EXTI_Line=EXTI_Line4;//中斷線4
	EXTI_InitStructe.EXTI_LineCmd=ENABLE;
	EXTI_InitStructe.EXTI_Mode=EXTI_Mode_Interrupt;//模式是中斷
	EXTI_InitStructe.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿觸發(fā)方式
	EXTI_Init(&EXTI_InitStructe);
	
	//外部中斷線3初始化
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);//exit3
	EXTI_InitStructe.EXTI_Line=EXTI_Line3;//中斷線3
	EXTI_Init(&EXTI_InitStructe);
	
	//外部中斷線2初始化
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);//exit2
	EXTI_InitStructe.EXTI_Line=EXTI_Line2;//中斷線2
	EXTI_Init(&EXTI_InitStructe);
	
	//外部中斷線0初始化
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//exit0
	EXTI_InitStructe.EXTI_Line=EXTI_Line0;//中斷線0
	EXTI_InitStructe.EXTI_Trigger=EXTI_Trigger_Rising;//上升沿觸發(fā)方式
	EXTI_Init(&EXTI_InitStructe);
	
	//中斷初始化
	NVIC_InitStructe.NVIC_IRQChannel=EXTI0_IRQn;//通道外部通道0
	NVIC_InitStructe.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority=0x02;//搶占優(yōu)先級全部設(shè)成2
	NVIC_InitStructe.NVIC_IRQChannelSubPriority=0x00;//響應(yīng)優(yōu)先級全部設(shè)成2
	
	NVIC_Init(&NVIC_InitStructe);
	NVIC_InitStructe.NVIC_IRQChannel=EXTI4_IRQn;//通道外部通道4
	NVIC_InitStructe.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority=0x02;//搶占優(yōu)先級全部設(shè)成2
	NVIC_InitStructe.NVIC_IRQChannelSubPriority=0x01;//響應(yīng)優(yōu)先級全部設(shè)成2
	NVIC_Init(&NVIC_InitStructe);
	NVIC_InitStructe.NVIC_IRQChannel=EXTI3_IRQn;//通道外部通道3
	NVIC_InitStructe.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority=0x02;//搶占優(yōu)先級全部設(shè)成2
	NVIC_InitStructe.NVIC_IRQChannelSubPriority=0x02;//響應(yīng)優(yōu)先級全部設(shè)成2
	NVIC_Init(&NVIC_InitStructe);
	NVIC_InitStructe.NVIC_IRQChannel=EXTI2_IRQn;//通道外部通道2
	NVIC_InitStructe.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructe.NVIC_IRQChannelPreemptionPriority=0x02;//搶占優(yōu)先級全部設(shè)成2
	NVIC_InitStructe.NVIC_IRQChannelSubPriority=0x03;//響應(yīng)優(yōu)先級全部設(shè)成2
	NVIC_Init(&NVIC_InitStructe);
}

void EXTI0_IRQHandler(void)
{
	delay_ms(10);//延時消抖
	//確定是否是WK_UP鍵按下
	if(WK_UP==1)
	{
		beep=!beep;//蜂鳴器狀態(tài)發(fā)生反轉(zhuǎn)
	}
	EXTI_ClearITPendingBit(EXTI_Line0);
}

void EXTI4_IRQHandler(void)
{
	delay_ms(10);//延時消抖
	//確定是否是KEY0鍵按下
	if(KEY0==0)
	{
		LED0=!LED0;
		LED1=!LED1;//倆個LED燈狀態(tài)同時反轉(zhuǎn)
	}
	EXTI_ClearITPendingBit(EXTI_Line4);
}

void EXTI3_IRQHandler(void)
{
	delay_ms(10);//延時消抖
	//確定是否是KEY1鍵按下
	if(KEY1==0)
	{
		LED0=!LED0;//LED0狀態(tài)發(fā)生反轉(zhuǎn)
	}
	EXTI_ClearITPendingBit(EXTI_Line3);
}

void EXTI2_IRQHandler(void)
{
	delay_ms(10);//延時消抖
	//確定是否是KEY2鍵按下
	if(KEY2==0)
	{
		LED1=!LED1;//LED1狀態(tài)發(fā)生反轉(zhuǎn)
	}
	EXTI_ClearITPendingBit(EXTI_Line2);
}

??效果展示

由于上傳視頻需要比較長的時間,該實驗的效果和控制LED燈和蜂鳴器實驗的效果一樣,實驗中的串口部分效果和串口實驗——簡單數(shù)據(jù)收發(fā)的效果一樣。
想看實驗結(jié)果的小伙伴可以移步到上面提到的倆篇文章。文章來源地址http://www.zghlxwxcb.cn/news/detail-752623.html

到了這里,關(guān)于【STM32】外部中斷實現(xiàn)按鍵實驗的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • STM32F429IGT6使用CubeMX配置外部中斷按鍵

    STM32F429IGT6使用CubeMX配置外部中斷按鍵

    1、硬件電路 2、設(shè)置RCC,選擇高速外部時鐘HSE,時鐘設(shè)置為180MHz 3、配置GPIO引腳? 4、NVIC配置 ?PC13相同 ? 5、生成工程配置 ? 6、部分代碼 中斷回調(diào)函數(shù) 7、實驗現(xiàn)象

    2024年02月13日
    瀏覽(29)
  • STM32G030C8T6:使用按鍵控制LED亮滅(外部中斷)

    STM32G030C8T6:使用按鍵控制LED亮滅(外部中斷)

    本專欄記錄STM32開發(fā)各個功能的詳細過程,方便自己后續(xù)查看,當然也供正在入門STM32單片機的兄弟們參考; 本小節(jié)的目標是,系統(tǒng)主頻64 MHZ,采用高速外部晶振,通過KEY1 按鍵的PA0 引腳配置成中斷輸入引腳,PB9引腳配置成輸出,每次按鍵,PA0 引腳就會進入一次外部中斷,每進

    2024年02月05日
    瀏覽(25)
  • 基于STM32CubeMX與keil采用按鍵外部中斷方式控制LED與蜂鳴器

    基于STM32CubeMX與keil采用按鍵外部中斷方式控制LED與蜂鳴器

    這篇文章詳細記錄外部中斷方式控制LED的亮滅以及蜂鳴器的開關(guān);本文從原理圖開始到最后實現(xiàn)功能,內(nèi)容詳細。 本欄目的所有都是基于STM32F407ZET6芯片,博主采用的是普中的天馬F407開發(fā)板。 實現(xiàn)功能:LED0與LED1默認熄滅,蜂鳴器默認關(guān)閉。按下按鍵KEY0,控LED0亮滅;按下按

    2024年02月16日
    瀏覽(23)
  • STM32單片機(五)第二節(jié):EXTI外部中斷練習(xí)2(旋轉(zhuǎn)編碼器計次)

    STM32單片機(五)第二節(jié):EXTI外部中斷練習(xí)2(旋轉(zhuǎn)編碼器計次)

    ?? 專欄簡介:本專欄記錄了從零學(xué)習(xí)單片機的過程,其中包括51單片機和STM32單片機兩部分;建議先學(xué)習(xí)51單片機,其是STM32等高級單片機的基礎(chǔ);這樣再學(xué)習(xí)STM32時才能融會貫通。 ?? 專欄適用人群 :適用于想要從零基礎(chǔ)開始學(xué)習(xí)入門單片機,且有一定C語言基礎(chǔ)的的童鞋

    2024年02月11日
    瀏覽(25)
  • 【STM32】STM32學(xué)習(xí)筆記-EXTI外部中斷(11)

    【STM32】STM32學(xué)習(xí)筆記-EXTI外部中斷(11)

    中斷 :在主程序運行過程中,出現(xiàn)了特定的中斷觸發(fā)條件(中斷源),使得CPU暫停當前正在運行的程序,轉(zhuǎn)而去處理中斷程序,處理完成后又返回原來被暫停的位置繼續(xù)運行 中斷優(yōu)先級 :當有多個中斷源同時申請中斷時,CPU會根據(jù)中斷源的輕重緩急進行裁決,優(yōu)先響應(yīng)更加

    2024年02月04日
    瀏覽(21)
  • 【STM32學(xué)習(xí)筆記】(13)——外部中斷詳解

    【STM32學(xué)習(xí)筆記】(13)——外部中斷詳解

    ????????EXTI(External interrupt/event controller)—外部中斷/事件控制器 ,管理了控制器的 20 個中斷/事件線。每個輸入線可以獨立地配置輸入類型(脈沖 或掛起)和對應(yīng)的觸發(fā)事件(上升沿或下降沿或者雙邊沿都觸發(fā))。EXTI 可以實現(xiàn)對每個中斷/事件線進行單獨配置,可以單獨配置

    2024年02月05日
    瀏覽(22)
  • STM32單片機(六)TIM定時器 -> 第二節(jié):TIM定時中斷練習(xí)(定時器定時中斷和定時器外部時鐘)

    STM32單片機(六)TIM定時器 -> 第二節(jié):TIM定時中斷練習(xí)(定時器定時中斷和定時器外部時鐘)

    ?? 專欄簡介:本專欄記錄了從零學(xué)習(xí)單片機的過程,其中包括51單片機和STM32單片機兩部分;建議先學(xué)習(xí)51單片機,其是STM32等高級單片機的基礎(chǔ);這樣再學(xué)習(xí)STM32時才能融會貫通。 ?? 專欄適用人群 :適用于想要從零基礎(chǔ)開始學(xué)習(xí)入門單片機,且有一定C語言基礎(chǔ)的的童鞋

    2024年02月09日
    瀏覽(31)
  • stm32學(xué)習(xí)筆記-5EXIT外部中斷

    stm32學(xué)習(xí)筆記-5EXIT外部中斷

    注:筆記主要參考B站 江科大自化協(xié) 教學(xué)視頻“STM32入門教程-2023持續(xù)更新中”。 注:工程及代碼文件放在了本人的Github倉庫。 圖5-1 中斷及中斷嵌套示意圖 中斷 是指在主程序運行過程中,出現(xiàn)了特定的中斷觸發(fā)條件(中斷源),使得CPU暫停當前正在運行的程序,轉(zhuǎn)而去處理

    2024年02月09日
    瀏覽(15)
  • stm32——hal庫學(xué)習(xí)筆記(外部中斷)

    stm32——hal庫學(xué)習(xí)筆記(外部中斷)

    一、什么是中斷?(了解) 打斷CPU執(zhí)行正常的程序,轉(zhuǎn)而處理緊急程序,然后返回原暫停的程序繼續(xù)運行,就叫中斷 中斷的作用和意義 中斷的意義:高效處理緊急程序,不會一直占用CPU資源 STM32 GPIO外部中斷簡圖 二、NVIC(熟悉) 2.1,NVIC基本概念 2.2,NVIC相關(guān)寄存器介紹

    2024年02月22日
    瀏覽(23)
  • STM32CubeMX學(xué)習(xí)三 之外部中斷

    STM32CubeMX學(xué)習(xí)三 之外部中斷

    記錄一下STM32CubeMX的學(xué)習(xí)筆記,同時分享給初學(xué)的小白,希望一起進步。 如何使用STM32CubeMX以及工程創(chuàng)建在之前的博客有提到,這里就直接從外部中斷講起。 編譯環(huán)境:KEIL 代碼生成:STM32CubeMX 庫:HAL MCU:STM32F072 假設(shè)你的cubeMX工程已經(jīng)建好,這里我們配置KEY1、KEY2、KEY3三個按

    2023年04月08日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包