stm32笔记[6]-中断触发流水灯

Posted qsBye

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stm32笔记[6]-中断触发流水灯相关的知识,希望对你有一定的参考价值。

环境

开发环境

  • STM32CubeIDE

硬件

Alios Things Dev kit 开发板

  • STM32L496VGT6
  • LED1:PB6(低电平有效)
  • LED2:PE3(低电平有效)
  • LED3:PD15(低电平有效)
  • KEY_1_A:PE14(低电平有效)
  • KEY_2_M:PE11(低电平有效)
  • KEY_3_B:PE10(低电平有效)
  • STLK_TX:PB10(LPUART1)
  • STLK_RX:PB11(LPUART1)

硬件外观:

引脚配置:

功能描述

利用按键(中断)实现流水灯的启动与停止,KEY1 实现流水灯的启动,KEY2 实现停止。

实现

流程图

核心代码

  1. 按键中断+阻塞延时
/* USER CODE BEGIN 0 */
// 定义全局变量,用于记录LED灯的状态
extern uint8_t led_state = 0;
// 定义全局变量,用于记录定时器计数
extern uint32_t timer_counter = 0;
/* USER CODE END 0 */
/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  if(led_state==1)
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_6);
	  HAL_Delay(500);
	  HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_3);
	  HAL_Delay(500);
	  HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_15);
	  HAL_Delay(500);
	  

  
  /* USER CODE END 3 */
// 定义中断处理函数,处理按键下降沿中断
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

  // 判断是否是按键引脚的中断
  if (GPIO_Pin == GPIO_PIN_11) 
	  if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_11)==0)
		  // 切换是否闪烁两个LED灯
		  led_state = !led_state;
	  
  

  1. 按键中断+RTOS非阻塞延时
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = 
  .name = "defaultTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
;
/* USER CODE BEGIN 0 */
// 定义全局变量,用于记录LED灯的状态
extern uint8_t led_state = 0;
// 定义全局变量,用于记录定时器计数
extern uint32_t timer_counter = 0;
/* USER CODE END 0 */
/* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* Start scheduler */
  osKernelStart();
  // 定义中断处理函数,处理按键下降沿中断
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

  // 判断是否是按键引脚的中断
  if (GPIO_Pin == GPIO_PIN_11) 
		  if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_11)==0)
		  // 切换是否闪烁两个LED灯
		  led_state = !led_state;
		  

  

/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)

  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  
	  if(led_state==1)
  	        HAL_UART_Transmit(&hlpuart1,"ok\\n",4,1000);
  	        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_6);
  	        HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_3);
  	        HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_15);
  	        osDelay(1000);//1s
	  
  
  /* USER CODE END 5 */

效果

  1. 按键中断+阻塞延时
  2. 按键中断+RTOS非阻塞延时

STM32-外部中断,没有硬件干扰就是快乐

一:触发方式

STM32 的外部中断是通过边沿来触发的,不支持电平触发;

二:外部中断分组

STM32 的每一个GPIO都能配置成一个外部中断触发源,STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB0,PC0,PD0,PE0,PF0,PG0为第一组,那么依此类推,我们能得出一共有16 组,STM32 规定,每一组中同时只能有一个中断触发源工作,那么,最多工作的也就是16个外部中断。

STM32 分组和对应中断处理函数分配:

管脚

中断标志

中断处理函数分配

PA0~PG0

EXTI0

EXTI0_IRQHandler

PA1~PG1

EXTI1

EXTI1_IRQHandler

PA2~PG2

EXTI2

EXTI2_IRQHandler

PA3~PG3

EXTI3

EXTI3_IRQHandler

PA4~PG4

EXTI4

EXTI4_IRQHandler

PA5~PG5

EXTI5

 EXTI9_5_IRQHandler

PA6~PG6

EXTI6

PA7~PG7

EXTI7

PA8~PG8

EXTI8

PA9~PG9

EXTI9

PA10~PG10

EXTI10

EXTI15_10_IRQHandler

PA11~PG11

EXTI11

PA12~PG12

EXTI12

PA13~PG13

EXTI13

PA14~PG14

EXTI14

PA15~PG15

EXTI15

三:外部中断的配置过程

l 配置触发源 -GPIO

触发源为通过GPIO端口输入,所以,要配置GPIO的模式,输入方式,输入方式有以下几种:

1.GPIO_Mode_AIN ,模拟输入(ADC模拟输入,或者低功耗下省电)

2.GPIO_Mode_IN_FLOATING ,浮空输入

3.GPIO_Mode_IPD = 0x28,带下拉输入 

4.GPIO_Mode_IPU = 0x48,带上拉输
 
-----------------------具体配置例子-----------------------
参考STM32的库函数版自带例程 PB5对应的EXTI9_5_IRQHandler,及5号中断线,这个不能乱设,否则不工作
void EXTIX_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
     EXTI_InitTypeDef EXTI_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);     //关闭jtag
 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
 
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
       GPIO_Init(GPIOB, &GPIO_InitStructure);
 
       GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource5);

       EXTI_InitStructure.EXTI_Line=EXTI_Line5;
       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 = EXTI9_5_IRQn;               //使能按键所在的外部中断通道
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;     //先占优先级4位,共16级
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                         //先占优先级0位,从优先级4位
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                        //使能外部中断通道
       NVIC_Init(&NVIC_InitStructure); 
}
处理函数,要清除中断标志位,不然一秒M次的中断都可能
void EXTI9_5_IRQHandler(void)
{
       delay_ms(10);    //消抖,是按键的话这里就需要,否则就不用延迟               
printf("delay_ms\r\n");

      if (EXTI_GetITStatus(EXTI_Line5) != RESET)
     {
     //自己要实现的动作
          printf("EXTI0_IRQHandler\r\n");
     }
     EXTI_ClearITPendingBit(EXTI_Line5);  //清除EXTI13线路挂起位
    
}

以上是关于stm32笔记[6]-中断触发流水灯的主要内容,如果未能解决你的问题,请参考以下文章

stm32亮灯后灯不能灭

STM32 cubeMX:使用中断触发SPI DMA中断

stm32外部中断这程序编译没问题,但触发不了外部中断,卡了一天了

STM32-外部中断,没有硬件干扰就是快乐

如何配置STM32定时器在每次递增/递减时触发中断?

在STM32 Nucleo上多次触发上升沿中断