Top.Mail.Ru
Уведомления
Очистить все

Настройка предделителя и периода таймера в STM32.

(@alexandr)
New member

Всех приветствую. Недавно начал знакомиться с микроконтроллерами STM32, сейчас тестирую разную периферию с помощью платы Blue Pill с микроконтроллером STM32F103CBT6. Дошел до таймеров и никак не могу разобраться со значениями предделителей и периодов...

Нашел в интернете пример, значения такие:

/* TIM2 init function */
void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 7999;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 1000;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  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();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}

Предделитель равен 7999, период равен 1000. Получаю прерывание по переполнению таймера каждые 1000 мс (то есть секунду). Проверяю это значение через функцию HAL_GetTick(), которая возвращает значение в миллисекундах.

Первый вопрос - как из этих значений получается 1 с? И если несложно, то приведите пожалуйста пример, какие должны быть значения например для периода в 2.5 мс...

Забыл написать про тактирование. Как я понял таймер у меня работает от 8 МГц.

Цитата
Создатель темы Размещено : 30.03.2025 10:22
Метки темы
(@eduard)
Level 5 Moderator

https://microtechnics.ru/profilegrid_blogs/tajmery-s-tochki-zreniya-zhelezyachnika/#more-22041

Здесь посмотрите. Как раз рассказано, как вести расчёты.

И начните с тактирования. От этого многое зависит. И там есть где запутаться. Желательно сначала понять какая периферия как тактируется.

 

https://microtechnics.ru/profilegrid_blogs/chast-15-stm32-i-s-bazovye-tajmery-tim6-i-tim7/#more-17872

Здесь немного о тактировании. В начале статьи. Что откуда берётся

ОтветитьЦитата
Размещено : 30.03.2025 11:28
Aveal
(@aveal)
Top level Admin

Запись от: @alexandr

Предделитель равен 7999, период равен 1000. Получаю прерывание по переполнению таймера каждые 1000 мс (то есть секунду).

Забыл написать про тактирование. Как я понял таймер у меня работает от 8 МГц.

Отправная точка - частота тактирования таймера, 8 МГц.

Эта частота делится на значение, которое получается прибавлением единицы к значению предделителя в регистрах контроллера, в данном случае частота делится на число (7999 + 1) = 8000. Итоговая частота, на которой работает таймер = 8 МГц / 8000 = 8000000 Гц / 8000 = 1000 Гц.

Исходя из полученной частоты, один отсчет таймера соответствует периоду, равному: 1 с / 1000 Гц = 1 мс. То есть за 1 мс таймер увеличивает значение своего счетного регистра на единицу.

Прерывание по переполнению срабатывает в тот момент, когда таймер "досчитает" до значения периода, значит прерывание сработает каждые: 1 мс * 1000 = 1000 мс = 1 с.

Теперь для случая с 2.5 мс: изменяем значение предделителя допустим на 399. Производим расчет в точности по тем же шагам:

  • частота, на которой работает таймер: 8 МГц / (399+ 1) = 20000 Гц.
  • один отсчет таймера: 1 с / 20000 Гц = 0.05 мс.
  • для того, чтобы прерывания срабатывало каждые 2.5 мс, период *в настройках таймера) должен составлять 50 (0.05 мс * 50 = 2.5 мс).

 

ОтветитьЦитата
Размещено : 31.03.2025 11:43
Поделиться: