2017-02-26 130 views
0

我有一個STM32L476RC核心板,我正用它來學習STM32。我正在使用STM32Cube HAL和AC6 System Workbench進行開發。我試圖遠離CubeMX,因爲我的目標更多的是學習,而不僅僅是讓某些東西起作用。STM32 SysTick的計數速度是它的兩倍

我遇到的問題是當我嘗試使用下面的代碼設置systick計時器時,它似乎計數的速度是其應該快兩倍。

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); 

但是,如果我只是保持默認形式上電,那麼它是以正確的速度計數。

我已經使用CubeMX生成以下時鐘設置,並將其直接粘貼到System Workbench中創建的新項目中,但systick計數器似乎仍然是計數的兩倍。由CubeMX生成的項目似乎運行得很好但是

/** 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); 

} 

必須有我丟失的東西。也許不知怎的,滴答計數器配置在其他地方,並調用HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/ 1000);只是設置另一個滴答櫃檯?我不知道!請幫助我完全失去了正在發生的事情!

我通過簡單地閃爍LED和測量在邏輯分析儀的頻率測量刻度速度:

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(); 
} 

完整的代碼爲我的測試項目是在這裏: https://github.com/c-herring/STM32L476_Nucleo_FirstTest

謝謝!

回答

1

在您複製的SystemClock_Config函數中,STM32CubeMX將系統時鐘初始化爲80MHz。爲此,它使用HSI(16MHz)作爲PLL的輸入,然後將其除以1(PLLM),然後將其乘以10(PLLN),最後將其除以2(PLLR)。

當您不使用STM32CubeMX並從頭開始創建項目時,時鐘在SystemInitsystem_stm32l4xx.c中初始化。 SystemInit在啓動文件(startup_stm32l476xx.S)中的main之前被調用。根據評論SystemInit,使用MSI(4MHz)作爲PLL的輸入,將時鐘初始化爲40MHz。

系統時鐘快兩倍,因此您會看到Systick中的差異。

+0

嗨Guillaume。感謝您的回覆。我仍然有點困惑。我認爲SysTick來源於HCLK。我認爲我複製的代碼確實改變了時鐘源。我已經通過調試器,SystemCoreClock正確更新到80MHz。我還設置了一個PWM,並且我測量了80MHz的正確載波頻率。所以HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/ 1000);應該用80MHz HCLK正確更新SysTick中斷時間?問題在於,當我將HCLK更改爲80MHz時,請勿更新systick,它以正確的速度運行。當我更新systick時,它運行得很快 – Chris

+0

此外,CubeMX自動生成的代碼似乎也會調用相同的SystemInit函數,並將時鐘設置爲與通過在SW中創建新項目生成的代碼完全相同。然後它繼續調用HAL_Init()然後調用SystemClock_Config()。我從頭開始創建的項目和CubeMX代碼之間沒有看到代碼的區別。CubeMX代碼:https://github.com/c-herring/testmx – Chris