大家好,
我遇到了一个奇怪的问题。我想在我的
STM32F446 芯片上使用 USART3 或 UART5。我们在
PCB 上有芯片,所以我不是在谈论核板。
问题是当我执行 system_clock_config() 时,列出的 uart 不起作用。
- void init()
- {
- // Loop forever on error such that the error can be diagnosed with a debugger.
- auto loop_forever = []() { while (true) {} };
- if (HAL_Init() != HAL_OK) { loop_forever(); }
- if (system_clock_config() != HAL_OK) { loop_forever(); }
- gpio_config();
- }
- auto system_clock_config()
- {
- RCC_ClkInitTypeDef rcc_clk_init {};
- RCC_OscInitTypeDef rcc_osc_init {};
- /* Enable Power Control clock */
- __HAL_RCC_PWR_CLK_ENABLE();
- /* Max frequency of the chip is 168MHz (voltage scale 1, normal mode)
- * or 180Mhz (voltage scale 1, overdrive mode)
- * Lower power consumption and heat can be achieved if the internal voltage regulator
- * is set to a lower level.
- * With a scale factor of 3, the lowest voltage across the two ceramic condensators
- * of the oscillator is configured. The maximum frequency for a scale factor 3 is 120MHz.
- * The RCC frequency HCLK (SystemCoreClock) is configured to 80MHz, which results in
- * even lower energy consumption.
- * It must be taken into account that the TSIC506 of this sensorhub is based on timer
- * configuration for data bit reading. Configuring HCLK below 80MHz is therefore not considered.
- * To update the voltage scaling value regarding system frequency,
- * refer to product datasheet and the CubeMX graphical clock configuration tool.
- */
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
- /* Enable HSI Oscillator and activate PLL with HSI as source */
- rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
- rcc_osc_init.HSIState = RCC_HSI_ON;
- rcc_osc_init.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
- rcc_osc_init.LSIState = RCC_LSI_ON;
- rcc_osc_init.PLL.PLLState = RCC_PLL_ON;
- rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSI;
- rcc_osc_init.PLL.PLLM = 8;
- rcc_osc_init.PLL.PLLN = 80;
- rcc_osc_init.PLL.PLLP = RCC_PLLP_DIV2;
- if (const auto ret = HAL_RCC_OscConfig(&rcc_osc_init); ret != HAL_OK)
- {
- return ret;
- }
- /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
- clocks dividers */
- rcc_clk_init.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
- RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
- rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
- rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV2;
- rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV2;
- if (const auto ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_3); ret != HAL_OK)
- {
- return ret;
- }
- return HAL_OK;
- }
我对此进行了更深入的研究,发现只有 HAL_RCC_ClockConfig() 和配置的结构使 uart 无法工作。也有意义,因为 HAL_RCC_OscConfig() 对外围设备没有直接影响。无论如何,如果我只是离开 system_clock_config() 并只执行 HAL_Init(),uart 工作但我们所有的 I2C 和定时器相关的传感器测量都将失败。
我在手册中看到有一个映射表,它说 APB1 涵盖 UART2-5(加上定时器和所有 I2C),APB2“仅”涵盖 UART1 和 6。如果我执行 system_clock_config(),UART1 仍然有效(这就是 uart我们一直在这块板上运行,这是我们唯一需要的 uart。UART 3 或 5 现在是我们的扩展。它们因我们的标准初始化“system_clock_config()”) 而失败。