欢迎入群共同学习交流
时间记录:2023/12/2
一、基础知识介绍
- 外部中断:简单易懂的理解就是你在吃饭,这时候有人给你打电话(中断请求),然后你先去接起电话(中断响应),打完电话后接着回来吃饭(中断返回),当然中间还有一个多中断同时发生时根据中断优先级进行选择的步骤
- 配置步骤
(1) 使能GPIO口时钟配置为输出模式
(2) 使能AFIO时钟,绑定外部中断线
stm32f10x_gpio.c文件中的void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);函数绑定外部中断线
(3) 初始化外部中断EXTI
stm32f10x_exti.c文件中的void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);函数,关于EXTI_InitStruct变量为外部中断结构体,可设置中断线(Line)、使能中断线(Cmd)、触发模式(Mode)、触发方式(Trigger)
(4) 设置中断优先级组
misc.c文件中的void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);函数进行设置
(5) 初始化中断优先级NVIC
misc.c文件中的void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);函数进行设置,关于NVIC_InitStruct结构体,可以设置中断请求信道(Channel)、使能中断请求(Cmd)、抢占式优先级(PreemptionPriority)、响应式优先级(SubPriority),中断请求线在stm32f10x.h中查找
(6) 在stm32f10x_it.c文件中编写中断函数,或者将stm32f10x_it.h头文件包含,重写中断函数,中断函数的句柄在启动文件(.s)中查找
(7) ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);函数获取中断线状态
(8) void EXTI_ClearITPendingBit(uint32_t EXTI_Line);函数清除中断线中断标志
二、事例代码(GPIOA1为例)
1.头文件(.h)
#ifndef __KEY_H__
#define __KEY_H__
#include "stm32f10x.h"
#include "stm32f10x_it.h"
void vKeyInit(void);
#endif
2.源文件(.c)
#include "key.h"
void vKeyInit(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//2. 设置AFIO引脚的中断复用功能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能时钟
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);//绑定外部中断线
//3. 设置外部中断EXTI
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line = EXTI_Line1;//中断口
EXTI_InitStruct.EXTI_LineCmd = ENABLE;//开启EXTI中断
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//设置为中断模式
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
EXTI_Init(&EXTI_InitStruct);
//4.配置分配中断优先级NVIC
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;//中断请求线
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//允许中断
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级的优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;//响应优先级的优先级
NVIC_Init(&NVIC_InitStruct);
}
//设置中断函数
void EXTI1_IRQHandler(void)
{
//获取中断线状态
if(EXTI_GetITStatus(EXTI_Line1)==SET){
//软件复位
EXTI_ClearITPendingBit(EXTI_Line1);
}
}