STM32——中断应用概览

异常类型

系统异常(体现在内核)

外部中断(体现在外设)

NVIC简介

NVIC是嵌套向量中断控制器,属于内核外设,

优先级的定义

中断编程

1.使能中断请求

先配置外设的使能中断请求位,再配置NVIC的中断使能寄存器。
比须两个都使能,才能顺利地收到外设的中断请求。

2.配置中断优先级分组

3.配置NVIC寄存器,初始化NVIC_InitTypeDef

  1. 指定中断源
  2. 配置抢占优先级
  3. 配置子优先级
  4. 配置NVIC中断使能信号

4.编写中断服务函数

中断服务函数名

与启动文件中定义的中断服务函数名相同

中断服务函数位置

为了便于管理,中断服务函数全部放在stm32f10x_it.c文件中

EXTI简介

(External interrupt/event controller)外部中断/事件控制器,当GPIO电平发生跳变时,由EXTI来产生中断,再交给NVIC。

我们先来看EXTI框图,从框图的右下角可以看到一个输入线,中断就是从输入线进入EXTI的。

输入线总共有多少?

通过图中可以看到,输入线一共有20根,所以共由20个中断输入源,每一条输入线可以对应很多个端口

EXTI具体寄存器配置

通过配置EXTI上升沿或者下降沿触发选择寄存器,边缘检测电路就会对上升沿或下降沿进行检测,并输入1,

编程要点

初始化要连接到EXTI的GPIO

void GPIO_LED_Config()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2ENR_IOPBEN, ENABLE);
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void GPIO_KEY1_Config()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2ENR_IOPAEN, ENABLE);
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
}

GPIO的初始化没什么好讲的,已经写过很多次了

初始化EXTI用于产生中断/事件

void EXTI_Config()
{
	EXTI_InitTypeDef EXTI_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2ENR_AFIOEN, ENABLE); // 在配置EXTI使能信号时,我没有在结构体中找到EXTI,只找到AFIO
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//选择中断输入线
	EXTI_InitStruct.EXTI_Line = EXTI_Line0; // 中断/事件线
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//配置模式为中断
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;//配置触发方式
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;//使能中断线
	EXTI_Init(&EXTI_InitStruct);
}

在初始化EXTI时,往往容易漏掉选择中断输入线,这个需要额外注意。

其余配置与GPIO的配置流程差不多,定义结构体变量,对结构体内的属性进行赋值就行了。

初始化NVIC,用于处理中断

// 初始化完EXTI后,初始化NVIC
void NVIC_Config()
{
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//中断分组容易漏掉
	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; // 配置中断源
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//配置抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;//配置子优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能中断源
	NVIC_Init(&NVIC_InitStruct);
}

编写中断服务函数

void EXTI0_IRQHandler()
{
  if (EXTI_GetITStatus(EXTI_Line0) != RESET)//当中断线中发生中断
  {
    //LED灯状态翻转,由亮转灭、由灭转亮
    if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_1) == 0)
    {
      GPIO_SetBits(GPIOB, GPIO_Pin_1);
    }
    else
    {
      GPIO_ResetBits(GPIOB, GPIO_Pin_1);
    }
  }
  EXTI_ClearITPendingBit(EXTI_Line0);//清楚中断线的中断状态
}

中断服务函数需要写在stm32f10x_it.c文件中,并且函数名需要与启动文件中定义的中断名称一致。

main函数

int main()
{
	GPIO_LED_Config();
	GPIO_KEY1_Config();
	EXTI_Config();
	NVIC_Config();
}

在main函数中,只需要对上面几个函数进行调用就行了

欢迎关注微信公众号:计算机达人

请添加图片描述

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamerForLife

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值