Техника широтно-импульсной модуляции, ШИМ (Pulse Width Modulation, PWM) широко используется для преобразования цифрового потока аудиоданных в звуковой сигнал, поскольку это очень простой метод для реализации. Множество недорогих микроконтроллеров (MCU) имеют на борту контроллеры PWM как общепринятый стандарт, и многие инженеры используют его для разных целей. В этой статье представлен вариант вывода 16-битного PWM с использованием автокалибровки с целью повышения точности.
[PWM в микроконтроллере]
Контроллер PWM, встроенный в MCU, реализован как таймер или счетчик. С каждым тактом этот счетчик инкрементируется, и сбрасывается в 0 при достижении определенного значения, которое конфигурируется. Это значение определяет период PWM. При каждом инкременте счетчика он сравнивается с другим программируемым значением, и при совпадении это служит сигналом к изменению уровня на выходе. Если значение счетчика меньше, чем это запрограммированное значение, то на выходе лог. 1, а если больше, то лог. 0.
В результате на выходе появляются импульсы с частотой периода PWM, у которых соотношение длительностей лог. 1 и лог. 0 зависят от запрограммированной величины сравнения, для простоты назовем её значением PWM. Значение PWM может регулярно обновляться аудиоданными. В результате, если выходной сигнал пропустить через фильтр низкой частоты (ФНЧ), то будет сформирован аналоговый звуковой сигнал. Этот ФНЧ нужен, чтобы вырезать компонент частоты PWM (эта частота обратна периоду PWM). Такая фильтрация становится возможной, потому что частота PWM обычно намного превышает частоту полезного аудиосигнала. На блок-схеме ниже представлена типовая реализация модуля PWM микроконтроллера.
Рис. 1. Модуль PWM, реализованный как периферийное устройство MCU.
Частота тактов, поступающих на счетчик, конфигурируется несколькими способами, зависящими от архитектуры MCU. Например, основная частота тактов системы, стабилизированная кварцевым резонатором, поступает на программируемый делитель частоты (прескалер), и с выхода прескалера частота тактов подается на вход счетчика PWM. Значение сброса/перезагрузки счетчика также программируется, и оно определяет период PWM.
Разрешающая способность, на которую накладывается ограничение по скорости. Очевидно, что период PWM ограничивает разрешающую способность (разрядность) PWM. Другими словами, чем большую разрешающую способность PWM мы хотим получить, тем меньше возможностей по увеличению частоты PWM, и наоборот - чем больше должна быть частота PWM, тем меньше возможностей по управлению периодом PWM. Для примера возьмем MCU STM32F103. У него есть 16-разрядный счетчик с возможностью генерации PWM, и мы можем сконфигурировать максимальную частоту тактов для счетчика 72 МГц. С этой частотой будет инкрементироваться счетчик PWM. Если мы захотим получить 10-битную разрешающую способность, то для периода PWM мы можем запрограммировать 1024 в качестве значения для автоматического сброса/перезагрузки счетчика. Таким образом, мы получим частоту PWM (72000000/1024) Гц, или 70.312 кГц.
Мы можем увеличить разрешающую способность до 11 бит, и получим частоту PWM 35.156 кГц. Дальнейшее увеличение разрядности PWM приведет к недопустимо низкой скорости, т. е. низкой частое PWM. Поскольку частота PWM влияет на качество звука, то она должна быть как можно выше, чем частота, с которой оцифрован звук (частота выборок звука, samplerate). Иногда допустима передаваемая полоса частот около 15 кГц (половина частоты PWM) с 11-битной разрешающей способностью. Однако такое низкое качество недопустимо для профессионального стандарта воспроизведения или записи звука.
[Два 8-битных PWM для формирования 16-битного Audio PWM]
Чтобы преодолеть аппаратные ограничения по на частоту PWM и разрешающую способность, мы можем использовать 2 модуля PWM. Если запрограммировать каждый из них на разрешающую способность 8 бит, и использовать параллельно для вывода звука, то можно получить звук 16-битного качества на повышенной частоте. Чтобы это работало, старший байт выборки звука нужно посылать в один 8-битный блок PWM, а младший в другой. Выходные сигналы 8-битных PWM будут поступать в сумматор, реализованный на двух резисторах.
Рис. 2. Параллельная работа двух 8-битных блоков PWM.
Сумматор должен содержать в своем составе резисторы, которые соотношение номиналов которых должны давать смешивание выходов PWM с коэффициентом 1/256. Этот способ формирования аудиосигнала описан в апноуте AN3143 [2].
Рис. 3. Сумматор на резисторах.
[Автокалибровка выхода]
Система двойного PWM, показанная на рис. 2 и 3, очень простая, однако подстройка веса вывода младшего байта PWM на сумматор требует применения очень точных значений резисторов R1 и R2. Во-первых, их соотношение должно обеспечивать точную пропорцию 1:256 смешивания сигналов PWM. Во-вторых, мы просто не сможем найти один резистор такой точной величины. И наконец, даже если такой нужный номинал резистора существует, у него всегда будет вариация номинала в пределах установленного заводом допуска.
Примечание: на самом деле проблема подбора соотношения резисторов легко решается, если один резистор в сумматоре составить из двух параллельно (или последовательно) соединенных резистора, значения которых отличаются на один порядок.
Чтобы обеспечить калибровку в коде программы, был намеренно выбран резистор канала младшего байта (220k). MCU использует напряжение питания 3.3V и такой же уровень опорного напряжения ADC. Схема усилителя и фильтра выполнена на операционном усилителе LM324, она питается от напряжения 5V. Уровень на выходе операционного усилителя может меняться от почти нулевого до уровня примерно на 1.5V ниже напряжения питания.
Рис. 4. Схема сумматора сигналов PWM с ФНЧ и автокалибровкой.
Калибровка 16-bit Audio PWM. Калибровка сумматора подразумевает, что на канала младшего байта PWM от значения 0x00 к значению 0xFF должно приводить к такому же уровню на выходе, что и инкремент на 1 значения канала PWM старшего байта. С применением 12-битной разрешающей способности ADC выбранное усиление 16x должно быть адекватным. Усилитель U4 преобразует младшие 12 комбинированного PWM в полный диапазон уровней преобразования ADC. Это позволяет выполнить калибровку путем подстройки младшего байта PWM.
При значении выше 0x0fff уровень на выходе U4 должен быть выше 3.3V. Номинал резистора R7 достаточен, чтобы ограничить выходной ток операционного усилителя. По этой причине калибровка работает только для вывода диапазона уровней от 0x0000 до 0x0fff. На схеме рис. 4 не показаны напряжения питания усилителя. В частности +VCC должно быть 5V и -VCC должно быть уровня не выше -2V.
Несоответствие усиления для младшего канала PWM может привести к ошибкам типа "пропущен шаг" или "лишний шаг". Для иллюстрации см. рис. 5, где показаны варианты ошибок (для упрощения на иллюстрациях показано преобразование 8 уровнями, т. е. 3-разрядное). Когда значение резистора R2 недостаточно велико, то происходят ошибки типа "лишний шаг" (рис. 5-B). Это произойдет, если период канала младшего байта PWM будет меньше ожидаемого. С другой стороны, слишком большой период приведет к ошибке "пропущенный шаг" (рис. 5-C). Все, что нам надо сделать - скорректировать период PWM канала младшего байта так, чтобы получить правильное значение на выходе канала младшего байта PWM (рис. 5-A).
Рис. 5. Совмещение преобразования старшего и младшего байт выборки на каналах PWM.
Алгоритм калибровки. Чтобы минимизировать ошибки типа "пропущен шаг" или "лишний шаг", авторы [1] реализовали функцию калибровки, которая подстраивает период PWM младшего байта на оптимальное значение. Сначала, со схемой усилителя, который дает 16-кратное усиление (U4), можно измерить размер шага старшего байта для все первых шагов 4 бит. В результате получаются 16 уровней инкремента старшего байта, используемых для оптимизации калибровки. Затем мы можем измерить для всех шагов изменение значения младшего байта, меняя его с 0x00 на 0xFF и обратно, для каждого уровня. Может получиться так, что не все 16 уровней окажутся подходящими для калибровки, потому что U4 не откалиброван. В результате некоторые верхние уровни окажутся бесполезными из-за насыщения ADC. Чтобы определить условие насыщения, просто анализируют считываемые их 12-битного ADC значения, чтобы они не превышали 4095.
Исходный код проекта можно скачать из репозитория [4].
[Ссылки]
1. 16-bit Audio PWM by Dual 8-bit PWM with Auto Calibration site:deeptronic.com. 2. Программный аудиокодек для STM8S. 3. DIY Multi-Effect Pedal site:deeptronic.com. 4. hamuro80 / deepstomp site:github.com. 5. Быстрый PWM DAC без выходных пульсаций. |