2017-02-26 40 views
0

STM32를 배우기 위해 사용하는 STM32L476RC 핵 보드가 있습니다. STM32Cube HAL과 AC6 System Workbench를 사용하여 개발 중입니다. 나는 CubeMX에서 벗어나려고 노력하고 있습니다. 제 목표는 뭔가 일하는 것 이상으로 배우는 것입니다.STM32 SysTick은 2 배 빨리 계산됩니다.

내가 겪고있는 문제는 아래 코드를 사용하여 systick 타이머를 설정하려고 할 때 두 번째로 빠른 것으로 계산되는 것 같습니다.

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); 

그러나 전원을 켠 채로 기본 설정을 그대로두면 정확한 속도로 계산됩니다.

다음 클럭 설정을 생성하고 System Workbench에서 생성 된 새로운 프로젝트에 직접 붙여 넣기 위해 CubeMX를 사용했습니다.하지만 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를 사용하지 않고 처음부터 프로젝트를 생성하면 SystemInit에 시계가 system_stm32l4xx.c으로 초기화됩니다. SystemInit이 시작 파일 (startup_stm32l476xx.S)에 main보다 먼저 호출됩니다. 의견에 따르면 SystemInit는 PLL의 입력으로 MSI (4MHz)를 사용하여 40MHz에서 클럭을 초기화합니다.

시스템 시계가 두 배 빠르기 때문에 Systick의 차이점을 볼 수 있습니다.

+0

안녕하세요. 답장을 보내 주셔서 감사합니다. 나는 아직도 약간 혼란 스럽다. 나는 SysTick이 HCLK에서 파생되었다고 생각했다. 나는 복사 한 코드가 클럭 소스를 변경했다고 생각한다. 디버거를 밟았으며 SystemCoreClock이 올바르게 80MHz로 업데이트되었습니다. 나는 또한 PWM을 설정했고 그 80MHz에 맞는 올바른 캐리어 주파수를 측정했다. 그래서 HAL_SYSTICK_Config (HAL_RCC_GetHCLKFreq()/1000); 80MHz HCLK로 SysTick 인터럽트 시간을 올바르게 업데이트해야합니까? 문제는 내가 HCLK를 80MHz로 변경했지만 시스템 업데이트를하지 않으면 정확한 속도로 실행된다는 것입니다. 내가 업데이트 시스템을 실행하면, 빨리 실행됩니다. – Chris

+0

또한 CubeMX의 자동 생성 코드는 동일한 SystemInit 함수를 호출하고 SW에서 새 프로젝트를 생성하여 생성 된 코드와 정확히 동일한 시계를 설정하는 것으로 보입니다. 그런 다음 HAL_Init()을 호출 한 다음 SystemClock_Config()를 호출합니다. 나는 처음부터 생성 된 프로젝트와 CubeMX 코드 사이의 코드 차이를 보지 않고 있습니다. CubeMX 코드 : https://github.com/c-herring/testmx – Chris