HAL延时死循环调试报告

- **调试日期**: 2026-04-21 - **调试人员**: 系统调试团队

2026-07-04
HAL库延时函数死循环嵌入式调试

HAL_Delay函数死循环问题调试报告

文档信息


1. 问题描述

现象:

可能原因:

  1. Systick定时器配置错误
  2. 系统时钟频率与Systick配置不匹配
  3. 中断优先级问题
  4. 系统时钟配置后未重新初始化Systick

2. 问题分析

2.1 代码分析

HAL_Delay函数实现:


__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  uint32_t wait = Delay;

  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }

  while((HAL_GetTick() - tickstart) < wait)
  {
  }
}

HAL_IncTick函数实现:


__weak void HAL_IncTick(void)
{
  uwTick += uwTickFreq;
}

SysTick_Handler函数实现:


void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

系统初始化顺序:

  1. HAL_Init() - 初始化Systick定时器(使用默认MSI时钟)
  2. SystemClock_Config() - 配置系统时钟为HSI 16MHz
  3. 初始化其他外设

2.2 问题原因

主要原因:

次要原因:


3. 解决方案

3.1 重新初始化Systick定时器

修改前:


PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
  Error_Handler();
}

修改后:


PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
  Error_Handler();
}

// 重新初始化Systick定时器,确保使用正确的系统时钟频率
if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
{
  Error_Handler();
}

说明:

3.2 其他优化措施

  1. 确保FLASH_LATENCY设置正确:
  1. 检查中断优先级:
  1. 添加错误处理:

4. 测试验证

4.1 测试步骤

  1. 硬件连接:
  1. 软件设置:
  1. 测试执行:

4.2 预期结果

测试项目 预期结果
HAL_Delay(100) 正常退出,耗时约100ms
HAL_GetTick() 正常增长,每秒增加1000
系统运行 稳定,无死循环

5. 结论

通过分析和修改,解决了HAL_Delay函数进入死循环的问题。主要修改包括:

  1. 重新初始化Systick定时器:在系统时钟配置完成后,重新调用HAL_InitTick()函数,确保Systick使用正确的系统时钟频率
  2. 确保FLASHLATENCY设置正确:系统时钟为16MHz时,FLASHLATENCY设置为1
  3. 添加错误处理:对HAL_InitTick()的返回值进行检查

这些修改确保了Systick定时器的配置与系统时钟频率匹配,HALIncTick()能够按预期调用,HALGetTick()返回值正常增长,从而使HAL_Delay()函数能够正常退出。


文档结束

本文档提供了详细的HAL_Delay函数死循环问题的调试方案和解决方案,可作为系统维护的参考