Программирование ARM ESP32: API-функции ESP-IDF управления ШИМ-контроллером LEDC Sun, October 06 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

ESP32: API-функции ESP-IDF управления ШИМ-контроллером LEDC Печать
Добавил(а) microsin   

Периферийное устройство контроллера LED (LEDC) было разработано для основной цели управления яркостью светодиодов LED, хотя его можно также использовать для генерации ШИМ-сигналов (PWM), предназначенных для других целей. Имеется 16 каналов, которые могут генерировать независимые формы сигналов, что может использоваться, к примеру, для управления светодиодными лентами RGB или генерации звука.

Каналы LEDC делятся на 2 группы по 8 каналов в каждой. Одна группа каналов LEDC работает в высокоскоростном режиме (high speed mode). Этот режим реализован аппаратно, и предоставляет автоматическое, без выбросов изменение скважности PWM. Другая группа каналов работает в низкоскоростном режиме (low speed mode), в этом режиме скважность PWM должна меняться программным драйвером. Каждая группа каналов также может также может использовать разные источники тактов.

Контроллер PWM может автоматически и постепенно увеличивать или уменьшать скважность PWM, что позволяет управлять освещением без программного вмешательства процессора.

Настройка канала LEDC в высокоскоростном или низкоскоростном режиме делается тремя шагами:

1. Конфигурируется таймер путем указания частоты сигнала PWM и разрешающей способности изменения его скважности.
2. Конфигурируется канал путем связывания его с таймером и ножкой GPIO для вывода сигнала PWM.
3. Изменение сигнала PWM, который управляет выходом, чтобы менять интенсивность свечения LED. Это может осуществляться либо по полным управлением со стороны программы, либо аппаратным фейдингом.

Как опциональный шаг также можно настроить прерывание по окончанию фейдинга.

settings LEDC API fig01

Рис. 1. Ключевые настройки контроллера LED PWM с помощью API-функций.

[Конфигурация таймера]

Настройка таймера осуществляется вызовом функции ledc_timer_config(), с передачей ей структуры данных ledc_timer_config_t, которая содержит следующие настройки конфигурации:

• ledc_mode_t: режим скорости.
• ledc_timer_t: номер таймера.
• Частота сигнала PWM.
• Разрешающая способность (разрядность) изменения скважности PWM.
• ledc_clk_cfg_t: частота источника тактов.

Частота и разрешающая способность взаимосвязаны. Чем выше частота PWM, тем меньшая разрешающая способность доступна, и наоборот. Эта взаимосвязь может быть важной, если Вы планируете использовать это API не для простого управления яркостью LED. Для дополнительной информации см. далее раздел "Поддерживаемые диапазоны частоты и разрешающей способности скважности".

Частота тактирования также ограничивает частоту PWM. Чем выше частота тактов, тем более высокая частота PWM может быть сконфигурирована.

Таблица 1. Характеристики источников тактирования ESP32 LEDC.

Мнемоника Частота тактов Режим скорости Возможности тактирования
APB_CLK 80 МГц High / Low  
REF_TICK 1 МГц Совместимо с динамическим масштабированием частоты (Dynamic Frequency Scaling).
RTC8M_CLK ~8 МГц Low Совместимо с Dynamic Frequency Scaling и режимом пониженного энергопотребления Light Sleep.

Примечание: на ESP32, если в качестве источника тактов LEDC выбран RTCxM_CLK, то для получения точной частоты тактов выполняется внутренняя калибровка. Это гарантирует точную частоту выходного сигнала PWM.

Конфигурация канала. Когда настраивается таймер, конфигурируется желаемый канал (один из ledc_channel_t). Это делается функцией ledc_channel_config().

Подобно конфигурации таймера, функции настройки канала должна быть передана структура ledc_channel_config_t, которая содержит параметры конфигурации канала.

В этом месте канал должен начать работать, генерируя сигнал PWM на выбранной ножке GPIO, как это было сконфигурировано в ledc_channel_config_t, на частоте, указанной в настройках таймера, и с заданной скважностью. Работа канала (генерация сигнала) может быть приостановлена в любой момент вызовом функции ledc_stop().

[Изменение сигнала PWM]

