2020-11-15 08:10 AM
Hello,
I am trying to set the clock frequency to max of 480 MHz. I tried 120 MHz and there is not problem with that. The block code is very similar for both, so not sure what is going wrong.
I feel the oscillator fails and goes into an error state.
Based on datasheet max speed is 480 MHz and PLLM, N, Q are set based on valid values taken from CubeMX.
I also tried all possible value for "FLASH_ACR_LATENCY_15WS" since this is the only difference between 2 code blocks of 120 and 480.
Here is USART output:
[2020-11-15_10:56:03:539] Before.
[2020-11-15_10:56:03:539]SYSCLK : 64000000Hz
[2020-11-15_10:56:03:539]HCLK : 64000000Hz
[2020-11-15_10:56:03:539]PCLK1 : 64000000Hz
[2020-11-15_10:56:03:539]PCLK2 : 64000000Hz
[2020-11-15_10:56:03:539] AFTER 120.
[2020-11-15_10:56:03:539]SYSCLK : 64000000Hz
[2020-11-15_10:56:03:539]HCLK : 64000000Hz
[2020-11-15_10:56:03:539]PCLK1 : 64000000Hz
[2020-11-15_10:56:03:539]PCLK2 : 64000000Hz
[2020-11-15_10:56:03:574]Something`went`wrong
#include "main.h"
TIM_HandleTypeDef htim2;
UART_HandleTypeDef huart2;
void SystemClock_Config(uint16_t Clock_Freq);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_TIM2_Init(void);
void GPIO_Init(void);
char *user_data = "Hello world, I made it using STM32 ARM Cortex M7!\r\n";
int main(void)
{
char msg[100];
HAL_Init();
MX_USART2_UART_Init();
user_data = " Before.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
memset(msg,0,sizeof(msg));
sprintf(msg,"SYSCLK : %ldHz\r\n",HAL_RCC_GetSysClockFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"HCLK : %ldHz\r\n",HAL_RCC_GetHCLKFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK1 : %ldHz\r\n",HAL_RCC_GetPCLK1Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK2 : %ldHz\r\n",HAL_RCC_GetPCLK2Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
//SystemClock_Config(120);
MX_GPIO_Init();
GPIO_Init();
MX_USART2_UART_Init();
MX_TIM2_Init();
user_data = " AFTER 120.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
memset(msg,0,sizeof(msg));
sprintf(msg,"SYSCLK : %ldHz\r\n",HAL_RCC_GetSysClockFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"HCLK : %ldHz\r\n",HAL_RCC_GetHCLKFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK1 : %ldHz\r\n",HAL_RCC_GetPCLK1Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK2 : %ldHz\r\n",HAL_RCC_GetPCLK2Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
SystemClock_Config(480);
MX_USART2_UART_Init();
/*
user_data = " AFTER 480.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
// Error occurred
Error_Handler();
}
memset(msg,0,sizeof(msg));
sprintf(msg,"SYSCLK : %ldHz\r\n",HAL_RCC_GetSysClockFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"HCLK : %ldHz\r\n",HAL_RCC_GetHCLKFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK1 : %ldHz\r\n",HAL_RCC_GetPCLK1Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK2 : %ldHz\r\n",HAL_RCC_GetPCLK2Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
*/
while (1)
{
}
}
void SystemClock_Config(uint16_t Clock_Freq)
{
RCC_OscInitTypeDef OSC_Init;
RCC_ClkInitTypeDef clk_init;
uint8_t FLatency = 0;
OSC_Init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
OSC_Init.HSIState = RCC_HSI_ON;
OSC_Init.HSICalibrationValue = 16;
OSC_Init.PLL.PLLState = RCC_PLL_ON;
OSC_Init.PLL.PLLSource = RCC_PLLSOURCE_HSI;
switch(Clock_Freq)
{
case SYS_CLOCK_FREQ_120_MHZ:
{
OSC_Init.PLL.PLLM = 4;
OSC_Init.PLL.PLLN = 15;
OSC_Init.PLL.PLLP = 2;
OSC_Init.PLL.PLLQ = 2;
OSC_Init.PLL.PLLR = 2;
clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
clk_init.SYSCLKDivider = RCC_SYSCLK_DIV2;
clk_init.AHBCLKDivider = RCC_HCLK_DIV2;
clk_init.APB3CLKDivider = RCC_APB3_DIV2;
clk_init.APB1CLKDivider = RCC_APB1_DIV2;
clk_init.APB2CLKDivider = RCC_APB2_DIV2;
clk_init.APB4CLKDivider = RCC_APB4_DIV2;
FLatency = FLASH_ACR_LATENCY_2WS;
break;
}
case SYS_CLOCK_FREQ_480_MHZ:
{
OSC_Init.PLL.PLLM = 4;
OSC_Init.PLL.PLLN = 60;
OSC_Init.PLL.PLLP = 2;
OSC_Init.PLL.PLLQ = 2;
OSC_Init.PLL.PLLR = 2;
clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
clk_init.SYSCLKDivider = RCC_SYSCLK_DIV1;
clk_init.AHBCLKDivider = RCC_HCLK_DIV2;
clk_init.APB3CLKDivider = RCC_APB3_DIV2;
clk_init.APB1CLKDivider = RCC_APB1_DIV2;
clk_init.APB2CLKDivider = RCC_APB2_DIV2;
clk_init.APB4CLKDivider = RCC_APB4_DIV2;
FLatency = FLASH_ACR_LATENCY_15WS;
break;
}
default:
return;
}
if (HAL_RCC_OscConfig(&OSC_Init) != HAL_OK)
{
Error_Handler();
}
if(HAL_RCC_ClockConfig(&clk_init, FLatency) != HAL_OK)
{
Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}
static void MX_TIM2_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 4294967295;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 921600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_14, GPIO_PIN_RESET);
/*Configure GPIO pins : PD12 PD14 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
void GPIO_Init(void)
{
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitTypeDef ledgpio;
ledgpio.Pin = GPIO_PIN_14;
ledgpio.Mode = GPIO_MODE_OUTPUT_PP;
ledgpio.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOD, &ledgpio);
}
void Error_Handler(void)
{
user_data = "Something went wrong\r\n";
HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY);
while(1)
{
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
}
}
Solved! Go to Solution.
2020-11-16 07:10 AM
Thanks! It worked after making bellow modifications.
Here is my findings:
1.Bellow config is a must as you mentioned
2.Bellow is also a must when configuring the PLLM, N, Q
3.It is better to add bellow 2 lines as well to the clock config
Here is the complete working code. Changes were only made to "SystemClock_Config"
void SystemClock_Config(uint16_t Clock_Freq)
{
RCC_OscInitTypeDef OSC_Init;
RCC_ClkInitTypeDef clk_init;
uint8_t FLatency = 0;
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
OSC_Init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
OSC_Init.HSIState = RCC_HSI_DIV1;
OSC_Init.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
OSC_Init.PLL.PLLState = RCC_PLL_ON;
OSC_Init.PLL.PLLSource = RCC_PLLSOURCE_HSI;
switch(Clock_Freq)
{
case SYS_CLOCK_FREQ_120_MHZ:
{
OSC_Init.PLL.PLLM = 4;
OSC_Init.PLL.PLLN = 15;
OSC_Init.PLL.PLLP = 2;
OSC_Init.PLL.PLLQ = 2;
OSC_Init.PLL.PLLR = 2;
clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
clk_init.SYSCLKDivider = RCC_SYSCLK_DIV2;
clk_init.AHBCLKDivider = RCC_HCLK_DIV2;
clk_init.APB3CLKDivider = RCC_APB3_DIV2;
clk_init.APB1CLKDivider = RCC_APB1_DIV2;
clk_init.APB2CLKDivider = RCC_APB2_DIV2;
clk_init.APB4CLKDivider = RCC_APB4_DIV2;
FLatency = FLASH_ACR_LATENCY_2WS;
break;
}
case SYS_CLOCK_FREQ_480_MHZ:
{
OSC_Init.PLL.PLLM = 4;
OSC_Init.PLL.PLLN = 60;
OSC_Init.PLL.PLLP = 2;
OSC_Init.PLL.PLLQ = 2;
OSC_Init.PLL.PLLR = 2;
OSC_Init.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
OSC_Init.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
OSC_Init.PLL.PLLFRACN = 0;
clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
clk_init.SYSCLKDivider = RCC_SYSCLK_DIV1;
clk_init.AHBCLKDivider = RCC_HCLK_DIV2;
clk_init.APB3CLKDivider = RCC_APB3_DIV2;
clk_init.APB1CLKDivider = RCC_APB1_DIV2;
clk_init.APB2CLKDivider = RCC_APB2_DIV2;
clk_init.APB4CLKDivider = RCC_APB4_DIV2;
FLatency = FLASH_LATENCY_4;
break;
}
default:
return;
}
if (HAL_RCC_OscConfig(&OSC_Init) != HAL_OK)
{
Error_Handler();
}
if(HAL_RCC_ClockConfig(&clk_init, FLatency) != HAL_OK)
{
Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}
2020-11-15 08:13 AM
Your code as currently written doesn't output to the UART after the attempted clock change:
...
SystemClock_Config(480);
MX_USART2_UART_Init();
/*
user_data = " AFTER 480.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
// Error occurred
Error_Handler();
}
memset(msg,0,sizeof(msg));
sprintf(msg,"SYSCLK : %ldHz\r\n",HAL_RCC_GetSysClockFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"HCLK : %ldHz\r\n",HAL_RCC_GetHCLKFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK1 : %ldHz\r\n",HAL_RCC_GetPCLK1Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK2 : %ldHz\r\n",HAL_RCC_GetPCLK2Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
*/
while (1)
{
}
Also note you need some other stuff for 480MHz mode. CubeMX will generate the code for you.
// Configure the main internal regulator output voltage
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
2020-11-15 08:15 AM
I only commented that part to isolate the issue. The code goes into the error handler after "calling SystemClock_Config(480)"
2020-11-16 06:12 AM
I added to my post. Not sure if you saw the last part.
Try using the code generated from CubeMX. You need to do more than just PLL settings to go into 480MHz mode.
2020-11-16 07:10 AM
Thanks! It worked after making bellow modifications.
Here is my findings:
1.Bellow config is a must as you mentioned
2.Bellow is also a must when configuring the PLLM, N, Q
3.It is better to add bellow 2 lines as well to the clock config
Here is the complete working code. Changes were only made to "SystemClock_Config"
void SystemClock_Config(uint16_t Clock_Freq)
{
RCC_OscInitTypeDef OSC_Init;
RCC_ClkInitTypeDef clk_init;
uint8_t FLatency = 0;
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
OSC_Init.OscillatorType = RCC_OSCILLATORTYPE_HSI;
OSC_Init.HSIState = RCC_HSI_DIV1;
OSC_Init.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
OSC_Init.PLL.PLLState = RCC_PLL_ON;
OSC_Init.PLL.PLLSource = RCC_PLLSOURCE_HSI;
switch(Clock_Freq)
{
case SYS_CLOCK_FREQ_120_MHZ:
{
OSC_Init.PLL.PLLM = 4;
OSC_Init.PLL.PLLN = 15;
OSC_Init.PLL.PLLP = 2;
OSC_Init.PLL.PLLQ = 2;
OSC_Init.PLL.PLLR = 2;
clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
clk_init.SYSCLKDivider = RCC_SYSCLK_DIV2;
clk_init.AHBCLKDivider = RCC_HCLK_DIV2;
clk_init.APB3CLKDivider = RCC_APB3_DIV2;
clk_init.APB1CLKDivider = RCC_APB1_DIV2;
clk_init.APB2CLKDivider = RCC_APB2_DIV2;
clk_init.APB4CLKDivider = RCC_APB4_DIV2;
FLatency = FLASH_ACR_LATENCY_2WS;
break;
}
case SYS_CLOCK_FREQ_480_MHZ:
{
OSC_Init.PLL.PLLM = 4;
OSC_Init.PLL.PLLN = 60;
OSC_Init.PLL.PLLP = 2;
OSC_Init.PLL.PLLQ = 2;
OSC_Init.PLL.PLLR = 2;
OSC_Init.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
OSC_Init.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
OSC_Init.PLL.PLLFRACN = 0;
clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
clk_init.SYSCLKDivider = RCC_SYSCLK_DIV1;
clk_init.AHBCLKDivider = RCC_HCLK_DIV2;
clk_init.APB3CLKDivider = RCC_APB3_DIV2;
clk_init.APB1CLKDivider = RCC_APB1_DIV2;
clk_init.APB2CLKDivider = RCC_APB2_DIV2;
clk_init.APB4CLKDivider = RCC_APB4_DIV2;
FLatency = FLASH_LATENCY_4;
break;
}
default:
return;
}
if (HAL_RCC_OscConfig(&OSC_Init) != HAL_OK)
{
Error_Handler();
}
if(HAL_RCC_ClockConfig(&clk_init, FLatency) != HAL_OK)
{
Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}