STM32F429ZGT6从用户代码跳转到system memory中的bootloader代码(STM32内置的bootloader)。
实际板子测试验证OK, 如果按芯片型号实现不了,来南京新港汇智科技园扇我脸。
如果有转载的,不懂的麻烦不要改动,改了记得标记好说明好型号条件啥的,别误人子弟。
再次重申MCU型号:STM32F429ZGT6
void Sys_Deinit(void)
{
HAL_UART_DeInit(&USB_UART); ///测试把这个串口还原初始化
HAL_UART_DeInit(&COOKER_UART);
HAL_UART_DeInit(&SCANNER_UART);
HAL_UART_DeInit(&RS485_UART);
}
static void JumpToBootloader (void)
{
uint32_t i = 0;
void (*SysMemBootJump) (void); /* 声明一个函数指针 */
__IO uint32_t BootAddr = 0x1FFF0000; /* STM32F4的系统BootLoader地址 */
/* 关闭全局中断 */
__disable_irq(); /* 禁止全局中断*/
/* 关闭滴答定时器,复位到默认值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
Sys_Deinit(); ///所有外设端口还原初始化 ,不然会产生错误,无法跳转
/* 设置所有时钟到默认状态,使用HSI时钟 */
HAL_RCC_DeInit();
/* 关闭所有中断,清除所有中断挂起标志 */
for (i = 0; i < 8; i++)
{
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
/* 使能全局中断 */
__enable_irq(); /* 使能全局中断 */
/* 设置重映射到系统Flash */
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); //(STM32F407VET6去掉此条就行)
///STM32F429ZGT6有双BANK,要加此条,参见手册AN2606
//For STM32 devices having the Dual Bank Boot feature, to jump to system memory from
//user code the user has first to remap the System Memory bootloader at address
//0x00000000 using SYSCFG register (except for STM32F7 Series), then jump to bootloader.
//For STM32F7 Series, the user has to disable nDBOOT and/or nDBANK features (in option
//bytes), then jump to bootloader.
//
/* 跳转到系统BootLoader,首地址是MSP,地址+4是复位中断服务程序地址 */
SysMemBootJump = (void (*) (void) ) (* ( (uint32_t *) (BootAddr + 4) ) );
/* 设置主堆栈指针 */
__set_MSP (* (uint32_t *) BootAddr);
/* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */
__set_CONTROL (0);
/* 跳转到系统BootLoader */
SysMemBootJump();
/* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */
while (1)
{
}
}
在用户代码中调用这个函数就行,如果芯片有读取保护,记得先去掉读保护才行,不然STM32CubeProgrammer会提示RDP错误,无法读取。
跳转到 STM32出厂自带system memory中的bootloader后,就能执行STM32自带的bootloader程序了,然后借用配套的STM32CubeProgrammer软件用UART方式连接芯片 就能进行串口烧录更新程序。