Как только канал начнет работать и генерировать сигнал PWM с постоянной скважностью, есть несколько способов поменять этот сигнал. Когда осуществляется управление LED, меняется главным образом яркость свечения.

В следующих двух секциях описывается, как менять скважность с помощью аппаратного и программного фейдинга. Если необходимо, также можно поменять частоту сигнала, это рассматривается в секции "Изменение частоты PWM".

Изменение скважности программно. Для установки скважности периода PWM используйте специальную функцию ledc_set_duty(). После этого вызовите ledc_update_duty() для активации изменений. Для проверки текущего установленного значения скважности используйте соответствующую функцию ledc_get_duty().

Другой способ установки скважности, как и некоторых других параметров, это вызов ledc_channel_config(), см. выше секцию "Конфигурация канала".

Диапазон передаваемых значений для изменения скважности зависит от выбранной разрешающей способности (duty_resolution), и значение должно быть от 0 до (2duty_resolution) - 1. Например, если выбранная разрешающая способность 10 (duty_resolution=10), то скважность может быть в диапазоне от 0 до 1023. Это дает точность установки уровня примерно 0.1%.

Изменение скважности аппаратно. Аппаратура LEDC обеспечивает способ плавного изменения скважности от одного значения к другому. Для использования этой возможности разрешите фейдинг функцией ledc_fade_func_install(), и затем сконфигурируйте её вызовом одной из следующих доступных функций фейдинга:

ledc_set_fade_with_time()
ledc_set_fade_with_step()
ledc_set_fade()

Фейдинг начинается вызовом ledc_fade_start(). Фейдинг может работать в режиме блокирования или без блокирования, см. ledc_fade_mode_t для двух различных отличающихся режимов фейдинга. Обратите внимание, что в любом из этих двух режимов следующий фейдинг или обновление на фиксированную скважность не даст эффект, пока не завершится последний процесс фейдинга. Из-за аппаратных ограничений нет способа остановить фейдинг до момента достижения им целевой скважности.

Для получения оповещения о завершении операции фейдинга может быть зарегистрирована соответствующая callback-функция путем вызова ledc_cb_register() после того, как была установлена служба фейдинга.

Если больше не требуется фейдинг и связанное с ним прерывание, то фейдинг может быть запрещен вызовом ledc_fade_func_uninstall().

Изменение частоты PWM. LEDC API предоставляет несколько способов поменять частоту PWM "на лету":

• Установка частоты вызовом ledc_set_freq(). Имеется комплементарная функция ledc_get_freq() для проверки текущей частоты.
• Изменение частоты и разрешающей способности для скважности вызовом ledc_bind_channel_timer(), чтобы привязать к каналу какой-нибудь другой таймер.
• Изменение таймера канала вызовом ledc_channel_config().

Дополнительное управление функцией PWM. Существует несколько функций таймера, реализующих управление на более низком уровне, которые можно использовать для изменения настроек PWM:

ledc_timer_set()
ledc_timer_rst()
ledc_timer_pause()
ledc_timer_resume()

Две первые из них вызываются "закулисно" функцией ledc_channel_config(), чтобы обеспечить запуск таймера после того, как он сконфигурирован.

Использование прерываний. Когда конфигурируется канал LEDC, одним из параметров ledc_channel_config_t является ledc_intr_type_t. Это обработчик прерывания, который запускается, когда завершается фейдинг PWM.

Для регистрации обработчика этого прерывания вызовите ledc_isr_register().

Высокоскоростной и низкоскоростной режимы. Высокоскоростной режим LEDC позволяет реализовать переключение настроек таймера без выбросов и сбоев. Это означает, что если настройки таймера были изменены, то они вступят в действие автоматически на следующем прерывании переполнения таймера. Если сравнить с низкоскоростным режимом, когда применяется низкоскоростной таймер, изменение настроек должно быть явно инициировано программой. Драйвер LEDC осуществляет это в фоновом режиме, т. е. когда вызывается ledc_timer_config() или ledc_timer_set().

Дополнительную информацию по скоростным режимам см. документацию ESP32 Technical Reference Manual -> LED PWM Controller (LEDC) [PDF].

[Поддерживаемые диапазоны частоты и разрешающей способности скважности]

