На борту ESP32-C3 есть сигма-дельта модулятор второго порядка, который может генерировать независимые друг от друга импульсы PDM на нескольких каналах. Количество доступных каналов см. техническое руководство по используемому микроконтроллеру.
Обычно канал с ΔΣ-модуляцией можно использовать для следующих целей:
● Димминг LED (управление яркостью светодиодов). ● Простой ЦАП (DAC 8-bit), работающий месте с активным RC ФНЧ. ● Усилитель низкой частоты (УНЧ) класса D, построенный на основе полумоста и LC ФНЧ.
Блок сигма-дельта модуляции (SDM) есть во всех моделях кристаллов ESP32, и они управляются через API-функции драйвера одинаково, отличие только в количестве доступных каналов.
ESP32 SoC |
Количество каналов SigmaDelta |
ESP32 |
8 |
ESP32-S2 |
8 |
ESP32-C3 |
4 |
ESP32-S3 |
8 |
В последующих секциях (перевод документации [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. ● Получить соответствующую блокировку управления питанием (power management lock), если выбран конкретный источник синхросигнала (например, синхросигнал APB). Дополнительные сведения см. далее в разделе "Управление питанием".
Вызов 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. ● Пример, который управляет яркостью светодиодов через Sigma-Delta: peripherals/sigma_delta/sdm_led.
[API-функции драйвера Sigma-Delta модулятора]
Заголовочный файл API-функций: components/driver/include/driver/sdm.h.
Функция |
Описание |
sdm_new_channel |
Создание нового канала Sigma Delta. |
sdm_del_channel |
Удаление канала Sigma Delta. |
sdm_channel_enable |
Разрешение канала Sigma Delta. |
sdm_channel_disable |
Запрет канала Sigma Delta. |
sdm_channel_set_duty |
Установит скважность периода выходного сигнала PDM. |
Подробное описание параметров функций, структур, определений и констант см. в документации [1].
[Ссылки]
1. ESP32-C3 Sigma-Delta Modulation site:docs.espressif.com. 2. Дельта-сигма модуляция. 3. XPS Delta-Sigma ЦАП. 4. Что такое PWM (ШИМ)? 5. Sigma Delta Modulation LED Example site:github.com. 6. Sigma Delta Modulation DAC Example site:github.com. |