STM32的EXTI

STM32的EXTI(External Interrupt/Event Controller,外部中断/事件控制器)模式的选择主要涉及到中断和事件的配置,以及触发方式(如上升沿、下降沿、双边沿等)的设置。以下是如何选择和配置STM32 EXTI模式的详细步骤:

1. 确定EXTI的模式

EXTI支持两种基本模式:中断模式和事件模式。

  • 中断模式:当外部信号满足触发条件时,EXTI会产生一个中断请求,CPU会暂停当前任务去执行相应的中断服务程序(ISR)。
  • 事件模式:当外部信号满足触发条件时,EXTI会触发一个事件,但不会直接产生中断。事件通常用于唤醒CPU或触发其他硬件操作,如DMA传输。

2. 配置EXTI的触发方式

EXTI支持多种触发方式,包括上升沿触发、下降沿触发、双边沿触发等。这些触发方式的选择取决于具体的应用场景。

  • 上升沿触发:当外部信号从低电平变为高电平时触发。
  • 下降沿触发:当外部信号从高电平变为低电平时触发。
  • 双边沿触发:无论外部信号是上升沿还是下降沿变化时都触发。

3. 配置步骤

在STM32中配置EXTI模式和触发方式的步骤通常包括以下几个方面:

  1. 配置GPIO引脚:首先,需要将与EXTI线相关联的GPIO引脚配置为输入模式,并可能需要根据需要选择上拉/下拉输入。

  2. 配置AFIO(Alternate Function I/O,复用功能输入输出):在STM32的早期版本中,可能需要通过AFIO外设将GPIO引脚与EXTI线进行映射。但在一些新版本的STM32中,这一步骤可能已经被简化或取消。

  3. 配置EXTI线

    • 选择要使用的EXTI线。
    • 配置EXTI线的触发方式(上升沿、下降沿、双边沿等)。
    • 使能EXTI线。
  4. 配置NVIC(Nested Vectored Interrupt Controller,嵌套向量中断控制器):如果选择了中断模式,则需要配置NVIC来设置中断的优先级和使能中断。NVIC允许对中断进行分组,并设置抢占优先级和响应优先级。

  5. 编写中断服务函数:如果选择了中断模式,则需要编写相应的中断服务函数来处理中断请求。在中断服务函数中,可以读取EXTI的状态,执行必要的操作,并清除中断标志位以避免中断重复触发。

4. 注意事项

  • 在配置EXTI时,需要确保外部信号的频率和时序与STM32的时钟频率和中断响应时间相匹配,以避免漏检或误检。
  • 在使用中断模式时,需要注意中断的嵌套和优先级问题,以避免中断冲突或优先级倒置。
  • 在使用事件模式时,需要了解事件如何与STM32的其他硬件功能(如DMA)进行交互。

5. 示例代码(假设使用STM32F1系列)

​

static void NVIC_Configuration(void)//static只能被exti.c调用
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 配置NVIC为优先级组1 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//这里只有一个中断,随便选
  
  /* 配置中断源:按键1 */
  NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
  /* 配置抢占优先级 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//先比较的是抢占你优先级,这里的组1可以是0或1
  /* 配置子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//在比较子优先级,这里只有一个中断源
  /* 使能中断通道 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  /* 配置中断源:按键2,其他使用上面相关配置 */  
  NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
  NVIC_Init(&NVIC_InitStructure);
}

 /**
  * @brief  配置 IO为EXTI中断口,并设置中断优先级
  * @param  无
  * @retval 无
  */
void EXTI_Key_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; 
	EXTI_InitTypeDef EXTI_InitStructure;//stm32f10x_exti.h结构体在这里面找

	/*开启按键GPIO口的时钟*/
	RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
  RCC_APB2PeriphClockCmd(KEY2_INT_GPIO_CLK,ENABLE);
												
	/* 配置 NVIC 中断*/
	NVIC_Configuration();
	
/*--------------------------KEY1配置-----------------------------*/
	/* 选择按键用到的GPIO */	
  GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
  /* 配置为浮空输入 */	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入电平由外部决定,实现任意的GPIO作为EXTI的输入端
  GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);

	/* 选择EXTI的信号源 */
  GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE); 
  EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;//EXTI_Line0,看EXTI_IMR寄存器,写lin0就是MR0写1,开放Lin0的中断请求
	
	/* EXTI为中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	/* 上升沿中断 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//这里上升沿下降沿都可以
  /* 使能中断 */	
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);//初始化,相当于把结构体写到相应的寄存器才能起作用
  /*--------------------------KEY2配置-----------------------------*/
	/* 选择按键用到的GPIO */	
  GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
  /* 配置为浮空输入 */	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);

	/* 选择EXTI的信号源 */
  GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE); 
  EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;
	
	/* EXTI为中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	/* 下降沿中断 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  /* 使能中断 */	
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
}
​

 

 

你可能感兴趣的:(stm32内容,单片机,嵌入式硬件,stm32,c语言)