1.中断处理

##项目目标是通过中断控制GPIO,实现rgb灯的亮灭;

 

中断基本概念:

  CPU在正常执行程序的过程中,遇到内部/外部的紧急事件需要处理,暂时中止当前程序执行,转而去处理紧急事件,处理完成后再返回被打断的程序继续执行

  中断能提高CPU效率(针对不频繁事件),能针对突发事件做出实时处理,实现程序的并行化,嵌入式系统进程之间的切换。

  //内部中断也成为异常

  

  EXTI管理所有GPIO产生的中断——>    NVIC  (嵌套向量中断控制器)——>    内核指令执行单元查找查找中断向量表

  NVIC主要功能:①中断管理  

    外部中断可以被使能或者禁止,并且可以设置为挂起状态或者清楚状态

  ②支持异常及中断向量化处理

    当异常或中断发生时,处理器会把PC设置为一个特定地址,这一地址就称为异常向量。每一类异常源都对应一个特定的入口地址,这些地址按照优先级排列以后就组成一张异常向量表

    向量化处理中断的好处:传统的处理方式需要软件去完成。采用向量表处理异常,处理器会从存储器的向量表中,自动定位异常的程序入口。从发生异常到异常的处理中间的时间被缩减。

 

  ③支持嵌套中断
    数字越小优先级越高;优先级相同时,优先级相同时中断向量号小的先响应。
 
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
一、按键中断:
  
步骤:  

1、使能相应的时钟

2、配置GPIO管脚为中断功能

3、设置中断优先级

4、使能相应的中断

5、实现中断服务程序

 

 

 

当使用轮询的方式通过GPIO控制灯亮灭,很简单

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	  if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(key1_GPIO_Port,key1_Pin))
	  {
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,RESET);
		  HAL_Delay(500);
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,RESET);
		  HAL_Delay(500);
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,RESET);
		  HAL_Delay(1000);
	  }

	  else if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(key2_GPIO_Port,key2_Pin))
	  {
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,SET);
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,SET);
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,SET);
	  }

	  HAL_Delay(500);


  }

但是缺点很明显,cpu不能干其他事情,并且如果在延时时间段内接收到其他信号,将会错过这个信号(按键反应不灵敏)

因此改为中断模式更好,此时需要将引脚由GPIO_OUT 改为GPIO_EXTI模式并且打开上拉电阻设置,边缘下降沿触发

 

p.s硬件设计时候,多个引脚使用一个中断号,例如(PA0 PB0 PC0 PD0都使用GPIO_EXTI_0)因此要注意不要将多个按键映射到使用同一个中断号的引脚上

 

使能中断并调整优先级,优先级默认为0,因为延时函数优先级也为0,延时不能打断外部中断

所以这里需要降低中断的优先级 让System tick timer优先级高于中断

 

 

 

将代码逻辑放在gpio.c中,编写函数 HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

/* USER CODE BEGIN 2 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(key1_Pin == GPIO_Pin) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,RESET); HAL_Delay(100); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,RESET); HAL_Delay(100); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,RESET); HAL_Delay(100); } else if(key2_Pin == GPIO_Pin) { HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,SET); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,SET); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,SET); } }

 

执行main函数前还有其他操作:

设置栈指针

初始化cpu寄存器

将data 段拷贝(SRAM)

清空bss区

执行标准库的初始化函数等

 

posted @ 2023-06-27 12:44  面筋玄师  阅读(124)  评论(0)    收藏  举报