Аналогічно до відповідного CMSIS-поста, беремо проект, котрий генерує ШІМ, збільшуємо період до видимого оком значення -- нам потрібен один імпульс заданої тривалості, а не власне ШІМ та кажемо зупинятися після переповнення.
Для цього на вкладці pinout слід поставити одну "пташку" -- One Pulse Mode:
Подільник, рівний 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); }
Всі елементи його ми вже розглядали раніше.
Вона схожа на розглянуту раніше, основна відмінність (крім періоду і тривалості імпульсу -- задача інша) -- виклик HAL_TIM_OnePulse_Init() із аргументом TIM_OPMODE_SINGLE. Сама ця функція призначена для конфігурації "повноцінного" One Pulse Mode, про який ми поговоримо окремо, тому зараз не розглядатимемо, зауважу тільки, що вона, поміж іншого, робить наступне:
Якраз те, що нам потрібно.
Скачати проект із кодом для цього та двох попередніх постів ("Таймери STM32 -- зовнішнє тактування/HAL", "Таймери STM32 -- внутрішні тригери/HAL"), можна тут.
Ініціалізація
Традиційно, подивимося, як виглядатиме 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"), можна тут.
-Подякував, стався у нагоді ваш пост)
ВідповістиВидалитиДмитро Львів
Радий, що стало у пригоді! :-)
Видалити