首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HAL_GetTick存在精度问题

HAL_GetTick存在精度问题
EN

Stack Overflow用户
提问于 2022-10-13 12:14:44
回答 1查看 60关注 0票数 0

我试着在stm32f103r6t上做我自己的毫秒计时器,我使用了计时器2,在经过一段时间后中断,然后我把计数器增加了一步。时钟频率为64 The (APB1 1&2也为64 the ),预调用者为127,周期值设置为500。我通过在中断上切换一个引脚进行测试,在示波器上我得到了1ms的半周期(这是预料中的)。我所做的另一个测试是将它与__Hal_get_ticks()进行比较,并将其发送到uart。__Hal_get_ticks()似乎更快,而且它们之间的差异随着时间的推移而不断增加。我已经发布了下面的代码,虽然我确实初始化了更多的外围设备,但我还没有使用它们。

长HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* milliseconds=0){ HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);milliseconds++;}

代码语言:javascript
复制
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* Configure the system clock */
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_CAN_Init();
  MX_SPI1_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  stm32_uart2_set_state(1);
  HAL_TIM_Base_Start_IT(&htim2);
//  MX_WWDG_Init();
  /* USER CODE BEGIN 2 */
  char string[100]={0};
  int index=0; 
  /* Infinite loop */
  while (1)
  {
      uint32_t hall_tick=HAL_GetTick();
      sprintf(string,"It:%lu\tHt:%lu\n\r",milliseconds,hall_tick);
      stm32_uart2_send_string(string, strlen(string));
  }
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses 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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_TIM2_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 127; //prescaller is zero-based (0 means clk/1)
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 500;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
}

编辑:这是hal计数器的默认init函数,默认情况下中断优先级为15,我尝试将其设置为0,但结果是相同的。我测量了HAL_get_tick()和它的998 its的周期,而不是1ms。

代码语言:javascript
复制
    _weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  /* Configure the SysTick to have interrupt in 1ms time basis*/
  if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
  {
    return HAL_ERROR;
  }

  /* Configure the SysTick IRQ priority */
  if (TickPriority < (1UL << __NVIC_PRIO_BITS))
  {
    HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
    uwTickPrio = TickPriority;
  }
  else
  {
    return HAL_ERROR;
  }

  /* Return function status */
  return HAL_OK;

}

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-14 09:31:58

我认为您可能希望将您的TIM2周期设置为499。它是零基的,就像预定标器一样。从手册中:

在超数模式下,计数器计数从0到自动重新加载值( TIMx_ARR寄存器的内容),然后从0重新启动并生成计数器溢出事件。

您希望计数从0到499,然后重置为零。

这就解释了为什么你每毫秒就有2美元被淘汰。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74055617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档