ESP32-C3: сигма-дельта модуляция |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||
На борту ESP32-C3 есть сигма-дельта модулятор второго порядка, который может генерировать независимые друг от друга импульсы PDM на нескольких каналах. Количество доступных каналов см. техническое руководство по используемому микроконтроллеру. Обычно канал с ΔΣ-модуляцией можно использовать для следующих целей: ● Димминг LED (управление яркостью светодиодов). Блок сигма-дельта модуляции (SDM) есть во всех моделях кристаллов ESP32, и они управляются через API-функции драйвера одинаково, отличие только в количестве доступных каналов.
В последующих секциях (перевод документации [1]) будут рассмотрены следующие шаги по настройке и запуску канала SDM (Sigma-Delta Modulation): Выделение ресурсов - какие параметры должны быть подготовлены, чтобы получить дескриптор канала (channel handle), и как восстановить эти ресурсы после того, как завершена работа с каналом. Разрешение и запрет канала - как запустить и остановить генерацию сигнала PDM (Pulse-Density Modulation). Установка эквивалентной скважности - описывается, как устанавливается equivalent duty cycle импульсов PDM. Управление питанием (Power Management) - как выбор различных источников тактирования может повлиять на энергопотребление. IRAM Safe - перечислены функции, которые должны работать даже когда кэш запрещен. Thread Safety - перечислены API-функции, которые гарантируют для драйвера безопасные вызовы из разных потоков. Опции Kconfig - перечислены опции, поддерживаемые системой конфигурации проекта (idf.py menuconfig), которые по-разному влияют на поведение драйвера. Выделение ресурсов. Канал SDM представлен структурой sdm_channel_handle_t. Каждый канал может выводить двоичный, аппаратно генерируемый сигнал ΔΣ-модуляции. Драйвер управляет всеми доступными каналы в пуле, так что пользователю не надо заботиться о назначении фиксированного канала на GPIO. Для инсталляции канала SDM нужно вызвать sdm_new_channel() для получения дескриптора канала (channel handle). Специфичные для канала параметры конфигурации передаются в структуру sdm_config_t: sdm_config_t::gpio_num установит порт GPIO на котором будут формироваться импульсы PDM. sdm_config_t::clk_src выбирает источник тактирования для модуля SDM. Имейте в виду, что на всех каналах должен быть выбран один и тот же источник тактирования. sdm_config_t::sample_rate_hz установит частоту выборок (sample rate) модуля SDM. sdm_config_t::invert_out установит инверсию выходного сигнала. sdm_config_t::io_loop_back предназначается только для отладки. Это разрешит функционал ввода и вывода GPIO через матрицу периферийных устройств (GPIO matrix peripheral). Функция sdm_new_channel() может потерпеть неудачу из-за различных ошибок, таких как недостаток памяти, ошибки в аргументах и т. п. Особенно когда свободных каналов больше нет (например все аппаратные каналы SDM уже используются), тогда будет возвращен код ошибки. Если ранее созданный канал SDM больше не нужен, то его (и связанные с ним ресурсы) надо освободить вызовом sdm_del_channel(). Это позволит использовать аппаратуру нижнего уровня для других целей. Перед удалением дескриптора канала SDM (channel handle) нужно его запретить вызовом sdm_channel_disable(), либо надо гарантировать, что он не был (и не будет) разрешен вызовом sdm_channel_enable(). Пример создания канала SDM с частотой дискретизации 1 МГц: sdm_channel_handle_t chan = NULL; sdm_config_t config = { .clk_src = SDM_CLK_SRC_DEFAULT, .sample_rate_hz = 1 * 1000 * 1000, .gpio_num = 0, }; ESP_ERROR_CHECK(sdm_new_channel(&config, &chan)); Разрешение и запрет канала. Чтобы в будущем управлять выводом в канал SDM его нужно сначала разрешить вызовом sdm_channel_enable(). Внутри этой функции выполняется следующее: ● Переключить состояние канала из init в enable. Вызов sdm_channel_disable() делает обратное, т. е. переводит канал обратно в начальное состояние (init state) и освобождает его блокировку по управлению питанием (power management lock). Установка эквивалентной скважности. Известно, что сигнал ΔΣ не имеет фиксированной частоты импульсов. Это сделано специально, чтобы уменьшить частоту переключения силовых ключей и соответственно снизить потери мощности [2]. Поэтому для сигналов ΔΣ существует такое понятие, как эквивалентная скважность. PDM скважность периода (duty cycle) относится к процентному соотношению периодов высокого уровня к среднестатистическому периоду сигнала. Среднее выходное напряжение, генерируемое каналом, вычисляется по формуле Vout = VDD_IO / 256 * duty + VDD_IO / 2. Таким образом, диапазон входного параметра скважности функции sdm_channel_set_duty() будет в диапазоне от -128 до 127 (8-битное целое число со знаком). Например, если установлено значение 0, то скважность выходного сигнала составит около 50%. Управление питанием (Power Management). Когда разрешено управление питанием (например включена опция CONFIG_PM_ENABLE), система будет подстраивать частоту APB (сокращение от Advanced Peripherial Bus) перед переходом в режим пониженного энергопотребления light sleep, что потенциально поменяет частоту выборок (sample rate) ΔΣ-модулятора. Однако драйвер может предотвращать изменение системой частоты APB получением блокировки управления питанием (power management lock) типа ESP_PM_APB_FREQ_MAX. Всякий раз, когда драйвер создает экземпляр канала SDM, у которого выбран источник тактов SDM_CLK_SRC_APB, драйвер будет гарантировать, что при вызове sdm_channel_enable() для разрешения канала захватывается соответствующая блокировка управления питанием. Соответственно драйвер освободит эту блокировку, когда для этого канала будет вызвана функция sdm_channel_disable(). IRAM Safe. Существует Kconfig-опция CONFIG_SDM_CTRL_FUNC_IN_IRAM, которая переведет часто используемые функции управления ввода/вывода в область ОЗУ (IRAM). Таким образом, эти функции могут выполняться также когда кэш запрещен. К таким функциям управления относится sdm_channel_set_duty(). Thread Safety. Заводская функция sdm_new_channel() гарантирована драйвером для безопасного вызова из потока (thread safe). Это означает, что пользователь может вызвать эту функцию из различных потоков (RTOS tasks) без дополнительных защитных блокировок. Также функцию sdm_channel_set_duty() можно безопасно вызывать из контекста прерывания (код ISR), для этого драйвер использует критическую секцию для предотвращения ситуации, когда эта функция одновременно вызвана и из основного кода (т. е. обычного потока), и из ISR. Другие функции, которые принимают в качестве первого параметра дескриптор канала sdm_channel_handle_t, не являются потокобезопасными (not thread safe). Это означает, что пользователь должен избегать вызывать их из нескольких потоков. Опции Kconfig. Предусмотрены следующие опции, которые можно менять в утилитой idf.py menuconfig: CONFIG_SDM_CTRL_FUNC_IN_IRAM управляет тем, куда будут помещены функции управления каналом SDM (IRAM или Flash, см. выше IRAM Safe). CONFIG_SDM_ENABLE_DEBUG_LOG используется для разрешения вывода в лог отладки. Разрешение этой опции увеличит размер двоичного кода firmware приложения. [Преобразование PDM в аналоговую форму] Обычно если ΔΣ-сигнал подключен к LED, то не нужен никакой фильтр между ними (потому что наши глаза не замечают быстрых мерцаний, и работают как усредняющий ФНЧ). Однако если вы хотите сформировать реальный аналоговый сигнал (например для использования в лабораторном блоке питания, или для вывода звукового сигнала), то может понадобиться разработать фильтр низкой частоты (ФНЧ), пассивный или активный. Активный фильтр обеспечивает лучшую фильтрацию полезного сигнала и может обеспечить больший выходной уровень сигнала. В качестве примера ниже показана схема ФНЧ с топологией Sallen-Key. Примеры приложений см. в каталоге peripherals/sigma_delta среди других примеров кода в ESP-IDF (также см. репозиторий GitHub [5, 6]). ● Синусоидальный сигнал 100 Гц, модулированный Sigma-Delta: peripherals/sigma_delta/sdm_dac. [API-функции драйвера Sigma-Delta модулятора] Заголовочный файл API-функций: components/driver/include/driver/sdm.h.
Подробное описание параметров функций, структур, определений и констант см. в документации [1]. [Ссылки] 1. ESP32-C3 Sigma-Delta Modulation site:docs.espressif.com. |