stm32h743iit6 配置 FMC 的时钟源
使用 cubemx 可以看到 FMC 支持的时钟源
HCLK3
HCLK3 所在的位置如下图所示:
PLL1Q
和 PLL2R
下图是 3 个 PLL
所谓的 PLL1Q
和 PLL2R
是指 PLL 的 2 个输出通道。如下所示:
上面的红色方框框起来的 DIVQ1
就是 PLL1Q
,下方的红色方框框起来的 DIVR2
就是 PLL2R
.
PERCK
PERCK 的位置如下图所示
这就是一个多路复用器。
封装一个配置函数
void bsp::config_fmc_clock_source(std::string const &clock_source_name)
{RCC_PeriphCLKInitTypeDef PeriphClkInitStruct{};if (clock_source_name == "hclk3"){PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_D1HCLK;HAL_StatusTypeDef result = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);if (result != HAL_OK){throw std::runtime_error{CODE_POS_STR + "配置 FMC 时钟源失败。"};}return;}if (clock_source_name == "pll1_q"){PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL;HAL_StatusTypeDef result = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);if (result != HAL_OK){throw std::runtime_error{CODE_POS_STR + "配置 FMC 时钟源失败。"};}return;}if (clock_source_name == "pll2_r"){PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_PLL2;HAL_StatusTypeDef result = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);if (result != HAL_OK){throw std::runtime_error{CODE_POS_STR + "配置 FMC 时钟源失败。"};}return;}if (clock_source_name == "per_ck"){PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_CLKP;HAL_StatusTypeDef result = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);if (result != HAL_OK){throw std::runtime_error{CODE_POS_STR + "配置 FMC 时钟源失败。"};}return;}throw std::invalid_argument{CODE_POS_STR + "无效的时钟源名称。"};
}
吐槽
stm32 的时钟源和时钟信号命名真的是乱七八糟的。而且同一个信号还有多种名称。HAL 库的 API 中的名称和 cubemx 中显示的还不一样。以上文中的 PERCK
为例, cubemx 中对同一个时钟信号也会在不同地方使用不同名称。FMC 时钟源选择的最后一个选项干脆在旁边备注 PER Source Mux
不好吗,非要整出一个 PERCK
让人一下子找不到在哪,还要选中后根据频率去到处找和推测是哪一个。