2017-02-26 6 views
0

J'ai un panneau nucléo STM32L476RC que j'utilise pour apprendre STM32. J'utilise STM32Cube HAL et AC6 System Workbench pour développer. J'essaie de rester loin de CubeMX car mon but est plus d'apprendre que de simplement faire quelque chose pour travailler. Le problème que je rencontre est que lorsque j'essaie de configurer le minuteur systick en utilisant le code ci-dessous, il semble compter deux fois plus vite qu'il le devrait.STM32 SysTick comptant deux fois plus vite qu'il le faudrait

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); 

Cependant, si je laisse juste défaut la forme sous tension, puis il compte à la bonne vitesse.

J'ai utilisé CubeMX pour générer la configuration d'horloge suivante, et la coller directement dans un nouveau projet créé dans System Workbench, mais le compteur systick semble toujours compter deux fois plus vite qu'il devrait l'être. Le projet qui a été généré par CubeMX semble fonctionner très bien mais

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

} 

Il doit y avoir quelque chose que je suis absent. Peut-être que le compteur de taquets est configuré ailleurs et appelle HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq()/1000); est juste de définir un autre compteur de tique? Je n'ai aucune idée! S'il vous plaît, aidez-moi, je suis complètement perdu quant à ce qui se passe!

Je mesure la vitesse de tique en clignotant simplement une LED et et la mesure de la fréquence sur un analyseur logique:

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

Le code complet pour mon projet de test est ici: https://github.com/c-herring/STM32L476_Nucleo_FirstTest

Merci!

Répondre

1

Dans la fonction SystemClock_Config que vous avez copiée, STM32CubeMX initialise l'horloge système à 80 MHz. Pour ce faire, il utilise HSI (16MHz) comme entrée de la PLL, puis le divise par 1 (PLLM), puis le multiplie par 10 (PLLN) et divise finalement par 2 (PLLR). Lorsque vous n'utilisez pas STM32CubeMX et créez un projet à partir de rien, l'horloge est initialisée au SystemInit dans le . SystemInit est appelée avant main dans le fichier de démarrage (startup_stm32l476xx.S). Selon les commentaires SystemInit initialise l'horloge à 40MHz en utilisant le MSI (4MHz) comme entrée de la PLL.

L'horloge système est deux fois plus rapide, vous voyez donc la différence dans Systick.

+0

Bonjour Guillaume. Merci pour votre réponse. Je suis encore un peu confus. Je pensais que SysTick est dérivé de HCLK. Je pense que le code que j'ai copié a changé la source d'horloge. J'ai traversé le débogueur et SystemCoreClock est correctement mis à jour à 80MHz. J'ai également mis en place un PWM et je mesure la fréquence de transport correcte pour ce 80MHz. Donc HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq()/1000); devrait correctement mettre à jour le temps d'interruption SysTick avec la HCLK 80MHz? Le problème est quand je change HCLK à 80MHz mais ne met pas à jour systick, il fonctionne à la bonne vitesse. Quand je mets à jour systick, ça marche vite – Chris

+0

Aussi, il semble que le code généré automatiquement par CubeMX appelle aussi la même fonction SystemInit et configure l'horloge exactement de la même manière que le code généré en créant un nouveau projet dans SW. Il appelle ensuite HAL_Init() puis SystemClock_Config(). Je ne vois pas de différence dans le code entre le projet créé à partir de rien et le code CubeMX. Code CubeMX: https://github.com/c-herring/testmx – Chris