基于stmf103的外部中断实验
文章目录
外部中断
中断就是主程序在正常执行时,CPU发出一个中断请求,然后程序就会跳到中断子程序去执行,执行完后会返回主程序。
一、概述
组成结构
1-15中断号用于系统异常
16开始是外部中断
<font color=#999AAA GPIO与中断线的映射关系
1、GPIO引脚0对应的是外部中断0
2、一个中断对应了9个IO口(PA0~PA9)
3、同一时刻一个中断只能对应一个IO口,不能PA0链接了外部中断0,PB0再链接外部中断0
二、使用步骤
1.GPIO端口设置为外部中断输入----参考stm32f10x_gpio.c
代码如下(示例):
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
2.把引脚与EXIT0链接----参考stm32f10x_gpio.c
代码如下(示例):
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
函数原型:
/**
* @brief Selects the GPIO pin used as EXTI Line.
* @param GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.
* This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).
* @param GPIO_PinSource: specifies the EXTI line to be configured.
* This parameter can be GPIO_PinSourcex where x can be (0..15).
* @retval None
*/
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
{
uint32_t tmp = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));
assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));
AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;
AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
}
3.EXIT配置----参考stm32f10x_exti.c
代码如下(示例):
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
EXTI_InitTypeDef 初始化结构体成员:
/**
* @brief EXTI Init Structure definition
*/
typedef struct
{
uint32_t EXTI_Line; /*中断线标号范围 0-15*/
EXTIMode_TypeDef EXTI_Mode; /*中断模式/事件模式*/
EXTITrigger_TypeDef EXTI_Trigger; /*中断触发方式 上升沿、下降沿、双边沿都触发*/
FunctionalState EXTI_LineCmd; /*中断线使能/不使能*/
}EXTI_InitTypeDef;
①中断模式 EXTIMode_TypeDef
/**
* @brief EXTI mode enumeration
*/
typedef enum
{
EXTI_Mode_Interrupt = 0x00,//中断
EXTI_Mode_Event = 0x04//事件
}EXTIMode_TypeDef;
②中断触发方式结构体 EXTITrigger_TypeDef
/**
* @brief EXTI Trigger enumeration
*/
typedef enum
{
EXTI_Trigger_Rising = 0x08,//上升沿触发
EXTI_Trigger_Falling = 0x0C,//下降沿
EXTI_Trigger_Rising_Falling = 0x10///*//双边沿都触发
}EXTITrigger_TypeDef;
4.NVIC中断优先级配置------参考misc.c
代码如下(示例):
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
中断优先级管理结构体 NVIC_InitTypeDef
/**
* @brief NVIC Init Structure definition
*/
typedef struct
{
uint8_t NVIC_IRQChannel; /*使能按 键外部中断通道*/
uint8_t NVIC_IRQChannelPreemptionPriority; /*抢占优先级 2*/
uint8_t NVIC_IRQChannelSubPriority; /*响应优先级 2 */
FunctionalState NVIC_IRQChannelCmd; /*使能/不使能 */
} NVIC_InitTypeDef;
抢占优先级
EXIT0 最高优先级
/************************************************
函数功能:中断0优先级配置函数
************************************************/
void Nvic0_Config(void)
{
/*中断优先级配置*/
NVIC_InitTypeDef NVIC_InitStruct;//配置中断分组NVIC
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
EXIT3------响应优先级2
/************************************************
函数功能:中断3优先级配置函数
************************************************/
void Nvic3_Config(void)
{
/*中断优先级配置*/
NVIC_InitTypeDef NVIC_InitStruct;//配置中断分组NVIC
NVIC_InitStruct.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
EXIT4—响应优先级1
/************************************************
函数功能:中断4优先级配置函数
************************************************/
void Nvic4_Config(void)
{
/*中断优先级配置*/
NVIC_InitTypeDef NVIC_InitStruct;//配置中断分组NVIC
NVIC_InitStruct.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;//响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
EXIT3:绿灯 响应优先级0x01
EXIT4:红灯 0x02
外部中断0先按下,然后依次按下外部中断4,外部中断3,CPU记录下中断。
现象:
LED绿灯亮起,后LED红灯亮起。
5.中断服务函数(中断后你想让CPU做的事情)
部分代码如下(示例):
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; Tamper
DCD RTC_IRQHandler ; RTC
DCD FLASH_IRQHandler ; Flash
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line 0
DCD EXTI1_IRQHandler ; EXTI Line 1
DCD EXTI2_IRQHandler ; EXTI Line 2
DCD EXTI3_IRQHandler ; EXTI Line 3
DCD EXTI4_IRQHandler ; EXTI Line 4
三、应用实例
EXIT.c
/************************************************
函数功能:中断初始化函数
************************************************/
void EXIT_Init(void)//初始化
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
KEY_Init();
Exit9_5_Config();
Nvic_Config();
}
/************************************************
函数功能:EXIT中断配置函数
************************************************/
void Exit9_5_Config(void)
{
//初始的结构体定义
EXTI_InitTypeDef EXTI_InitStruct;//中断初始化的结构体
//将引脚与中断链接
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
EXTI_InitStruct.EXTI_Line = EXTI_Line4;//外部中断4
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;//任意电平
EXTI_InitStruct.EXTI_LineCmd = ENABLE;//使能
EXTI_Init(&EXTI_InitStruct);
}
/************************************************
函数功能:中断优先级配置函数
************************************************/
void Nvic_Config(void)
{
/*中断优先级配置*/
NVIC_InitTypeDef NVIC_InitStruct;//配置中断分组NVIC
NVIC_InitStruct.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
/************************************************
函数功能:中断服务函数
************************************************/
void EXTI4_IRQHandler(void)
{
//判断是否有中断请求
delay_ms(10);//消抖
if(PEin(4)==1)
{
PEout(5) = 0;
}
EXTI_ClearITPendingBit(EXTI_Line4); //清除LINE0上的中断标志位
}
main.c
/************************************************
外部中断点亮LED
************************************************/
int main(void)
{
delay_init();//延时函数
LED_Init();
//KEY_Init();
EXIT_Init();
while(1)
{
}
}
总结
注意:
1.要开启RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
2.将引脚链接到中断