STM32——中断
在我们在学习中断之前,先来谈谈什么是中断吧。
1.中断顾名思义就是暂停原先的程序或事情,执行另外一些程序或事情,执行完成后返回原来的程序。
2.因为另一些程序或事情比你原先正在做的事情要重要,或者这些突发事情你是无法控制它的来临的。所以我们需要时用中断来处理这些突发事件。
在写代码是我们需要先进行初始化配置:
//使能(打开)端口A的硬件时钟,就是对端口A供电
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
//使能系统配置时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//配置PA0引脚为输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //第0根引脚
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN; //输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //没有使能上下拉电阻
GPIO_Init(GPIOA,&GPIO_InitStructure);
//将PA0和EXTI0连接在一起
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
//外部中断的配置
EXTI_InitStructure.EXTI_Line = EXTI_Line0; //外部中断0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发,用于识别按键的按下;上升沿触发,用于检测按键的松开;
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //外部中断0的请求通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; //响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能该通道
NVIC_Init(&NVIC_InitStructure);
接下来我们需要进行编写中断服务函数,代码如下:
//判断是否有中断请求
if(EXTI_GetITStatus(EXTI_Line0) == SET)
{
//点亮LED1
PFout(9)=0;
//延时一会
delay();
//熄灭LED1
PFout(9)=1;
//延时一会
delay();
EXTI_ClearITPendingBit(EXTI_Line0);//清空标志位
上面代码中的清空标志位是告诉CPU,已经完成当前中断处理;可以响应新的中断请求 。
完整代码如下:
#include "stm32f4xx.h"
#include "sys.h"
static GPIO_InitTypeDef GPIO_InitStructure;
static EXTI_InitTypeDef EXTI_InitStructure;
static NVIC_InitTypeDef NVIC_InitStructure;
void delay(void)
{
uint32_t i=0x8000000;
while(i--);
}
void exti0_init(void)
{
//使能(打开)端口A的硬件时钟,就是对端口A供电
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
//使能系统配置时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//配置PA0引脚为输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //第0根引脚
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN; //输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//高速响应
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //没有使能上下拉电阻
GPIO_Init(GPIOA,&GPIO_InitStructure);
//将PA0和EXTI0连接在一起
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
//外部中断的配置
EXTI_InitStructure.EXTI_Line = EXTI_Line0; //外部中断0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发,用于识别按键的按下;上升沿触发,用于检测按键的松开;
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //外部中断0的请求通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; //响应优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能该通道
NVIC_Init(&NVIC_InitStructure);
}
int main(void)
{
//exti0初始化
exti0_init();
while(1)
{
}
}
void EXTI0_IRQHandler(void)
{
//判断是否有中断请求
if(EXTI_GetITStatus(EXTI_Line0) == SET)
{
//点亮LED1
PFout(9)=0;
//延时一会
delay();
//熄灭LED1
PFout(9)=1;
//延时一会
delay();
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
关于上文位带操作的代码,在上一节为带操作中已经有所提到了,大家可以翻看上一篇的文章进行学习。
最后我下个对大家说的是我们努力不一定能带了未来的成功,但是不努力是一定不可能成功的,在大家感觉学的有点累了的时候,不妨出去跑跑步,放松一下,同事也请大家记住:天生我材必有用,千金散尽还复来。
——致每一个为自己的理想而奋斗的青少年