Проблемы с настройкой SystemClock для STM32L4R5

#c #embedded #stm32 #system-clock

#c #встроенный #stm32 #системные часы

Вопрос:

Мой первоначальный проект, созданный на CubeMX, работал на частоте 32 МГц. Поскольку я пытаюсь реализовать АЦП с частотой 80 МГц, я решил увеличить системную частоту до 100 МГц. Изменения, которые я внес в исходный код, находятся в main.c:

 void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Configure the main internal regulator output voltage 
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 12;
  RCC_OscInitStruct.PLL.PLLN = 50;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(amp;RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(amp;RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }


  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_USB
                              |RCC_PERIPHCLK_ADC;
  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
  PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
  PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
  PeriphClkInit.PLLSAI1.PLLSAI1M = 6;
  PeriphClkInit.PLLSAI1.PLLSAI1N = 20;
  PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV2;
  PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
  PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
  PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_ADC1CLK;
  if (HAL_RCCEx_PeriphCLKConfig(amp;PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }


}

  

Я только что изменил PLLM и PLLN для настройки на 100 МГц. Теперь, когда я отлаживаю программу в системном регистре, я вижу, что:

SYST_CSR = 7 SYST_RVR = 99999

Итак, я думаю, что галочки правильно показывают 100 МГц. Я не уверен, насколько это правильно, но, скажем, для выполнения простой строки:

 i_flag=1;
  

требуется 7 циклов в соответствии с SYST_CVR-> CURRENT.

Учитывая некоторые проблемы с синхронизацией с АЦП, я полагаю, что я неправильно установил системные часы, и они по-прежнему 32 МГц. Есть идеи, верны ли мой код и проверки?

Комментарии:

1. В большинстве микроконтроллеров вам необходимо настроить состояния ожидания флэш-памяти при выходе за пределы ~ 50 МГц. Я не вижу этого в вашем коде, но, возможно, это обрабатывается оборудованием или драйверами? Нужны ли состояния ожидания в этой части и кто отвечает за их настройку?

2. (если вы неправильно определяете состояния ожидания, код обычно сразу же выходит из строя, программа зависает или выходит из строя)

3. Спасибо за ваше руководство! Я понятия не имел об этом. Уже установил его на 4 WS, поскольку это значение для моего процессора. Просто вставил его в конец SystemClock_Config(). Я все еще не уверен, что все работает правильно. Теперь для выполнения вышеупомянутой команды требуется 10 циклов. Я могу восстановить исходные 32 МГц или переделать CubeMX с чистой настройкой 100 МГц.

4. К сожалению, эти вредоносные библиотеки от поставщика в основном вредны. Вместо этого я бы рекомендовал поискать исходный код (на Github и т.д.), Который не использует ST HAL, но выполняет настройку часов вручную. Также могут быть примечания к приложению от ST. Если все остальное не удается, всегда есть руководство.