问题
I have a STM32L476RC nucleo board that I am using to learn STM32. I am using STM32Cube HAL and AC6 System Workbench to develop on. I am trying to stay away from CubeMX as my goal is more towards learning than just getting something to work.
The problem that I am having is when I try to set up the systick timer using the code below, it seems to be counting twice as fast as it should.
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
However if I just leave it default form the power-up then it is counting at the correct speed.
I have used CubeMX to generate the following clock setup, and paste it directly into a fresh project created in System Workbench, however the systick counter still seems to be counting twice as fast as it should be. The project that was generated by CubeMX seems to be running just fine however
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 10;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&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(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
//Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
//Error_Handler();
}
/**Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
//Error_Handler();
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
There must be something I am missing. Maybe somehow the tick counter is configured elsewhere, and calling HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); is just setting another tick counter? I have no idea! Please help I am completely lost as to what is going on!
I am measuring the tick speed by simply flashing a LED and and measuring the frequency on a logic analyser:
if (HAL_GetTick() - LEDstopwatch > 1000)
{
// Toggle the LED
//BSP_LED_Toggle(LED2);
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_10);
// Reset the stopwatch
LEDstopwatch = HAL_GetTick();
}
The full code for my test project is here: https://github.com/c-herring/STM32L476_Nucleo_FirstTest
Thanks!
回答1:
In the SystemClock_Config
function you copied, STM32CubeMX initializes the system clock at 80MHz. To do this, it uses HSI (16MHz) as input of the PLL, then divide it by 1 (PLLM), then multiplies it by 10 (PLLN) and finally divides its by 2 (PLLR).
When you don't use STM32CubeMX and creates a project from scratch, the clock is initialized in SystemInit
in the system_stm32l4xx.c
. SystemInit
is called before main
in the startup file (startup_stm32l476xx.S). According to the comments SystemInit
initializes the clock at 40MHz using the MSI (4MHz) as input of the PLL.
The system clock is twice faster therefore you see the difference in the Systick
.
来源:https://stackoverflow.com/questions/42467538/stm32-systick-counting-twice-as-fast-as-it-should