stm32中断

发布于:2024-07-05 ⋅ 阅读:(17) ⋅ 点赞:(0)

2 中断及按键使用

2.1 中断基础和方式

轮询:即每过一段时间查看一次事件(一直探测),但是仍然可能错过,若事件发生时,轮询未能轮到该事件的函数,那么就错过了。同时效率低下。

中断(NVIC):即cpu探测到发生某事后执行某个动作,相比于轮询,他不会一直占用CPU资源,并且避免了像轮询那样错过的情况发生。中断发生后执行什么动作由中断向量表来决定。

  • 水平触发:即根据电平判断是否中断。
  • 沿触发:包括上升沿触发,下降沿触发和双沿触发。一般用于按键,但是要注意按键抖动问题。

设计中断服务处理程序必须要注意的点!!!:

  1. 中断服务处理函数应该快进快出,例如串口在接收数据时候,若数据收发速率很快,数据到来时,中断服务处理程序还在处理数据,那么就错过了收发,这个中断就不会相应。
  2. 同时,在中断中使用临界资源加锁时,应使用非阻塞锁,阻塞锁可能会成为死锁。
  3. 若使用循环buffer在另一个线程和中断服务处理程序之间进行读写交换数据的操作时,一定要注意的是,循环buffer非线性的,所以不能直接使用strncpy等函数来拷贝,对比等。

2.2 常见中断概念

  • 中断号:每个中断请求信号都会有特定的标志,使得计算机能够判断是哪个设备提出的中断请求,这个标志就是中断号。
  • 中断请求:“紧急事件”需向 CPU 提出申请,要求 CPU 暂停当前执行的任务,转而处理该“紧急事件”,这一申请过程称为中断请求。
  • 中断优先级:为使系统能够及时响应并处理所有中断,系统根据中断时间的重要性和紧迫程度,将中断源分为若干个级别,称作中断优先级。
  • 中断处理程序:当外设产生中断请求后,CPU 暂停当前的任务,转而响应中断申请, 即执行中断处理程序。
  • 中断触发:中断源发出并送给 CPU 控制信号,将中断触发器置“1”,表明该中断源 产生了中断,要求 CPU 去响应该中断,CPU暂停当前任务,执行相应的中断处理程序。 中断触发类型:外部中断申请通过一个物理信号发送到 NVIC,可以是电平触发边沿触发
  • 中断向量:中断服务程序的入口地址。
  • 中断向量表:存储中断向量的存储区,中断向量与中断号对应,中断向量在中断向量 表中按照中断号顺序存储。
  • 临界段:代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断 打断。为确保临界段代码的执行不被中断,在进入临界段之前须关中断,而临界段代码执 行完毕后,要立即开中断。

2.3 中断流程

  1. 安装中断服务处理程序(中断服务处理程序是发生中断后,根据中断向量表找到的处理函数);
  2. 判断中断号,压栈(还要判断优先级,CubeMx中数字越小优先级越高);
  3. 判断优先级。
  4. 保存现场
  5. 执行中断服务处理程序(IRQ)
  6. 返回现场

stm32的中断是可以嵌套的,但是Linux的嵌套不能中断。中段向量表每一个IRO都是四字节的地址,用来跳转到对应的函数入口,而不是直接就是函数。

ps:着重注意中断程序与HAL_Delay的优先级问题,然后自己查看main函数前的初始化处理(汇编)以及中断向量表配置。

2.3 按键中断例程

//默认的中断服务处理函数,看源代码会有一个若函数版本的weak _void HAL_GPIO_EXTI_Callback(uint16_t GPIO_PIN),所以如果我们没有定义,那么就执行若函数什么都没有的中断,如果有定义,那么就会执行我们定义的中断服务处理函数。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_PIN)
{   
  switch(GPIO_PIN)
  {
  	case GPIO_PIN_1:
  				//do something
  				break;
  	case GPIO_PIN_2:
  				//do something
  				break;
  	case GPIO_PIN_3:
  				//do something
  				break;
  }
}

网站公告

今日签到

点亮在社区的每一天
去签到