Контроллер LED PWM (LEDC) изначально был разработан для управления светодиодами (LED). Он предоставляет для этого большую гибкость для настройки периода и скважности PWM. Например, при частоте PWM 5 кГц можно получить максимальную разрешающую способность скважности 13 бит. Это значит, что скважность можно менять в диапазоне от 0 до 100% шагами по ~0.012% (2 ^ 13 = 8192 дискретных уровней интенсивности свечения LED). Однако следует заметить, что эти параметры зависят от частоты тактов таймера, вырабатывающего такты для контроллера LED PWM, который в свою очередь тактирует канал (см. описание конфигурации таймера в документе ESP32 Technical Reference Manual -> LED PWM Controller (LEDC) [PDF]).

LEDC может использоваться для генерации сигналов и с намного большей частотой, достаточной для тактирования других устройств, например модуля цифровой камеры. В этом случае максимально возможная частота составит 40 МГц при разрешающей способности 1 бит. это значит, что скважность может быть в этом случае только фиксированной на 50%, и не может быть изменена.

Разработанное LEDC API сообщает об ошибке, когда делается попытка установить частоту и скважность, превышающие возможный диапазон аппаратуры LEDC. Например, попытка установить частоту 20 МГц и разрешающую способность 3 бита приведут к следующей ошибке, о которой сообщит serial monitor:

E (196) ledc: requested frequency and duty resolution cannot be achieved, try reducing freq_hz
 or duty_resolution. div_param=128

В такой ситуации нужно уменьшить либо разрядность (т. е. разрешающую способность) скважности, либо уменьшить частоту PWM. Например, установка разрешающей способности изменения скважности 2 устранит эту проблему, и скважность периода ШИМ можно будет менять 4 градациями, с шагом 25%.

Драйвер LEDC будет также перехватывать попытки конфигурирования комбинаций частота / разрядность, которые ниже поддерживаемого минимума, и сообщать о таких попытках, например:

E (196) ledc: requested frequency and duty resolution cannot be achieved, try increasing freq_hz
 or duty_resolution. div_param=128000000

Разрешающая способность скважности обычно устанавливается с помощью ledc_timer_bit_t. Это перечисление, перекрывающее диапазон от 10 до 15 бит. Если нужна меньшая разрешающая способность (1 .. 10 бит), введите напрямую нужное числовое значение.

Пример приложения, где осуществляется управление скважностью с функцией фейдинга, см. в каталоге peripherals/ledc/ledc_fade среди примеров среды разработки ESP-IDF [2]. Базовый пример LEDC см. в peripherals/ledc/ledc_basic.

[Справочник по API LEDC]

Заголовочный файл для API-функций драйвера LEDC: components/driver/include/driver/ledc.h. Используемые драйвером типы данных описаны в заголовке components/hal/include/hal/ledc_types.h.

