STM32VLDiscovery 定时器中断 HardFault c
STM32VLDiscovery Timer Interrupt HardFault c
我尝试在 STM32VLDiscovery 板上的 stm32f100rbt6 上使用 stm32 定时器中断编写一个简短的程序。
这是我目前的代码 (main.c):
static inline void initGPIO() {
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIO_InitTypeDef init;
init.GPIO_Mode = GPIO_Mode_Out_PP;
init.GPIO_Speed = GPIO_Speed_2MHz;
init.GPIO_Pin = 0xFFFF;
GPIO_Init(GPIOC, &init);
}
static inline void initTimer3() {
NVIC_EnableIRQ(TIM3_IRQn);
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3->SR = 0;
TIM3->ARR = 0xFFFF;
TIM3->PSC = 0xFFFF;
TIM3->DIER = TIM_DIER_UIE;
TIM3->CR1 |= TIM_CR1_CEN;
//same problem when I enable the IRQ here
}
int main(void) {
SCB->CCR |= SCB_CCR_STKALIGN;
SystemInit();
initGPIO();
GPIOC->ODR = 0xFFFF;
initTimer3();
for (;;) {
GPIOC->BSRR = ~(TIM3->CNT >> 8) & 0x7F;
GPIOC->BRR = (TIM3->CNT >> 8) & 0x7F;
}
}
void TIM3_IRQHandler() {
TIM3->SR = 0;
//GPIOC->ODR = 0xCC;
}
void HardFault_Handler() {
GPIOC->BRR = 0x100;
while (1)
;
}
每次定时器溢出时都应该调用IRQHandler。当我不启用 NVIC 时,程序运行正常,只是将一部分定时器值写入 GPIOC。但是一旦我启用 NVIC,程序 HardFaults,只要调用 initTimer3 函数。
到目前为止我尝试过的:
将 NVIC_EnableIRQ 行移动到函数的其他位置
- 仍然遇到同样的问题
在调用 initTimer3 函数之前添加延迟
- 在 initTimer3 函数正确执行之前的一切,只要调用 init 函数,程序就会出现硬故障。
使用不同的计时器
- 我已经尝试过使用 TIM7 和 TIM6
更新
设置 STKALIGN 位也不会改变任何内容。一旦中断被激活,HardFault 就会发生。
你有HF可能是因为调用中断例程时堆栈没有对齐。 F1xx 系列默认关闭硬件堆栈对齐,启动或用户应用程序必须启用它。或者,您可以使用适当的属性强制进行适当的对齐。
另一个常见问题:
启动文件中的中断例程名称必须多这一项。
例如,在 Cube MX 生成的代码中,矢量 table 在 startup_stm32f103xb.s 文件中定义。
定时器中断例程是:
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
检查您的文件,向量中使用了哪些名称 table。
我尝试在 STM32VLDiscovery 板上的 stm32f100rbt6 上使用 stm32 定时器中断编写一个简短的程序。
这是我目前的代码 (main.c):
static inline void initGPIO() {
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIO_InitTypeDef init;
init.GPIO_Mode = GPIO_Mode_Out_PP;
init.GPIO_Speed = GPIO_Speed_2MHz;
init.GPIO_Pin = 0xFFFF;
GPIO_Init(GPIOC, &init);
}
static inline void initTimer3() {
NVIC_EnableIRQ(TIM3_IRQn);
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3->SR = 0;
TIM3->ARR = 0xFFFF;
TIM3->PSC = 0xFFFF;
TIM3->DIER = TIM_DIER_UIE;
TIM3->CR1 |= TIM_CR1_CEN;
//same problem when I enable the IRQ here
}
int main(void) {
SCB->CCR |= SCB_CCR_STKALIGN;
SystemInit();
initGPIO();
GPIOC->ODR = 0xFFFF;
initTimer3();
for (;;) {
GPIOC->BSRR = ~(TIM3->CNT >> 8) & 0x7F;
GPIOC->BRR = (TIM3->CNT >> 8) & 0x7F;
}
}
void TIM3_IRQHandler() {
TIM3->SR = 0;
//GPIOC->ODR = 0xCC;
}
void HardFault_Handler() {
GPIOC->BRR = 0x100;
while (1)
;
}
每次定时器溢出时都应该调用IRQHandler。当我不启用 NVIC 时,程序运行正常,只是将一部分定时器值写入 GPIOC。但是一旦我启用 NVIC,程序 HardFaults,只要调用 initTimer3 函数。
到目前为止我尝试过的:
将 NVIC_EnableIRQ 行移动到函数的其他位置
- 仍然遇到同样的问题
在调用 initTimer3 函数之前添加延迟
- 在 initTimer3 函数正确执行之前的一切,只要调用 init 函数,程序就会出现硬故障。
使用不同的计时器
- 我已经尝试过使用 TIM7 和 TIM6
更新
设置 STKALIGN 位也不会改变任何内容。一旦中断被激活,HardFault 就会发生。
你有HF可能是因为调用中断例程时堆栈没有对齐。 F1xx 系列默认关闭硬件堆栈对齐,启动或用户应用程序必须启用它。或者,您可以使用适当的属性强制进行适当的对齐。
另一个常见问题:
启动文件中的中断例程名称必须多这一项。 例如,在 Cube MX 生成的代码中,矢量 table 在 startup_stm32f103xb.s 文件中定义。 定时器中断例程是:
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
检查您的文件,向量中使用了哪些名称 table。