[STM32F4] 烧录程序后应用无法自动运行

[复制链接]
133|15
唐纳德d 发表于 2026-7-18 17:36 | 显示全部楼层 |阅读模式
我有多套适配不同 STM32 系列的工程,全部用了自己写的 Bootloader:
Bootloader 存放起始地址 0x08000000,应用程序放在更高地址,常规为 0x08010000。
Bootloader 与应用运行功能均正常:Bootloader 可以正常跳转启动应用,应用也能指令跳转回 Bootloader,这部分无任何问题。
唯一异常是使用 STM32CubeProgrammer 配合 ST-LINK V3 烧录新版应用。
即便勾选Run after programming,烧录完毕单片机也无法正常启动应用。
调试跟踪发现程序卡死在应用代码的无限循环内。
程序卡死的代码位置如下:
0801c444 <HAL_GetTick>:
  *       implementations in user file.
  * @retval tick value
  */
__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
801c444:        4b01              ldr        r3, [pc, #4]        @ (801c44c <HAL_GetTick+0x8>)
801c446:        6818              ldr        r0, [r3, #0]
}
801c448:        4770              bx        lr
801c44a:        bf00              nop
801c44c:        200013f0         .word        0x200013f0
0801c450 <HAL_Delay>:
  *       implementations in user file.
  * @param Delay  specifies the delay time length, in milliseconds.
  * @retval None
  */
__weak void HAL_Delay(uint32_t Delay)
{
801c450:        b538              push        {r3, r4, r5, lr}
801c452:        4604              mov        r4, r0
  uint32_t tickstart = HAL_GetTick();
801c454:        f7ff fff6         bl        801c444 <HAL_GetTick>
  uint32_t wait = Delay;
  /* Add a period to guaranty minimum wait */
  if (wait < HAL_MAX_DELAY)
801c458:        1c63              adds        r3, r4, #1
  {
    wait += (uint32_t)uwTickFreq;
801c45a:        bf1c              itt        ne
801c45c:        4b05              ldrne        r3, [pc, #20]        @ (801c474 <HAL_Delay+0x24>)
801c45e:        781b              ldrbne        r3, [r3, #0]
  uint32_t tickstart = HAL_GetTick();
801c460:        4605              mov        r5, r0
    wait += (uint32_t)uwTickFreq;
801c462:        bf18              it        ne
801c464:        18e4              addne        r4, r4, r3
  }
  while ((HAL_GetTick() - tickstart) < wait)
801c466:        f7ff ffed         bl        801c444 <HAL_GetTick>
801c46a:        1b43              subs        r3, r0, r5
801c46c:        42a3              cmp        r3, r4
801c46e:        d3fa              bcc.n        801c466 <HAL_Delay+0x16>
  {
  }
}

公羊子丹 发表于 2026-7-20 21:44 | 显示全部楼层
单纯相加得数是24,但21ic论坛发这个肯定不是小学数学题。我怀疑是三路采样电压汇总,你贴下采集电路和芯片型号,我帮你核对程序里的累加计算逻辑。
周半梅 发表于 2026-7-20 21:46 | 显示全部楼层
刚刷到还以为是灌水水帖,平时做小设备功耗统计经常要累加多路数值。建议分开分步计算,先9+10再加5,方便快速定位哪一路采样数据出现偏移。
帛灿灿 发表于 2026-7-20 21:47 | 显示全部楼层
之前调试多路电流采集踩过同类坑,数字看着简单,单位不统一直接相加完全没用。你检查下这三组数值,有没有V和mV、A和mA混用没换算?
童雨竹 发表于 2026-7-20 21:48 | 显示全部楼层
调侃一下,差点直接口算报答案,才反应过来这里全是硬件工程师。最好附上简易原理图,说明三组数字对应什么元器件,大伙才能给实用调试方案。
万图 发表于 2026-7-20 21:49 | 显示全部楼层
想请教楼主一个问题,这三组数值是串联回路电阻,还是三路独立负载参数?电路拓扑不一样不能直接累加,乱算出来的总量和实际工况差距很大。
Wordsworth 发表于 2026-7-20 21:50 | 显示全部楼层
分享个工程核对小技巧,分段保存每一步计算结果,先算出前两数之和再叠加最后一个,后续和单片机读出的总和对比,排查代码计算bug效率很高。
Bblythe 发表于 2026-7-20 21:51 | 显示全部楼层
三路数值求和在小电源总功率测算里很普遍,我建议你拿万用表分别测出三组原始数值手动核算,和程序输出对比,确认累加算法是否存在误差。
Pulitzer 发表于 2026-7-20 21:52 | 显示全部楼层
会不会是代码里存储总和的变量定义太小溢出了?手动求和结果24,短整型虽够用,但通道增多后容易出错,你可以去看下变量的数据类型设置。
Uriah 发表于 2026-7-20 21:52 | 显示全部楼层
本来准备直接划走帖子,转念做多路传感器采集经常汇总三路数据,如果你用STM32做信号采集,我可以分享一段带简单滤波的求和代码片段。
Clyde011 发表于 2026-7-20 21:53 | 显示全部楼层
只给出三个数字看不出实际工程场景,单纯算术结果没有工程参考价值。你补充下是阻值、电压还是温度采样,我们才能给你针对性排查思路。
elephant00 发表于 2026-7-22 16:11 | 显示全部楼层
卡在HAL_GetTick说明SysTick中断没有触发,uwTick变量***不更新。
故里说长安 发表于 2026-7-22 16:16 | 显示全部楼层
应用程序的SystemInit里若重新配置了PLL,切换时钟时可能短暂丢失HSE,导致SysTick停摆。
等凌晨日出 发表于 2026-7-22 16:27 | 显示全部楼层
在Bootloader跳转前手动把SysTick->CTRL寄存器清零,避免加载到应用后状态错乱。
classroom 发表于 2026-7-22 16:41 | 显示全部楼层
烧录后未自动运行,检查BOOT0引脚电平是否为低,高电平会停在Bootloader或系统存储区。
cr315 发表于 2026-7-22 17:13 | 显示全部楼层
应用程序向量表偏移量设置是否正确,SCB->VTOR需要在启动时指向0x08010000。
duo点 发表于 2026-7-22 17:44 | 显示全部楼层
STM32CubeProgrammer的Run after programming仅复位MCU,不保证电源时序,建议烧完后手动断电重启。
flycamelaaa 发表于 2026-7-22 18:15 | 显示全部楼层
检查应用工程的链接脚本,ROM起始地址和向量表偏移必须一致,否则中断向量取错。
茉璃夏 发表于 2026-7-22 18:22 | 显示全部楼层
不要依赖烧录器的自动运行,改为烧录后用上位机发自定义命令触发跳转,更可靠。
jcky001 发表于 2026-7-22 19:45 | 显示全部楼层
HAL_Init函数内会调用HAL_SetTickFreq,如果SysTick配置失败,uwTickFreq为0导致Delay死等。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

186

主题

187

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0