STM8的中断系统以及外部中断详解

时间:2023-03-08 23:46:34
STM8的中断系统以及外部中断详解

STM8具有最多32的中断系统,在中断的处理上类似于cortexm系列的芯片,首先是每个中断的向量都是固化在系统内部的,用户需要向相应的中断向量flash位置写入中断处理函数,其二,每个中断向量都具有可编程的优先级,共有两位优先级,两个BIT的优先级可以催化出4个优先级,具体如下

STM8的中断系统以及外部中断详解

中断控制器内部有一些寄存器专门用来存放相应的中断的中断优先级,同同时,在系统内部也有一个系统寄存器CC他的第三位和第五位分别表示当前正在处理的中断的优先级

可以这样认为,中断发生的时候,系统寄存器在执行中断向量跳转的时候自动载入了相应的中断优先级到系统寄存器CC中.

中断的处理遵循先判断软件优先级后判断硬件优先级的模式,当几个中断同时发生的时候,系统会根据其固化的硬件优先级进行相应,

另外,STM8支持中断嵌套,因为软件优先级就4级,最多也就软件优先级三层嵌套

对STM8的中断进行操作其实也简单

1.      配置系统中断的打开或关闭

STM8的中断系统以及外部中断详解

2.      配置想要使用的中断向量的软件优先级

STM8的中断系统以及外部中断详解

3.      打开相应的外设中断源的中断,就可以响应了

针对于外部中断来说,首先,STM8的每一个引脚都能支持外部中断,但是在中断向量上,不是每一个引脚都有

独立的中断向量,而是每个端口共用一个中断向量,在端口中断向量处理函数中检查到底是哪一个引脚出现了问题,

对于外部中断的配置,如下

STM8的中断系统以及外部中断详解

可以定义中断的触发模式,电平触发,下降沿触发等,这个寄存器存放了A B CD四个向量的中断模式

STM8的中断系统以及外部中断详解

该寄存器存放了E向量的中断

另外,外部中断中有一个特殊的中断叫做TLI不可屏蔽中断,也就是PD7,他不属于D中断向量而是拥有自己的TLI中断向量

使用外部中断的过程

1.      根据前面的描述配置中断向量

2.      配置中断端口的触发模式

3.      对相应的GPIO口选择中断输入模式

在使用中断函数的时候需要注意,外部中断的中断函数我们并没有一个寄存器告诉我们哪一个中断向量的哪一个引脚发生了中断

需要我们读取端口的信息,假设是下降沿中断触发,那么中断处理函数在运行的时候,该引脚应该是电平的,检查哪一个引脚是低电平,我们就可以知道哪一个引脚发生了中断

从而进行正确的处理

所以最好是一个端口只有一个引脚中断,这样易于判断,省去了一些读引脚的过程

具体操作请查看一下代码

#include "exti.h"

void ExtiInit(void)
{
//首先禁用中断
disableInterrupts();
//配置IO口为输入中断模式
//D7初始化
GPIOD->DDR &= ~(1<<7);//设置为输入
GPIOD->CR1 |= (1<<7);
GPIOD->CR2 |= (1<<7);//中断上拉输入 //E3初始化
GPIOE->DDR &= ~(1<<3);//设置为输入
GPIOE->CR1 |= (1<<3);
GPIOE->CR2 |= (1<<3);//中断上拉输入 //设定中断优先级,TLI是最高的不可屏蔽中断优先级,所以不需要设置软件优先级,只
//需要设置E3也就是端口E的优先级即可,中断向量号为7 对应寄存器ITC_SPR2
ITC->ISPR2 &= (3<<6);//清楚中断优先级
ITC->ISPR2 |= (1<<6);//中断优先级01 //设置中断触发模式
EXTI->CR2 &= ~(1<<2);//TLI下降沿触发
EXTI->CR2 &= ~(3<<0);//清除PORTE
EXTI->CR2 |= (2<<0);//Porte仅仅下降沿触发 enableInterrupts();//打开中断
} //TLI中断处理函数
INTERRUPT_HANDLER(TLI_IRQHandler, 0)
{
keyValue = KEY_VALUE1;
}
//PORT E中断处理函数
INTERRUPT_HANDLER(EXTI_PORTE_IRQHandler, 7)
{
//保险起见,这里进行一次电平
if((GPIOE->IDR&0X08) == 0)//检测是不是低电平
{
keyValue = KEY_VALUE2;
}
}
#ifndef __EXTI_H_
#define __EXTI_H_ #include "stm8s.h"
#include "key.h"
//我们是用两个按键作为中断触发,其中,D7是TLI中断,E3是portE中断 void ExtiInit(void); #endif