STM32 Период прерывания от таймера - PullRequest
0 голосов
/ 16 февраля 2019

Я использую плату STM32F401RE и хочу, чтобы прерывание таймера происходило каждые X секунд (скажем, 60 секунд).

Обратный вызов прерывания работает.Проблема в том, что прерывание происходит не каждые 60 секунд (это происходит каждые 34 секунды).Я пробовал разные значения для prescaler и period, но ничего, что я пробую, не работает так, как я хочу.

Я использую функции, сгенерированные CubeMX в другом проекте:

main.c

TIM_HandleTypeDef htim10;

int main(void)
{
    HAL_Init();

    SystemClock_Config();

    // Some other code

    MX_TIM10_Init();

    HAL_TIM_Base_Start_IT(&htim10);        

    while (1)
    {

    }
}

static void MX_TIM10_Init(void)
{    
    htim10.Instance = TIM10;
    htim10.Init.Prescaler = 35999;
    htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim10.Init.Period = 60000;
    htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    if (HAL_TIM_Base_Init(&htim10) != HAL_OK)
    {
        Error_Handler();
    }
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM10)
    {
        printf("ABCDEFG\n\r");
    }
}

void SystemClock_Config(void)
{    
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};

  __HAL_RCC_PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  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        = 16;
  RCC_OscInitStruct.PLL.PLLN        = 288;
  RCC_OscInitStruct.PLL.PLLP        = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ        = 6;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType       = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1);
  RCC_ClkInitStruct.SYSCLKSource    = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider   = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider  = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider  = RCC_HCLK_DIV1;
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

  __HAL_RCC_SYSCFG_CLK_ENABLE();
}

stm32f4xx_hal_msp.c

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
  if(htim_base->Instance==TIM10)
  {
    __HAL_RCC_TIM10_CLK_ENABLE();
    HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);
  }
}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{    
  if(htim_base->Instance==TIM10)
  {
    __HAL_RCC_TIM10_CLK_DISABLE();
    HAL_NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn);   
  } 
}

stm32f4xx_it.c

void TIM1_UP_TIM10_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&htim10);
}

Может кто-нибудь объяснить мне, что я делаю неправильно?Как настроить параметры таймера для достижения желаемого периода?

Заранее спасибо!

1 Ответ

0 голосов
/ 18 февраля 2019

Можете ли вы захватить экран конфигурации часов вашего CubeMX вашего проекта, это облегчит мне диагностику вашей проблемы!

РЕДАКТИРОВАТЬ 1: я проверяю ваш код, таймер 10 запускается источником синхронизации APB2, поэтому ваш таймер 10часы работают в два раза быстрее.Вы должны настроить свой код следующим образом:

static void MX_TIM10_Init(void)
{    
    htim10.Instance = TIM10;
    htim10.Init.Prescaler = 35999;
    htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim10.Init.Period = 60000;
    htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2; //TIM_CLOCKDIVISION_DIV1
    if (HAL_TIM_Base_Init(&htim10) != HAL_OK)
    {
        Error_Handler();
    }
}

Фрэнки

...