你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32实战项目:HAL_RCC_OscConfig中程序卡死问题解决办法

[复制链接]
STMCU小助手 发布时间:2022-4-10 16:48
现象复现
项目中一个是IAP程序,另一个是APP程序,两个程序都是使用STM32CubeIDE生成,当程序跳转到APP中并且执行到函数SystemClock_Config中的时候,在初始化锁相环调用HAL_RCC_OscConfig函数的时候返回HAL_ERROR或者直接卡死在里面。

为什么在IAP中可以初始化通过,但是在APP中却通不过,查阅STM32F4xx参考手册发现这么一段话:

C5)Z[0`UUDFGQYX0P2KB{@E.png

那么出现这个问题的原因也就清楚了,因为在IAP中已经初始化了PLL,在APP中再次初始化就不成功。

解决办法
我查找ST官方HAL固件库中对重复配置RCC时钟的时候,发现他是这么做的:
1.先将时钟源选择为内部时钟
2.初始化锁相环
3.将时钟源在切换回外部时钟源
4.禁用内部高速时钟(可选步骤,如果内部高速时钟不用的话,建议禁掉)

官方代码如下:

CWW59K4%$L~GB`~][c1EN.png

以下是我的示例代码:

  1. void SystemClock_Config(void)
  2. {
  3.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  4.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  5.   /** Configure the main internal regulator output voltage
  6.   */
  7.   __HAL_RCC_PWR_CLK_ENABLE();
  8.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  9.   // 先将时钟源选择为内部时钟
  10.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
  11.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  12.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  13.   {
  14.     Error_Handler();
  15.   }

  16.   // 初始化锁相环
  17.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  18.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  19.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  20.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  21.   RCC_OscInitStruct.PLL.PLLM = 4;
  22.   RCC_OscInitStruct.PLL.PLLN = 168;
  23.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  24.   RCC_OscInitStruct.PLL.PLLQ = 4;
  25.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  26.   {
  27.     Error_Handler();
  28.   }

  29.   // 锁相环已经初始化完毕了,将时钟源在切换回外部时钟源
  30.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  31.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  32.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  33.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  34.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  35.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  36.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  37.   {
  38.     Error_Handler();
  39.   }

  40.         // 禁用内部高速时钟
  41.         RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  42.         RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
  43.         RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  44.         if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  45.         {
  46.           Error_Handler();
  47.         }
  48. }
复制代码

通过以上操作后,问题成功解决!

解决F4系列这个问题之后,我又去看F1系列的参考手册,发现:

Z~BM4E0%XV9CHOD)9M{EA`A.png

同样的也是需要在使能PLL之前完成时钟配置,不过在实际中发现,F1系列的IAP跳转到APP中并没有卡死在HAL_RCC_OscConfig函数中。

还有一个更快捷方便的办法,就是在IAP中不使用PLL,直接使用HSE或HSI的8M晶振作为系统时钟,如下图时钟的配置:

H0$`KI_NV8G756SU`T6(}]H.png



收藏 评论0 发布时间:2022-4-10 16:48

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版