0
点赞
收藏
分享

微信扫一扫

【韦东山】7天物联网智能家居实战训练营基础班-DAY4_中断系统

花姐的职场人生 2022-04-29 阅读 60

文章目录

一、什么是中断

1、中断的定义

中断的定义大家都很熟悉,是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行,如图所示。
在这里插入图片描述

2、中断的种类

中断的种类由ARM公司进行设计,不同的芯片之间的中断种类是不一样的,ARM的cortex—M3有256种中断,中断的来源有两种,但两种的表现的效果都是一样的:

  • 系统异常:由CPU内部产生的紧急事件,例如:非法指令
  • 外部中断:由外设产生的外部的紧急事件,例如:GPIO电平的变化、定时器溢出等

二、中断文件

1、中断向量表

这是STM32F103C8T6的中断向量表,由十种系统异常和六十种外部中断组成,其中:Reset(复位端)、NMI、HardFault(硬件异常)三个的优先级是负数,其他的优先级是正数。
在这里插入图片描述

2、在函数中位置

程序里,在startup_stm32f103xb.s文件中有中断向量表,里面有当前芯片所支持的中断。当发生中断时,会找到相应的中断处理函数的位置,执行中断函数。
在这里插入图片描述

三、中断优先级

中断优先级由NVIC(Nested Vectored lnterrupt Controller)管理所有的中断,包括系统异常和外部中断,优先级由两者组成,优先级值越小优先级高,负数的不能修改,正数不能变成负数

  • 抢占优先级:中断嵌套
  • 子优先级:相应顺序在这里插入图片描述
    优先级中的顺序问题:
  1. 抢占优先级高的中断可以中断抢占优先级低的中断:先比较抢占优先级
  2. 两个中断的抢占优先级相同,后来中断要等前面的中断处理完:抢占优先级相同,已经在执行的,即使后面的子优先级大,也要等待
  3. 两个中断的抢占优先级相同,同时产生,子优先级高的先执行:抢占优先级相同,同时产生子优先级高的先执行
  4. 抢占优先级、子优先级相同,同时产生,由中断向量表默认位置决定:抢占优先级和子优先级相同的,按照表的位置决定

下面的四个顺序需要我们思考
在这里插入图片描述

四、GPIO中断

GPIO的中断是由外部中断/事件控制器EXTI(External lnterrupt/Event Controller)控制,GPIO有两种中断模式:两者的产生源是相同的

  1. 中断模式:外部信号产生电平变化时触发中断,执行中断服务函数,完成操作,需要变成自定义功能,需要CPU参与
  2. 事件模式:外部信号产生电平变化时根据配置联动ADC/定时器等执行相关的操作,硬件触发之后执行相对应的操作,不需要CPU参与,响应的速度更快
    在这里插入图片描述
    将PA0、PB0、PC0、…、PG0归到EXTI0管理,PA1、PB1、PC1、…、PG1归到EXTI1管理,以此类推,PA15、PB15、PC15、…、PG15归到EXTI15管理。
    当PA0为中断源是,PB0~PG0都不能为中断源。

五、按键中断切换LED亮灭实验

首先,将按键引脚(PA0)设置成中断的形式
在这里插入图片描述
我们在STM32CubeMX软件中查看GPIO引脚,发现已经设置成上升沿触发:当低电平变成高电平时这个中断会触发
在这里插入图片描述
我们开启抢占优先级并降低优先级设置为2
在这里插入图片描述
将NVIC代码初始化勾选
在这里插入图片描述
查看代码

  MX_NVIC_Init();

里面有优先级和使能中断

static void MX_NVIC_Init(void)
{
  /* EXTI0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}

我们按下按键,会产生EXTI0中断,调用EXTIO中断服务函数,参数是中断引脚

void EXTI0_IRQHandler(void)
{
   HAL_GPIO_EXTI_IRQHandler(KEY_Pin);
}

会继续调用HAL_GPIO_EXTI_Callback(GPIO_Pin)函数

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
   if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

HAL_GPIO_EXTI_Callback(GPIO_Pin)是一个复调函数,是虚函数,需要我们重新复写

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    UNUSED(GPIO_Pin);
}

我们在GPIO.c的文件中进行复写

static uint8_t key_flag = 0;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == KEY_Pin)
	{
		key_flag = ~key_flag;
		HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,key_flag?GPIO_PIN_RESET);
	}
}
举报

相关推荐

0 条评论