Embedded STM32F030F4P6仅在从闪存引导时运行中断处理程序。从引导加载程序引导时重置
该守则—Embedded STM32F030F4P6仅在从闪存引导时运行中断处理程序。从引导加载程序引导时重置,embedded,stm32,cortex-m,stm32f0,Embedded,Stm32,Cortex M,Stm32f0,该守则— #include<stm32f030x6.h> void _delay_ms(unsigned int del) { //Delay with systick } void sys_init() { //Set Clock to 6 * 8MHz crystal } void TIM14_IRQHandler(void) { //If UEV was generated, toggle PA4 (Connected to LED) if(TIM14-&
#include<stm32f030x6.h>
void _delay_ms(unsigned int del) {
//Delay with systick
}
void sys_init() {
//Set Clock to 6 * 8MHz crystal
}
void TIM14_IRQHandler(void) {
//If UEV was generated, toggle PA4 (Connected to LED)
if(TIM14->SR & TIM_SR_UIF) {
GPIOA->BSRR = (GPIOA->ODR & GPIO_ODR_4)?(GPIO_BSRR_BR_4):(GPIO_BSRR_BS_4);
TIM14->SR &= ~TIM_SR_UIF;
}
}
int main(void) {
sys_init();
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM14EN;
GPIOA->MODER = 0b1 << GPIO_MODER_MODER4_Pos;
//GPIOA->AFR[0] = 4 << GPIO_AFRL_AFRL4_Pos;
//Init timer
TIM14->ARR = 731;
TIM14->PSC = 0xffff;
TIM14->DIER |= TIM_DIER_UIE;
TIM14->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM14_IRQn);
NVIC_SetPriority(TIM14_IRQn, 0);
while(1);
}
#包括
无效延迟毫秒(无符号整数del){
//systick延迟
}
void sys_init(){
//将时钟设置为6*8MHz晶体
}
无效TIM14_IRQHandler(无效){
//如果生成UEV,切换PA4(连接至LED)
如果(TIM14->SR&TIM\U SR\U UIF){
GPIOA->BSRR=(GPIOA->ODR&GPIO\U ODR\U 4)?(GPIO\U BSRR\U BR\U 4):(GPIO\U BSRR\U BS\U 4);
TIM14->SR&=~TIM_SR_UIF;
}
}
内部主(空){
sys_init();
RCC->AHBENR |=RCC_AHBENR|u GPIOAEN;
RCC->APB1ENR |=RCC_APB1ENR_TIM14EN;
GPIOA->MODER=0b1 AFR[0]=4 ARR=731;
TIM14->PSC=0xffff;
TIM14->DIER |=TIM | u DIER |;
TIM14->CR1 |=TIM_CR1_CEN;
NVIC_EnableIRQ(TIM14_IRQn);
NVIC_设置优先级(TIM14_IRQn,0);
而(1),;
}
正如问题中提到的,当我直接从闪存中引导它(BOOT0连接到GND)时,这段代码工作得很好,但当使用引导加载程序时,它不工作。一旦中断被触发,芯片就会复位并再次回到引导加载程序。我如何解决这个问题?我应该提到的是,我使用的是定制的和经过大量修改的。您遇到了该微控制器中使用的Cortex-M0内核的限制 Cortex-M0只能使用在地址0x0处映射的中断向量表。当微控制器配置为引导到引导加载程序时,系统内存映射到地址0,因此引导加载程序的向量表用于所有中断。因此,您无法在通过引导加载程序启动的应用程序中安全地使用中断 在Cortex-M0+和更高的部分上,您可以设置
SCB->VTOR
以使用内存中其他位置的向量表。但是,该寄存器不存在于Cortex-M0部件上,如STM32F0,因此这不是您的选项
考虑使用SWD程序员,比如ST Link,来编程微控制器,而不是引导加载程序。这也将允许您调试应用程序。根据Dashwufs的评论,由于您到boot.s和linker.script的链接可以工作,我假设,您的向量表仍然是引导加载程序中的向量表,并且您的应用程序中断只是跳到那里。如果引导加载程序在该向量表中没有映射ISR,那么它可能只是发出一个重置(由于非法地址/指令而导致的陷阱/异常)。您可以使用通用向量表间接跳转到RAM提供的向量表,该向量表由您的应用程序在启动代码中覆盖。谢谢您的回答。我知道您不能偏移向量表,但不知道您不能执行中断,因为您可以在引导加载程序模式下运行重置处理程序(使用stm32flash-g0),我没有专门研究过,但我怀疑这实际上不是作为中断发生的。STM32引导加载程序协议没有“重置为闪存”命令。它确实有一个“跳转到地址”命令,但地址是随命令提供的
stm32flash
可能正在从二进制文件中读取重置向量。虽然向量表必须从地址0开始,但MCU可以将内部RAM映射到那里,因此应用程序可以将向量表复制到RAM的开头,并更改SYSCFG
中的映射,使MCU使用新的向量表。