STM32中断

中断系统

  • 中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得单片机暂停当前正在运行的的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。
  • 中断优先级:当有多个中断源同时申请中断时,单片机会根据中断源的优先级进行相应(一个工程只能有一个优先级函数)。
  • 中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,单片机再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次返回。

中断代码

int mian(void) //主函数
{
	while(1){
		
		
	}
	
}
void EXTI0_IRQHandler(void)  //中断函数
{
	
	
}


STM32中断

  • STM32中断包含EXTI外部中断,TIM定时中断,ADC数模中断,USART串口中断,SPI通讯中断,IIC通讯中断,RTC实时时钟等多个外设中断。
  • 使用NVIC1统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级。
  • NVIC的优先级分组:NVIC的中断优先级由优先级寄存器的4为(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的相应优先级。抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和相应优先级均相同的按中断号排队
分组方式 抢占优先级 抢占优先级
分组0 0位,取值0 4位,取值0~15
分组1 1位,取值0~1 4位,取值0~7
分组2 2位,取值0~3 4位,取值0~3
分组3 3位,取值0~7 4位,取值0~1
分组4 4位,取值0~15 4位,取值0

EXTI外部中断

  • EXTI可以检测GPIO口的电平变化,GPIO口的电频变化时即可申请中断。
  • EXTI的支持触发方式:上升沿,下降沿,双边沿,软件触发
  • 支持所有的GPIO口但相同的Pin不能同时触发中断
  • 通道数:16个GPIO_Pin,PVD输出,RTC闹钟,USB唤醒,以太网唤醒
  • 触发响应方式:中断响应/事件响应2

EXTI中断基本结构

在这里插入图片描述

EXTI代码

根据EXTI中断的基本结构图可以写出配置中断的函数,这里展示以旋转编码器为例的库函数(这里为双中断)

  • .c文件:
#include "stm32f10x.h"                  // Device header

int16_t Encoder_Count;

void Encoder_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
	
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_Init(&NVIC_InitStructure);
}

int16_t Encoder_Get(void)
{
	int16_t Temp;
	Temp = Encoder_Count;
	Encoder_Count = 0;
	return Temp;
}

void EXTI0_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line0) == SET)
	{
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
		{
			Encoder_Count --;
		}
		EXTI_ClearITPendingBit(EXTI_Line0);
	}
}

void EXTI1_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line1) == SET)
	{
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
		{
			Encoder_Count ++;
		}
		EXTI_ClearITPendingBit(EXTI_Line1);
	}

.h文件(中断函数无需声明):

#ifndef __ENCODER_H
#define __ENCODER_H

void Encoder_Init(void);
int16_t Encoder_Get(void);

#endif

什么时候使用EXTI

以STM32为例,想要获取的信号时外部驱动的,很快的突发信号需要使用EXTI外部中断。如旋转编码器的输出信号,红外遥控接收头的输出等。


  1. NVIC的基本结构:
    在这里插入图片描述
    NVIC为内核外设,程序中不需要开启专门的NVIC时钟。 ↩︎

  2. 中断响应:申请中断,让CPU执行中断函数
    事件响应:外部中断的信号不通向CPU,转而通向其他外设,触发其他外设的操作,如:ADC转换,DMA等。 ↩︎

版权声明:本文为CSDN博主「L丶Aurora」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Gracelsd/article/details/122853573

中断系统

  • 中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得单片机暂停当前正在运行的的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。
  • 中断优先级:当有多个中断源同时申请中断时,单片机会根据中断源的优先级进行相应(一个工程只能有一个优先级函数)。
  • 中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,单片机再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次返回。

中断代码

int mian(void) //主函数
{
	while(1){
		
		
	}
	
}
void EXTI0_IRQHandler(void)  //中断函数
{
	
	
}


STM32中断

  • STM32中断包含EXTI外部中断,TIM定时中断,ADC数模中断,USART串口中断,SPI通讯中断,IIC通讯中断,RTC实时时钟等多个外设中断。
  • 使用NVIC1统一管理中断,每个中断通道都拥有16个可编程的优先等级,可对优先级进行分组,进一步设置抢占优先级和响应优先级。
  • NVIC的优先级分组:NVIC的中断优先级由优先级寄存器的4为(0~15)决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的相应优先级。抢占优先级高的可以中断嵌套,响应优先级高的可以优先排队,抢占优先级和相应优先级均相同的按中断号排队
分组方式 抢占优先级 抢占优先级
分组0 0位,取值0 4位,取值0~15
分组1 1位,取值0~1 4位,取值0~7
分组2 2位,取值0~3 4位,取值0~3
分组3 3位,取值0~7 4位,取值0~1
分组4 4位,取值0~15 4位,取值0

EXTI外部中断

  • EXTI可以检测GPIO口的电平变化,GPIO口的电频变化时即可申请中断。
  • EXTI的支持触发方式:上升沿,下降沿,双边沿,软件触发
  • 支持所有的GPIO口但相同的Pin不能同时触发中断
  • 通道数:16个GPIO_Pin,PVD输出,RTC闹钟,USB唤醒,以太网唤醒
  • 触发响应方式:中断响应/事件响应2

EXTI中断基本结构

在这里插入图片描述

EXTI代码

根据EXTI中断的基本结构图可以写出配置中断的函数,这里展示以旋转编码器为例的库函数(这里为双中断)

  • .c文件:
#include "stm32f10x.h"                  // Device header

int16_t Encoder_Count;

void Encoder_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
	
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_Init(&NVIC_InitStructure);
}

int16_t Encoder_Get(void)
{
	int16_t Temp;
	Temp = Encoder_Count;
	Encoder_Count = 0;
	return Temp;
}

void EXTI0_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line0) == SET)
	{
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
		{
			Encoder_Count --;
		}
		EXTI_ClearITPendingBit(EXTI_Line0);
	}
}

void EXTI1_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line1) == SET)
	{
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
		{
			Encoder_Count ++;
		}
		EXTI_ClearITPendingBit(EXTI_Line1);
	}

.h文件(中断函数无需声明):

#ifndef __ENCODER_H
#define __ENCODER_H

void Encoder_Init(void);
int16_t Encoder_Get(void);

#endif

什么时候使用EXTI

以STM32为例,想要获取的信号时外部驱动的,很快的突发信号需要使用EXTI外部中断。如旋转编码器的输出信号,红外遥控接收头的输出等。


  1. NVIC的基本结构:
    在这里插入图片描述
    NVIC为内核外设,程序中不需要开启专门的NVIC时钟。 ↩︎

  2. 中断响应:申请中断,让CPU执行中断函数
    事件响应:外部中断的信号不通向CPU,转而通向其他外设,触发其他外设的操作,如:ADC转换,DMA等。 ↩︎

版权声明:本文为CSDN博主「L丶Aurora」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Gracelsd/article/details/122853573

生成海报
点赞 0

L丶Aurora

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

STM32C8T6+LORA(SX1278)

LoRa通信系统 从毕设开始搭建了一个简单的LORA通信系统(两块STM32C8T6最小单片机系统,两块正点原子的loRa,一块温湿度传感器)构建了一个简单的loRa通信系统作为入门。之

STM32 QSPI双闪存操作

STM32 QSPI双闪存操作 使用CubeMX或者CubeIDE生成框架 使用野火的开发板,MCU型号为stm32h750/743,他们家核心板上使用了QSPI挂了2片FLASH,型号为W25Q2