野火F1开发板STM32案例-外部中断(按键)使用
硬件平台
野火STM32F103ZET6 霸道V2开发板正点原子F1系列开发板
软件平台
Keil MDK 5.31串口调试助手
工程下载https://download.csdn.net/download/weixin_43599390/12910397
Gitee st-demo.
中断相关概念
中断配置寄存器
# 配置中断时,使用ISER、 ICER 和 IP 寄存器,
## ISER 是中断使能寄存器
## ICER 是中断清除寄存器
## IP 是中断优先级寄存器
中断优先级
1. 数值越小,优先级越高
2. STM32F103 中只使用
4位,高
4位有效。
3. 用于表达优先级的高
4 位又被分组成抢占式优先级和响应优先级,称为“亚优先级”或“副优先级”
4. 每个中断源都需要被指定这两种优先级。
中断配置步骤
1.使能外设中断
6. 设置中断优先级分组
初始化 NVIC_InitTypeDef 结构体,设置抢占优先级和响应优先级,使能中断请求。
typedef struct
{
uint8_t NVIC_IRQChannel
;
uint8_t NVIC_IRQChannelPreemptionPriority
;
uint8_t NVIC_IRQChannelSubPriority
;
FunctionalState NVIC_IRQChannelCmd
;
} NVIC_InitTypeDef
;
NVIC_IRQChannel 中断源
:中断源的设置,不同的外设中断,中断源不一样
NVIC_IRQChannelPreemptionPriority
NVIC_IRQChannelSubPriority
NVIC_IRQChannelCmd
NVIC_IRQChannel
NonMaskableInt_IRQn
= -14,
MemoryManagement_IRQn
= -12,
BusFault_IRQn
= -11,
UsageFault_IRQn
= -10,
SVCall_IRQn
= -5,
DebugMonitor_IRQn
= -4,
PendSV_IRQn
= -2,
SysTick_IRQn
= -1,
WWDG_IRQn
= 0,
PVD_IRQn
= 1,
TAMPER_IRQn
= 2,
RTC_IRQn
= 3,
FLASH_IRQn
= 4,
RCC_IRQn
= 5,
EXTI0_IRQn
= 6,
EXTI1_IRQn
= 7,
EXTI2_IRQn
= 8,
EXTI3_IRQn
= 9,
EXTI4_IRQn
= 10,
DMA1_Channel1_IRQn
= 11,
DMA1_Channel2_IRQn
= 12,
DMA1_Channel3_IRQn
= 13,
DMA1_Channel4_IRQn
= 14,
DMA1_Channel5_IRQn
= 15,
DMA1_Channel6_IRQn
= 16,
DMA1_Channel7_IRQn
= 17,
STM32F103 中断向量表
EXTI外部中断
1. STM32F10x 外部中断
/事件控制器(EXTI)包含多达
20 个用于产生事件
/中断请求的边沿检测器。
2. EXTI 的每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、下降沿触发或边沿触发)
还可独立地被屏蔽。
3. EXIT功能
:产生中断
;产生事件
.
STM32 EXIT框架图
EXTI外部中断步骤
使能I0口时钟,配置I0口模式为输入开启AFIO时钟,设置I0口与中断线的映射关系配置中断分组(NVIC),使能中断初始化EXTI,选择触发方式编写EXTI中断服务函数
GPIO引脚配置(本文中和外部中断bsp_exit.h一起进行初始化,可以分开进行配置相关函数)
(一般配置过程类似,无论使用什么外设,UART,IIC,SPI,ADC 一般情况都要GPIO初始化)
# GPIO输入模式
void initKey(void)
{
GPIO_InitTypeDef GPIO_InitStructure
;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
, ENABLE
);
GPIO_InitStructure
.GPIO_Pin
= KEY_UP_PIN
|KEY_DOWN_PIN
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_IPU
;
GPIO_Init(GPIOA
, &GPIO_InitStructure
);
}
# GPIO输出模式
void initLED(void)
{
GPIO_InitTypeDef GPIO_InitStructure
;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB
, ENABLE
);
GPIO_InitStructure
.GPIO_Pin
= GPIO_Pin_5
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_Out_PP
;
GPIO_InitStructure
.GPIO_Speed
= GPIO_Speed_50MHz
;
GPIO_Init(GPIOB
, &GPIO_InitStructure
);
GPIO_ResetBits(GPIOB
, GPIO_Pin_5
);
}
配置嵌套向量中断控制器NVIC步骤
定义NVIC结构体 NVIC_InitTypeDef 结构体
typedef struct
{
uint8_t NVIC_IRQChannel
;
uint8_t NVIC_IRQChannelPreemptionPriority
;
uint8_t NVIC_IRQChannelSubPriority
;
FunctionalState NVIC_IRQChannelCmd
;
} NVIC_InitTypeDef
;
配置NVIC为优先级组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1
);
配置中断源
NVIC_InitStructure
.NVIC_IRQChannel
= KEY1_INT_EXTI_IRQ
;
配置抢占优先级
NVIC_InitStructure
.NVIC_IRQChannelPreemptionPriority
= 1;
配置子优先级
NVIC_InitStructure
.NVIC_IRQChannelSubPriority
= 1;
使能中断通道
NVIC_InitStructure
.NVIC_IRQChannelCmd
= ENABLE
;
初始化NVIC
NVIC_Init(&NVIC_InitStructure
);
配置 EXTI中断口,并设置中断优先级步骤流程
1. 定义GPIO_InitTypeDef EXTI_InitTypeDef 结构体
GPIO_InitTypeDef GPIO_InitStructure
;
EXTI_InitTypeDef EXTI_InitStructure
;
typedef struct
{
uint16_t GPIO_Pin
;
GPIOSpeed_TypeDef GPIO_Speed
;
GPIOMode_TypeDef GPIO_Mode
;
}GPIO_InitTypeDef
;
typedef struct
{
uint32_t EXTI_Line
;
EXTIMode_TypeDef EXTI_Mode
;
EXTITrigger_TypeDef EXTI_Trigger
;
FunctionalState EXTI_LineCmd
;
}EXTI_InitTypeDef
;
RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK
,ENABLE
);
NVIC_Configuration();
GPIO引脚配置
GPIO_InitStructure
.GPIO_Pin
= KEY1_INT_GPIO_PIN
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_IN_FLOATING
;
GPIO_Init(KEY1_INT_GPIO_PORT
, &GPIO_InitStructure
);
GPIO_InitStructure
.GPIO_Pin
= KEY2_INT_GPIO_PIN
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_IN_FLOATING
;
GPIO_Init(KEY2_INT_GPIO_PORT
, &GPIO_InitStructure
);
中断配置
中断信号源EXIT模式外部中断触发类型使能中断EXIT中断初始化
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE
, KEY1_INT_EXTI_PINSOURCE
);
EXTI_InitStructure
.EXTI_Line
= KEY1_INT_EXTI_LINE
;
EXTI_InitStructure
.EXTI_Mode
= EXTI_Mode_Interrupt
;
EXTI_InitStructure
.EXTI_Trigger
= EXTI_Trigger_Rising
;
EXTI_InitStructure
.EXTI_LineCmd
= ENABLE
;
EXTI_Init(&EXTI_InitStructure
);
BSP_EXIT.H
#define KEY1_INT_GPIO_PORT GPIOA
#define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO)
#define KEY1_INT_GPIO_PIN GPIO_Pin_0
#define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0
#define KEY1_INT_EXTI_LINE EXTI_Line0
#define KEY1_INT_EXTI_IRQ EXTI0_IRQn
#define KEY1_IRQHandler EXTI0_IRQHandler
#define KEY2_INT_GPIO_PORT GPIOC
#define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO)
#define KEY2_INT_GPIO_PIN GPIO_Pin_13
#define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOC
#define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource13
#define KEY2_INT_EXTI_LINE EXTI_Line13
#define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn
#define KEY2_IRQHandler EXTI15_10_IRQHandler
BSP_EXIT.C
配置嵌套向量中断控制器NVIC
#include “bsp_exit.h”
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure
;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1
);
NVIC_InitStructure
.NVIC_IRQChannel
= KEY1_INT_EXTI_IRQ
;
NVIC_InitStructure
.NVIC_IRQChannelPreemptionPriority
= 1;
NVIC_InitStructure
.NVIC_IRQChannelSubPriority
= 1;
NVIC_InitStructure
.NVIC_IRQChannelCmd
= ENABLE
;
NVIC_Init(&NVIC_InitStructure
);
NVIC_InitStructure
.NVIC_IRQChannel
= KEY2_INT_EXTI_IRQ
;
NVIC_Init(&NVIC_InitStructure
);
}
配置 IO为EXTI中断口,并设置中断优先级
void EXTI_Key_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure
;
EXTI_InitTypeDef EXTI_InitStructure
;
RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK
,ENABLE
);
NVIC_Configuration();
GPIO_InitStructure
.GPIO_Pin
= KEY1_INT_GPIO_PIN
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_IN_FLOATING
;
GPIO_Init(KEY1_INT_GPIO_PORT
, &GPIO_InitStructure
);
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE
, KEY1_INT_EXTI_PINSOURCE
);
EXTI_InitStructure
.EXTI_Line
= KEY1_INT_EXTI_LINE
;
EXTI_InitStructure
.EXTI_Mode
= EXTI_Mode_Interrupt
;
EXTI_InitStructure
.EXTI_Trigger
= EXTI_Trigger_Rising
;
EXTI_InitStructure
.EXTI_LineCmd
= ENABLE
;
EXTI_Init(&EXTI_InitStructure
);
GPIO_InitStructure
.GPIO_Pin
= KEY2_INT_GPIO_PIN
;
GPIO_InitStructure
.GPIO_Mode
= GPIO_Mode_IN_FLOATING
;
GPIO_Init(KEY2_INT_GPIO_PORT
, &GPIO_InitStructure
);
GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE
, KEY2_INT_EXTI_PINSOURCE
);
EXTI_InitStructure
.EXTI_Line
= KEY2_INT_EXTI_LINE
;
EXTI_InitStructure
.EXTI_Mode
= EXTI_Mode_Interrupt
;
EXTI_InitStructure
.EXTI_Trigger
= EXTI_Trigger_Falling
;
EXTI_InitStructure
.EXTI_LineCmd
= ENABLE
;
EXTI_Init(&EXTI_InitStructure
);
}
中断服务函数
#include "stm32f10x_it.h"
#include "bsp_test.h"
void KEY1_IRQHandler(void)
{
if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE
) != RESET
)
{
LED1_TOGGLE
;
BSP_KEY1_EXIT_LCDTEST();
USART_SendString(USART1
,"KEY1 EXIT www.delehub.top");
USART_SendLine(USART1
);
EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE
);
}
}
void KEY2_IRQHandler(void)
{
if(EXTI_GetITStatus(KEY2_INT_EXTI_LINE
) != RESET
)
{
LED2_TOGGLE
BSP_KEY2_EXIT_LCDTEST();
USART_SendString(USART1
,"KEY2 EXIT 2020-10-03 14:50");
USART_SendLine(USART1
);
EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE
);
}
}
按键外部中断测试函数
void BSP_KEY1_EXIT_LCDTEST(void)
{
LCD_SetFont(&Font8x16
);
LCD_SetColors(RED
,WHITE
);
ILI9341_Clear(0,0,LCD_X_LENGTH
,LCD_Y_LENGTH
);
ILI9341_DispStringLine_EN(LINE(0),"2020-10-03 14:30 BSP_EXIT_TEST");
ILI9341_DispStringLine_EN(LINE(1),"KEY1 EXIT TEST");
LCD_SetTextColor(RED
);
ILI9341_DrawCircle(100,200,20,1);
}
void BSP_KEY2_EXIT_LCDTEST(void)
{
LCD_SetFont(&Font8x16
);
LCD_SetColors(RED
,WHITE
);
ILI9341_Clear(0,0,LCD_X_LENGTH
,LCD_Y_LENGTH
);
ILI9341_DispStringLine_EN(LINE(3),"2020-10-03 14:30 DELEHUB");
ILI9341_DispStringLine_EN(LINE(4),"KEY2 EXIT TEST");
LCD_SetTextColor(GREEN
);
ILI9341_DrawCircle(100,200,40,0);
}
MAIN.C
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_key.h"
#include "bsp_beep.h"
#include "bsp_exit.h"
#include "timer.h"
#include "bsp_ili9341_lcd.h"
#include "bsp_SysTick.h"
#include "bsp_usart.h"
#include <stdio.h>
#include "bsp_test.h"
#include "STM32F103xxxx_USART.H"
void HardWare_Iint(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2
);
EXTI_Key_Config();
LED_Iint();
Key_Iint();
Beep_Init();
ILI9341_Init();
USART_Configure();
}
int main(void)
{
HardWare_Iint();
while(1)
{
}
}
串口打印效果
TFT显示效果
博客地址https://delehub.vercel.app/