STM32定时器中断周期

Posted

技术标签:

【中文标题】STM32定时器中断周期【英文标题】:STM32 Timer interrupt period 【发布时间】:2019-07-10 12:31:38 【问题描述】:

我正在使用 STM32F401RE 板,我希望每 X 秒(假设 60 秒)发生一次定时器中断。

中断回调有效。问题是中断不是每 60 秒发生一次(它每 34 秒发生一次)。我已经为预分频器和周期尝试了不同的值,但我尝试的一切都没有按我的意愿工作。

我在另一个项目中使用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);

谁能解释我做错了什么?如何配置定时器参数以达到我想要的周期?

提前谢谢你!

【问题讨论】:

由于您没有 .ioc 文件,我建议您在 STM32CubeMx 中创建一个新的简约项目,根据需要配置定时器和中断,让它自动生成源代码,测试它是否有效,然后使用git difftool 和融合来比较你的文件在它产生的和你现在拥有的之间。找到差异后,请返回此处并发布您找到的解决方案以供所有人查看,并将您自己的问题标记为正确的问题。我会赞成它。你知道STM32CubeMX怎么用吗? 【参考方案1】:

您能否捕获项目的 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();
    

弗兰基

【讨论】:

我已经尝试过 TIM_CLOCKDIVISION_DIV2 但它没有影响(中断仍然每 30 秒触发一次,这对我来说毫无意义)。我无法向您展示 CubeMX 的时钟配置,因为我正在处理 ST 已创建的项目,因此我没有 .ioc 文件。【参考方案2】:

将下面称为MX_NVIC_Init(); 的函数添加到main() 函数中

    static void MX_NVIC_Init(void)
    
      HAL_NVIC_SetPriority(TIM1_IRQn, 0, 0);
      HAL_NVIC_EnableIRQ(TIM10_IRQn);
    

【讨论】:

以上是关于STM32定时器中断周期的主要内容,如果未能解决你的问题,请参考以下文章

原子STM32带freeRTOS程序使用Timer3定时器时持续进入中断的问题解决

原子STM32带freeRTOS程序使用Timer3定时器时持续进入中断的问题解决

07 STM32F4定时器中断

STM32F4 定时器 - 预分频器或周期值必须除以二才能得到我期望的结果

使用STM32CubeIDE编写EC11 定时器中断方式

STM32 定时器中断