Функция Описание
ledc_channel_config Конфигурирует канал LEDC для определенного канала, ножки выхода GPIO, прерывания, таймера, частоты PWM в Гц и разрешающей способности скважности.
ledc_timer_config Конфигурирует таймер LEDC с указанием частоты PWM в Гц и разрешающей способности скважности.
ledc_update_duty Обновляет параметры канала таймера, вызовите эту функцию, чтобы активировать обновленные параметры LEDC. После вызова ledc_set_duty, нам нужно вызвать эту функцию, чтобы вступили в действие измененные настройки. И новые параметры LEDC не вступят в силу до момента следующего цикла PWM(1).
ledc_set_pin Установит ножку выхода GPIO. Эта функция только направляет сигнал LEDC на ножку GPIO через матрицу, другие инициализации ресурсов LEDC не производятся. Вместо этой функции используйте ledc_channel_config() для выполнения полной конфигурации канала LEDC.
ledc_stop Останавливает LEDC. Выход LEDC запрещается, и устанавливается в уровень ожидания (idle level).
ledc_set_freq Установит частоту PWM канала LEDC в Гц.
ledc_get_freq Считывает текущую установленную частоту PWM канала LEDC в Гц.
ledc_set_duty_with_hpoint Установит скважность и верхнее значение изменения скважности (hpoint) LEDC. Скважность обновится только после вызова ledc_update_duty(1, 2).
ledc_get_hpoint Считывает значение hpoint, значение счетчика, когда выход устанавливается в уровень лог. 1.
ledc_set_duty Установка скважности канала LEDC. Эта функция не поменяет значение hpoint для этого канала. Если это необходимо, то вызовите ledc_set_duty_with_hpoint. Скважность обновится только после вызова ledc_update_duty(1, 2).
ledc_get_duty Вернет скважность канала LED на текущем периоде PWM. Не следует ожидать, что функция вернет новую скважность на том же цикле, когда произошел вызов ledc_update_duty, потому что обновление скважности произойдет на следующем периоде PWM.
ledc_set_fade Установит градиент канала LEDC (т. е. скорость, направление и другие параметры автоматического фейдинга). Настройки этой функции вступят в силу после вызова ledc_update_duty(2).
ledc_isr_register Регистрирует обработчик прерывания (ISR) для LEDC. Этот обработчик будет подключен к тому же ядру CPU, на котором выполнялась эта функция.
ledc_timer_set Конфигурирует настройки таймера LEDC.
ledc_timer_rst Сбросит таймер LEDC.
ledc_timer_pause Приостановит таймер LEDC.
ledc_timer_resume Возобновит работу таймера LEDC.
ledc_bind_channel_timer Привязывает канал LEDC к выбранному таймеру.
ledc_set_fade_with_step Установит функцию фейдинга LEDC. Перед вызовом этой функции вызовите один раз ledc_fade_func_install(). После этого для запуска фейдинга вызовите ledc_fade_start()(1, 2).
ledc_set_fade_with_time Установит на ограниченное время функцию фейдинга LEDC. Перед вызовом этой функции вызовите один раз ledc_fade_func_install(). После этого для запуска фейдинга вызовите ledc_fade_start()(1, 2).
ledc_fade_func_install Инсталлирует функцию фейдинга LEDC. Эта функция займет прерывание модуля LEDC.
ledc_fade_func_uninstall Деинсталлирует функцию фейдинга LEDC.
ledc_fade_start Запустит фейдинг LEDC(2). Перед вызовом этой функции вызовите один раз ledc_fade_func_install(). Перед запуском фейдинга вызовите ledc_fade_start сразу после вызова ledc_set_fade_with_time или ledc_set_fade_with_step. Запуск операции фейдинга не будет потокобезопасным, поэтому используйте ledc_fade_start с осторожностью.
ledc_set_duty_and_update Потокобезопасная API-функция для установки скважности канала LEDC и возврата, когда скважность была обновлена(2).
ledc_set_fade_time_and_start Потокобезопасная API-функция для установки и старта фейдинга, с ограниченным временем(2). Перед вызовом этой функции требуется однократный вызов ledc_fade_func_install().
ledc_set_fade_step_and_start Потокобезопасная API-функция для установки и старта фейдинга (2). Перед вызовом этой функции требуется однократный вызов ledc_fade_func_install().
ledc_cb_register Регистрирует функцию обратного вызова (callback) LEDC. Callback-функция вызывается из ISR, она не должна никогда пытаться делать блокировку, и все вызываемые из неё API-функции FreeRTOS должны быть ISR-версиями.

Примечания:

(1) Функции ledc_set_duty, ledc_set_duty_with_hpoint и ledc_update_duty не являются потокобезопасными (not thread-safe), поэтому не вызывайте эти функции для управления одним и тем же каналом LEDC одновременно из разных задач RTOS. Потокобезопасная версия это ledc_set_duty_and_update.
(2) Для ESP32 аппаратура не поддерживает любое изменение скважности, пока происходит операция фейдинга (процесс автоматического изменения скважности) на этом канале. Другие операции по управлению скважности должны подождать момента завершения операции фейдинга.

Подробное описание функций, перечислений, типов данных, определений драйвера LEDC см. в документации [1].

[Ссылки]

1. ESP32 LED Control (LEDC) site:docs.espressif.com.
2. Установка среды разработки ESP-IDF для ESP32.
3ESP32 High Resolution Timer.

 

Добавить комментарий


Защитный код
Обновить

Top of Page