Таймеры - ШИМ
Работа с широтно-импульсной модуляцией
Last updated
Работа с широтно-импульсной модуляцией
Last updated
Хоть нам и удалось в прошлом разделе сделать "мигание по синусоиде", оно было прерывистым и не очень красивым. Хотелось бы добиться плавного изменения яркости, без заметного для глаза мерцания. В этом нам поможет ШИМ - широтно-импульсная модуляция (PWM - pulse-width modulation).
В прошлом упражнении мы уже видели, что у таймера есть период - значения, достигая которого он сбрасывается. Таким образом, можно говорить о частоте таймера, с этой частотой у нас вызывались прерывания и эта же частота будет использоваться для ШИМ.
ШИМ нужна для генерации сигналов, переключающихся между двумя значениями (условно, 0 и 1) с постоянной частотой:
Видно, что частота ("время" от начала одного сигнала до следующего) постоянно - эта та же частота, что была и у прерывания и задается с помощью Counter Period. Duty cycly, или коэффициент заполнения, отмеченный на графике, управляется с помощью второго счетчика - pulse, по достижении которого сигнал переходит в состояние 0.
Представим, что counter period у нас 20. Тогда для получения таких сигналов, как на рисунке, нам нужно выставить pulse:
10
15
5
Если частота ШИМ достаточно велика (тысячи КГц), то держа таким образом светодиод во включенном состоянии 50/75/25 процентов времени, мы получим стабильную яркость в 50/75/25 или любой другой процент от максимальной. Переключения с такой частотой будут не различимы для глаза.
Аналогичным образом можно управлять, например, скоростью DC-мотора
Выберем ножку диода PA5
, и назначим ей режим TIM2_CH1
- это означает, что для нее мы будем использовать первый канал генерации PWM из второго таймера (дальше станет понятнее, что имеется ввиду).
Теперь необходимо настроить TIM2
:
С Clock Source, Prescaler и Counter Period мы уже разбирались. Тут важны следующие новые настройки:
Channel1 - PWM Generation CH1
- указывает, что на первом канале таймера (который мы как раз привязали к светодиоду) нужно генерировать ШИМ
PWM Generation Channel 1 - Pulse - 10
- значение, контролирующее коэффициент заполнения сигнала. При pulse == 10
и period == 500
, заполнение равно 2%
Очевидно, что чтобы менять яркость светодиода, необходимо просто менять значение pulse по синусоиде - при prescaler 16, частота таймера получилась равной 10 МГц, и с периодом 500 - частота ШИМ 20 КГц. С такой частотой, при управлении яркостью через pulse никакого мерцания заметно не будет, и можно рассматривать коэффициент заполнения просто как процент от максимальной яркости.
В таком случае, все что нам осталось сделать, это запустить ШИМ и в цикле устанавливать pulse как синус от какого-то X. Тут удобно привести большой кусок кода из main
, в котором содержится вся эта логика:
Залив этот код на контроллер, мы увидим, как светодиод плавно меняет яркость, без заметного мерцания.