STM32 向量表
在STM32微控制器中,向量表是一个非常重要的概念,尤其是在启动和中断处理过程中。本文将详细介绍向量表的作用、结构以及它在STM32中的实际应用。
什么是向量表?
向量表(Vector Table)是一个存储了中断服务程序(ISR)入口地址的数组。当STM32微控制器启动或发生中断时,处理器会根据向量表中的地址跳转到相应的中断服务程序。向量表通常位于Flash存储器的起始位置,但也可以通过配置将其放置在其他位置。
向量表的结构
向量表的结构非常简单,它由一系列32位的地址组成。每个地址对应一个特定的中断或异常。向量表的第一个条目是初始堆栈指针(SP)的值,第二个条目是复位向量,即复位处理程序的入口地址。接下来的条目依次对应不同的中断源。
typedef void (*vector_t)(void);
vector_t vector_table[] __attribute__((section(".isr_vector"))) = {
(vector_t)(&_estack), // 初始堆栈指针
Reset_Handler, // 复位向量
NMI_Handler, // NMI 中断
HardFault_Handler, // 硬件错误中断
// 其他中断向量...
};
在上面的代码中,vector_table
是一个函数指针数组,每个元素指向一个中断处理函数。__attribute__((section(".isr_vector")))
用于将向量表放置在特定的内存段中。
向量表的作用
1. 启动过程
当STM32微控制器上电或复位时,处理器首先从向量表的第一个条目中读取初始堆栈指针的值,并将其加载到SP寄存器中。接着,处理器从第二个条目中读取复位向量的地址,并跳转到该地址执行复位处理程序。
2. 中断处理
当发生中断时,处理器会根据中断号从向量表中查找对应的中断服务程序的入口地址,并跳转到该地址执行中断处理代码。这使得中断处理变得非常高效,因为处理器不需要在运行时动态计算中断处理程序的地址。
实际案例:配置向量表
假设我们有一个简单的STM32项目,需要处理一个外部中断(EXTI)。我们可以通过以下步骤配置向量表:
- 定义中断处理函数:首先,我们需要为外部中断定义一个处理函数。
void EXTI0_IRQHandler(void) {
// 处理外部中断0
// 清除中断标志
EXTI->PR |= EXTI_PR_PR0;
}
- 修改向量表:在向量表中,找到外部中断0对应的条目,并将其指向我们定义的处理函数。
vector_t vector_table[] __attribute__((section(".isr_vector"))) = {
(vector_t)(&_estack), // 初始堆栈指针
Reset_Handler, // 复位向量
NMI_Handler, // NMI 中断
HardFault_Handler, // 硬件错误中断
// 其他中断向量...
EXTI0_IRQHandler, // 外部中断0
};
- 启用中断:在初始化代码中,启用外部中断0。
void EXTI0_IRQ_Init(void) {
// 配置GPIO和EXTI
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // 使能GPIOA时钟
GPIOA->CRL &= ~(0xF << 0); // 配置PA0为输入
EXTI->IMR |= EXTI_IMR_MR0; // 使能EXTI0中断
EXTI->RTSR |= EXTI_RTSR_TR0; // 使能上升沿触发
NVIC_EnableIRQ(EXTI0_IRQn); // 使能EXTI0中断
}
通过以上步骤,我们成功配置了向量表,并实现了外部中断0的处理。
总结
STM32向量表是微控制器启动和中断处理的核心机制。通过理解向量表的结构和作用,我们可以更好地掌握STM32的启动过程和中断处理机制。在实际项目中,合理配置向量表是确保系统稳定运行的关键。
如果你对向量表的配置有疑问,可以参考STM32的参考手册,其中详细描述了每个中断向量对应的中断源。
附加资源
练习
- 修改向量表,添加一个新的中断处理函数,并测试其功能。
- 尝试将向量表从Flash存储器移动到RAM中,并观察系统的行为变化。