середу, 16 березня 2016 р.

Таймери STM32 -- автоматична зупинка/HAL

Аналогічно до відповідного CMSIS-поста, беремо проект, котрий генерує ШІМ, збільшуємо період до видимого оком значення -- нам потрібен один імпульс заданої тривалості, а не власне ШІМ та кажемо зупинятися після переповнення.

Для цього на вкладці pinout слід поставити одну "пташку" -- One Pulse Mode:


Потім, в Configure, налаштовуємо період і тривалість імпульсу:



Подільник, рівний 24000 (для цього в регістр PSC записується 24000-1) приводить до зміни лічильника кожну мілісекунду, тому період 5000, із довжиною імпульсу 3000 та високим рівнем активного сигналу, в режимі PWM2 означатиме -- 5000-3000 = 2000 мс = 2 секунди після активації на піні буде логічний нуль (що можна буде побачити, наприклад, по тому, що світлодіод не світитиметься), потім 3000 мс = 3 секунди -- логічна одиничка, (світлодіод ввімкнеться).

Код в main() буде простим (показано лише релевантний -- типові ініціалізації опущено):

  MX_TIM3_Init();

  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
  while (1)
  {
   HAL_Delay(10000);
   __HAL_TIM_ENABLE(&htim3);
  }

Всі елементи його ми вже розглядали раніше.

Ініціалізація

Традиційно, подивимося, як виглядатиме MX_TIM3_Init():

void MX_TIM3_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 23999;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 5000;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_Base_Init(&htim3);

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);

  HAL_TIM_PWM_Init(&htim3);

  HAL_TIM_OnePulse_Init(&htim3, TIM_OPMODE_SINGLE);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);

  sConfigOC.OCMode = TIM_OCMODE_PWM2;
  sConfigOC.Pulse = 3000;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);

}

Вона схожа на розглянуту раніше, основна відмінність (крім періоду і тривалості імпульсу -- задача інша) -- виклик HAL_TIM_OnePulse_Init() із аргументом TIM_OPMODE_SINGLE. Сама ця функція призначена для конфігурації "повноцінного" One Pulse Mode, про який ми поговоримо окремо, тому зараз не розглядатимемо, зауважу тільки, що вона, поміж іншого, робить наступне:

/* Reset the OPM Bit */
  htim->Instance->CR1 &= ~TIM_CR1_OPM;

  /* Configure the OPM Mode */
  htim->Instance->CR1 |= OnePulseMode;


Якраз те, що нам потрібно.


Скачати проект із кодом для цього та двох попередніх постів ("Таймери STM32 -- зовнішнє тактування/HAL", "Таймери STM32 -- внутрішні тригери/HAL"), можна тут.

2 коментарі: