Аппаратный цифровой фильтр FMAC на базе STM32G4

7 сентября

управление питаниемпотребительская электроникалабораторные приборыуниверсальное применениеST Microelectronicsстатьяинтегральные микросхемыARMCortex-M4МикроконтроллерSTM32STM32G4FMACIIRFIRКИХБИХ

Алексей Гребенников (г. Москва)

Цифровые фильтры применяются в системах цифровой обработки сигналов (ЦОС) для решения двух основных задач: разделения и восстановления сигналов. Такие задачи могут решаться программными и аппаратными методами. Для их решения удобно использовать аппаратный цифровой фильтр FMAC, входящий в состав микроконтроллеров семейства STM32G4 производства STMicroelectronics.

Цифровые фильтры используются для разделения двух и более сигналов, распространяющихся совместно, а также для восстановления сигналов, которые были каким-либо образом искажены. Например, при замере электрокардиограммы (ЭКГ) первичный сигнал, регистрируемый от сенсора, помимо колебаний, обусловленных биением сердца, будет содержать колебания, обусловленные дыханием и другими физиологическими процессами. От фильтра требуется обеспечить такое разделение полезного сигнала и помехи, после которого их можно анализировать независимо друг от друга. Задача восстановления решается в тех случаях, когда первичный сигнал регистрируется в искаженном виде. Например, цифровую фильтрацию применяют, чтобы улучшить звучание музыкальных произведений, записанных на оборудовании низкого качества или для устранения размытости изображения из-за дрожания камеры либо в результате плохой фокусировки объектива.

Для решения таких задач можно воспользоваться аналоговыми фильтрами, однако цифровые фильтры позволяют достичь намного более высокой точности, а также характеристик, недостижимых для аналоговых устройств. Реализация аналоговых фильтров, как правило, более выгодна с финансовой точки зрения. Также эти фильтры обладают более высоким быстродействием и более широким динамическим диапазоном по амплитуде и частоте. В свою очередь цифровые фильтры превосходят аналоговые по точности воспроизведения желаемых частотных характеристик. В связи с этим значительно различаются подходы, используемые при проектировании аналоговых и цифровых фильтров. Для аналоговых фильтров важнее всего учесть ограничения, обусловленные элементной базой, такие как стабильность и точность параметров пассивных компонентов схемы. Цифровые фильтры, как правило, позволяют достичь заданной точности, поэтому здесь первостепенное значение приобретают проблемы, связанные с ограниченностью динамического диапазона.

Наиболее широко в ЦОС используются сигналы, дискретизированные во временной области. В этом случае отсчеты сигнала выбираются с постоянным шагом по времени. Однако могут встречаться и другие типы дискретизации. Например, выборка отсчетов может идти с равномерным интервалом в пространстве, как это происходит при считывании информации с массива тензодатчиков, размещенных на крыле самолета.

Ключевые понятия и принцип работы цифровых фильтров

Важнейшим понятием для ЦОС и, в частности, для цифровых фильтров является дельта-функция ẟ(t), или функция Дирака, которая представляет собой бесконечно узкий импульс с бесконечной амплитудой, расположенной при нулевом значении аргумента функции. При этом площадь импульса равна единице. Дельта-функцию невозможно реализовать физически, однако она очень важна для теоретического анализа сигналов и систем. Для дискретных систем используется понятие дискретной дельта-функции, обычно обозначаемой символом ẟ[n]. Также эта функция называется единичным импульсом или единичным отсчетом, и представляет собой сигнал, в котором нулевой отсчет имеет значение единицы, а все остальные отсчеты равны нулю.

Еще одно важное понятие – импульсная характеристика системы, которая представляет собой реакцию системы на единичный импульс и обычно обозначается символом h[n]. Если две любые системы имеют хотя бы какие-то различия, их импульсные характеристики будут обязательно отличаться. Сигналы сложной формы можно разложить на простые составляющие с помощью импульсной декомпозиции. Любой импульсный сигнал, являющийся компонентом разложения при импульсной декомпозиции, может быть представлен как единичный импульс, сдвинутый на соответствующую величину по временной оси и умноженный на значение отсчета исходного сигнала в этот же момент времени. Таким образом, если известна импульсная характеристика системы, возможно вычисление реакции системы на сигнал произвольной формы. Для этого входной сигнал путем декомпозиции представляется в виде совокупности импульсных сигналов с единственным ненулевым отсчетом, каждый из которых может рассматриваться как единичный импульс, умноженный на некоторую величину и сдвинутый во времени. Реакция системы на каждый входной импульс получается путем соответствующего усиления и сдвига импульсной характеристики системы. Затем общая реакция системы на входной сигнал рассчитывается путем суммирования реакций системы на все компоненты декомпозиции отдельно. Вычисление выходного сигнала по входному сигналу и импульсной характеристике производится с помощью операции свертки, которая в математических выражениях обычно обозначается звездочкой (*). Для вычисления выходного сигнала y[n] необходимо вычислить свертку согласно формуле 1:

$$y[n]=x[n]\times h[n],\qquad{\mathrm{(}}{1}{\mathrm{)}}$$

где:

  • x[n] – входной сигнал;
  • h[n] – импульсная характеристика.

Графический пример вычисления свертки для фильтра нижних частот показан на рисунке 1.

Рис. 1. Свертка для фильтра нижних частот

Рис. 1. Свертка для фильтра нижних частот

Свертка обладает важным свойством – свертка любого сигнала с единичным импульсом равна самому сигналу, что можно выразить формулой 2:

$$x[n]\times \delta [n]=x[n]\qquad{\mathrm{(}}{2}{\mathrm{)}}$$

Если немного видоизменить единичный импульс, умножив его на постоянный множитель, получится система, работающая в качестве усилителя или аттенюатора, в зависимости от величины множителя. Таким образом, свойство свертки, описанное в формуле 2, позволяет проектировать цифровые фильтры с широким набором свойств.

Цифровые фильтры можно разделить на два больших класса – фильтры с конечной импульсной характеристикой (КИХ), также называемые нерекурсивными, и фильтры с бесконечной импульсной характеристикой (БИХ), также называемые рекурсивными. Пример структуры КИХ-фильтра показан на рисунке 2.

Рис. 2. Структура КИХ фильтра

Рис. 2. Структура КИХ фильтра

Математически работа КИХ-фильтра описывается формулой 3:

$$y[n]=b_{0}x(n)+b_{1}x(n-1)+…+b_{p}x(n-p)\qquad{\mathrm{(}}{3}{\mathrm{)}}$$

Формула 3 – это свертка входного сигнала с определенным набором коэффициентов фильтра.

КИХ-фильтры обладают следующими преимуществами: они всегда устойчивы и позволяют получать произвольные АЧХ и ФЧХ. Однако при этом они требуют больше ресурсов по сравнению с БИХ-фильтрами и обладают большими задержками.

Пример структуры БИХ-фильтра показан на рисунке 3.

Рис. 3. Структура БИХ-фильтра

Рис. 3. Структура БИХ-фильтра

Математически работа БИХ фильтра описывается формулой 4:

$$y[n]=b_{0}x(n)+b_{1}x(n-1)+…+b_{p}x(n-p)-a_{1}y(n-1)-a_{2}y(n-2)-…-a_{q}y(n-q)\qquad{\mathrm{(}}{4}{\mathrm{)}}$$

БИХ-фильтры имеют следующие преимущества: они быстрее и дешевле по сравнению с КИХ-фильтрами, а также имеют аналоговые прототипы. К их недостаткам следует отнести то, что их АЧХ необходимо выбирать из реальных фильтров-прототипов, и что они не всегда устойчивы.

Рассмотрим краткий пример проектирования КИХ-фильтра с использованием оконной функции. Сначала выбирается идеальная АЧХ. АЧХ идеального фильтра имеет коэффициент передачи, равный нулю в полосе помех и единице в полосе пропускания полезного сигнала. С учетом частоты дискретизации формула АЧХ будет выглядеть следующим образом (формула 5):

$$D_{p}(f)=\begin{cases} 1, & 0 \leq f \leq f_{pass}\\ 0, & f_{stop} \leq f \leq \frac{f_{s}}{2}, \end{cases}\qquad{\mathrm{(}}{5}{\mathrm{)}}$$

где:

  • fpass – граничная частота полосы пропускания;
  • fstop – граничная частота полосы непропускания;
  • fs – частота дискретизации.

Существует множество оконных функций. Окно Хэмминга, например, описывается формулой 6:

$$w_{k}=\begin{cases} 0.54-0.46\cdot \cos (\frac{2\pi k}{N-1}), & 0 \leq k \leq N-1\\ 0, & k<0, \: k>N-1, \end{cases}\qquad{\mathrm{(}}{6}{\mathrm{)}}$$

где:

  • N – число коэффициентов фильтра.

КИХ-фильтр может быть однозначно задан коэффициентами импульсной характеристики {h(n)}. Коэффициенты нерекурсивного фильтра полностью соответствуют отсчетам импульсной характеристики цепи. Для вычисления коэффициентов импульсной характеристики необходимо вычислить обратное дискретное преобразование Фурье (ОДПФ), вычисляемое по формуле 7:

$$h(n)=\frac{1}{N}\times \sum_{k=0}^{N-1}{H(k)\cdot e^{\frac{j\cdot 2\pi \cdot n\cdot k}{N}}}\qquad{\mathrm{(}}{7}{\mathrm{)}}$$

Далее умножаем каждый отсчет исходной импульсной функции на отсчет оконной функции с тем же порядковым номером (формула 8):

$$h_{wk}=h_{k}\times w_{k}\qquad{\mathrm{(}}{8}{\mathrm{)}}$$

В результате получаем набор коэффициентов КИХ-фильтра. Для построения реальной АЧХ получившегося фильтра необходимо выполнить прямое дискретное преобразование Фурье.

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

Реализация цифровых фильтров на STM32G4

Цифровая фильтрация требует значительных вычислительных ресурсов. Поэтому аппаратное ускорение этой операции позволяет значительно повысить производительность системы в целом. Входные данные для цифрового фильтра могут поступать с аналого-цифрового преобразователя (АЦП) или по какому-либо интерфейсу ввода-вывода. Микроконтроллеры семейства STM32G4 производства компании STMicroelectronics содержат встроенный математический ускоритель FMAC и богатый набор аналоговой периферии и интерфейсов ввода-вывода, что позволяет эффективно решать некоторые вопросы цифровой обработки сигналов, в частности, цифровой фильтрации. Так, например, микроконтроллеры линейки STM32G4x1 содержат 2×12 бит АЦП и 4х12 бит ЦАП, периферийные модули DMA, PWM, WDT, FMAC, CORDIC, OPAMP и LPTIM, интерфейсы FDCAN, I2C, IrDA, LIN, SPI, UART и USB. Все микроконтроллеры семейства STM32G4 содержат модуль FMAC. Это обуславливает применение этих устройств в таких сферах как управление двигателями, обработка аудиоданных, управление блоками питания, освещение, аналоговые сенсоры для здравоохранения, фитнеса, робототехники.

Основой блока FMAC является операция умножения с накоплением (MAC) двух 16-битных операндов в формате с фиксированной точкой. Операнды считываются из внутренней памяти RAM размером 256х16, результат умножения также записывается в память. Программное обеспечение центрального процессора (CPU) не принимает участия в этих рутинных операциях, что позволяет значительно разгрузить CPU для выполнения других задач. С помощью блока FMAC можно реализовать как КИХ-, так и БИХ-фильтры. Тип фильтра, его порядок и коэффициенты задаются с помощью программного обеспечения.

На рисунке 4 показана архитектура блока MAC.

Рис. 4. Архитектура блока MAC

Рис. 4. Архитектура блока MAC

Входной буфер Х содержит сырые данные, которые необходимо отфильтровать. В – массив коэффициентов фильтра, применимых к выборкам Х. Размер X и В одинаков и равен N + 1. Выходной буфер Y содержит результаты фильтрации. A – массив коэффициентов фильтра, применимых к результатам преобразования Y. Размер Y и А одинаков и равен M + 1. Для получения результата y[n] необходимо выполнить (N + 1) + M операций умножения с накоплением N + 1 умножений X и B и М умножений Y и А.

Входные и выходные данные FMAC представлены в формате с фиксированной точкой q1.15. В этом формате один бит представляет знак и остальные 15 – дробную часть числа. Диапазон значений при таком представлении -1 (0х8000)…0,99997 (0x7FFF).

Конвертация 32-битных чисел в формате с плавающей точкой (f32) в 16-битные числа с фиксированной точкой и обратно выполняется методом программного умножения и приведения к нужному типу с помощью модуля Cortrex-M4 FPU. Для этого используются следующие функции:

  • value_q15 = (int16_t)(value_f32*0x8000) – преобразование f32 в q15, выполняется за 8 тактов;
  • value_f32 = (float)value_q15/(float)0x8000 – преобразование q15 в f32, выполняется за 10 тактов.

На рисунке 5 показаны внутренние форматы модуля FMAC, используемые в процессе умножения с накоплением.

Рис. 5. Внутренние форматы модуля FMAC

Рис. 5. Внутренние форматы модуля FMAC

Выход умножителя в формате q2.30 усечен до q2.22 и суммируется с содержимым аккумулятора. Аккумулятор содержит 26 битов, из которых 22 бита – дробная часть и 4 бита – целая часть и знак. Дополнительные биты целой части аккумулятора позволяют ему хранить числа в диапазоне -8 (0х4000000)…+8 (0x3FFFFFF). Такая ситуация может возникнуть, если ряд последовательных коэффициентов равен большим положительным или отрицательным числам. Если коэффициент усиления фильтра меньше единицы для всех частот, величина аккумулятора всегда будет в диапазоне ±1. Если во время суммирования аккумулятор все таки переполняется, выставляется специальный флаг, который помогает в процессе отладки.

Коэффициент усиления аккумулятора регулируется программно и может находиться в диапазоне 0…42 дБ с шагом 6 дБ. Это необходимо для проектирования БИХ-фильтров.

Модуль FMAC выполняет операции над векторными данными, которые являются массивами 16-битных скаляров. Для хранения векторов возможно выделение до трех областей памяти в локальной SRAM, как это показано на рисунке 6.

Рис. 6. Области памяти для хранения данных

Рис. 6. Области памяти для хранения данных

Две области памяти можно использовать для входных данных и одну – для выходных. Базовые адреса и размеры областей памяти устанавливаются соответствующими регистрами, как это показано на рисунке 6. Базовые адреса областей памяти выбираются произвольно, но при этом необходимо учитывать, что все они должны размещаться во внутренней памяти в диапазоне 0x00…0xFF. Буферы X1, X2 и Y могут накладываться друг на друга. Эти буферы не видны в карте памяти CPU.

До начала операции фильтрации CPU или контроллер DMA должны инициализировать содержимое входных буферов с помощью специальных функций путем записи в регистр WDATA. Входными данными могут быть коэффициенты фильтра или данные для фильтрации. Данные копируются в соответствующий буфер на основании значения указателя на запись. После каждой операции записи указатель инкрементируется. После достижения указателем верхнего предела он оборачивается, переходя на базовый адрес.

Области памяти X1 и Y1 могут быть организованы как кольцевые буферы для более эффективного обмена данными (рисунок 7).

Рис. 7. Организация кольцевых буферов

Рис. 7. Организация кольцевых буферов

Если в буфере Х1 свободного места меньше, чем задано в поле FULL_WM регистра FMAC_X1BUFCFG, устанавливается флаг переполнения буфера. До момента установления этого флага генерируются прерывания или запросы DMA для заполнения буфера. Установление предела FULL_WM позволяет выполнять несколько транзакций записи за одно прерывание без риска переполнения. Однако в случае возникновения переполнения выставляется флаг OVFL, и дальнейшая запись данных игнорируется. В случае переполнения указатель записи не инкрементируется. В операциях фильтрации в буфере X1 хранятся данные, которые необходимо отфильтровать.

Если в буфере Y данных для чтения меньше, чем задано в поле EMPTY_WM регистра FMAC_YBUFCFG, устанавливается флаг опустошения буфера. До момента установления этого флага генерируются прерывания или запросы DMA для чтения данных из буфера. Установление предела EMPTY_WM позволяет выполнить несколько транзакций чтения за одно прерывание без риска опустошения. Однако в случае опустошения буфера устанавливается флаг UNFL, указатель на чтение не инкрементируется, и для всех операций чтения выдаются данные от текущего указателя. В буфере Y хранится результат фильтрации – свертка.

Буфер X2 может быть использован только для векторных данных, для этого буфера недоступен кольцевой режим. Поэтому в функциях фильтрации буфер X2 используется для хранения коэффициентов импульсной характеристики.

Рассмотрим пример создания адаптивного КИХ-фильтра для подавления помех с использованием пакета STM32CubeG4 MCU. Для лучшего усвоения информации при рассмотрении примера рекомендуется использование отладочных плат, доступных на складе компании КОМПЭЛ. Это позволит на практике проверить полученные расчетные данные.

К адаптивным относятся фильтры, меняющие свою импульсную характеристику в зависимости от входного воздействия. Такие фильтры часто используются для подавления нежелательных помех в каналах передачи данных. Адаптивный алгоритм может, например, определить частоту помехи и настроить коэффициенты фильтра таким образом, чтобы подавлять помеху этой частоты. Существуют несколько алгоритмов создания адаптивных фильтров. В данном примере используется авторегрессионный алгоритм. Выходными данными такого алгоритма являются коэффициенты КИХ-фильтра, которые периодически обновляются. Входной сигнал оцифровывается и хранится в памяти блоками по 2048 выборок. После формирования нового блока данных генерируется запрос DMA для передачи данных модулю FMAC, где осуществляется фильтрация. После фильтрации данные снова копируются в память с помощью механизма DMA, как это показано на рисунке 8.

Рис. 8. Обмен данными с модулем FMAC

Рис. 8. Обмен данными с модулем FMAC

На рисунке 8 показан общий случай обмена данными через DMA, где видно, что кроме памяти обмен может происходить с периферийными устройствами.

Время между загрузками блоков данных можно использовать для обновления коэффициентов фильтра.

Предположим, что входной сигнал состоит из «белого» шума с двумя помехами на частотах 8 и 16 кГц, как это показано на рисунке 9. Частота оцифровки равна 48 кГц.

Рис. 9. Входной сигнал с двумя помехами

Рис. 9. Входной сигнал с двумя помехами

АЧХ адаптивного фильтра для подавления такого шума показана на рисунке 10.

Рис. 10. АЧХ адаптивного фильтра для подавления помех на частотах 8 и 16 кГц

Рис. 10. АЧХ адаптивного фильтра для подавления помех на частотах 8 и 16 кГц

На рисунке 10 видны провалы на частотах 8 и 16 кГц, позволяющие фильтровать помехи с этими частотами. Выходной сигнал фильтра с АЧХ рисунка 10 показан на рисунке 11.

Рис. 11. Сигнал после фильтрации

Рис. 11. Сигнал после фильтрации

Как было показано в разделе «Ключевые понятия и принцип работы цифровых фильтров», КИХ-фильтр фактически производит свертку входного сигнала с определенным набором коэффициентов фильтра. Число коэффициентов определяет размер полосы удержания по отношению к общей ширине полосы частот. Большое число коэффициентов позволяет создавать фильтры с достаточно узкой полосой удержания, минимизируя таким образом потери информации. Однако вычисление N коэффициентов обычно требует порядка N2 операций, поэтому количество коэффициентов ограничено вычислительной мощностью системы. На рисунке 12 показан фильтр с 51 коэффициентом.

Рис. 12. КИХ-фильтр с 51 коэффициентом

Рис. 12. КИХ-фильтр с 51 коэффициентом

Обычно коэффициенты вычисляются в формате с плавающей точкой, поэтому они должны быть переведены в формат с фиксированной точкой для совместимости с FMAC. Как было показано выше, формат q1.15, используемый в FMAC, позволяет представлять числа в диапазоне -1 (0х8000)…0,99997 (0х7FFF). При правильном проектировании все коэффициенты адаптивного фильтра должны быть меньше или равны единице, поэтому они должны укладываться в диапазон формата q1.15 модуля FMAC. Если коэффициенты получаются больше единицы, их все нужно разделить на величину наибольшего коэффициента или какую-либо константу еще большей величины.

Для преобразования из формата с плавающей точкой в формат с фиксированной точкой все коэффициенты необходимо умножить на 32768 (0х8000) и привести к формату int16 (листинг 1).

Листинг 1.


value_q15 = (int16_t) (value_f32*0x8000)

Эта операция выполняется модулем FPU и занимает 8 тактов. Соответственно, для конвертации 51 коэффициента требуются примерно 408 тактов.

Коэффициенты, сгенерированные для АЧХ рисунка 10, показаны в таблицах 1 и 2, соответственно, в формате с плавающей точкой и в формате с фиксированной точкой.

Таблица 1. Коэффициенты КИХ-фильтра в формате с плавающей точкой

Коэффициент Величина Коэффициент Величина Коэффициент Величина
b0 1,000000000000000 b1 -0,067585539745262 b2 0,006224959010140
b3 0,028277400466664 b4 0,095621684047959 b5  -0,025419309428324
b6 -0,118211581775912 b7 -0,017634551659068 b8 0,007942637819215
b9 0,010412979853874 b10 0,008068146389393 b11 -0,025829002206100
b12 -0,099047067935483 b13 0,013754178201556 b14 0,010326267975033
b15 -0,004410154604102 b16 0,018253517952308 b17 -0,020353758821992
b18 -0,024400399446690 b19 -0,014641218999051 b20 0,056344891227786
b21 0,002202080623664 b22 0,062681980108469 b23 0,010721748758013
b24 -0,076947777702560 b25 -0,013179271499833 b26 0,000291963084803
b27 0,032380282793325 b28 0,055274021304300 b29 -0,028443886878990
b30 -0,073984161617267 b31 0,018549937430136 b32 0,061223395867052
b33 0,005625129616435 b34 -0,012746336662958 b35 -0,014040525509958
b36 -0,006883769006464 b37 -0,033436800912042 b38 0,025923135119918
b39 -0,063274099314035 b40 0,075218785578469 b41 -0,017973648077274
b42 -0,083497943067555 b43 -0,012450048061703 b44 0,051849240421091
b45 -0,036429925307428 b46 0,004933033556656 b47 0,015810917169290

b48

-0,047438072229140 b49 0,006899397242167 b50 0,085755772557646

Таблица 2. Коэффициенты КИХ-фильтра в формате с фиксированной точкой

Коэффициент Величина Коэффициент Величина Коэффициент Величина
b0 32767 b1 -2215 b2 203
b3 926 b4 3133 b5 -833
b6 -3874 b7 -578 b8 260
b9 341 b10 264 b11 -847
b12 -3246 b13 450 b14 338
b15 -145 b16 598 b17 -667
b18 -800 b19 -480 b20 1846
b21 72 b22 2053 b23 351
b24 -2522 b25 -432 b26 9
b27 1061 b28 1811 b29 -933
b30 -2425 b31 607 b32 2006
b33 184 b34 -418 b35 -461
b36 -226 b37 -1096 b38 849
b39 -2074 b40 2464 b41 -589
b42 -2737 b43 -408 b44 1698
b45 -1194 b46 161 b47 518
b48 -1555 b49 226 b50 2810

В связи с тем, что в формате q1.15 используются 16 бит, а в формате с плавающей точкой с одинарной точностью – 24 бита, снижается точность вычислений. Это нужно учитывать при выборе FMAC в качестве вычислительного узла. Если снижение точности недопустимо, необходимо использовать программную реализацию фильтра с числами в формате с плавающей точкой или с 32-битными числами с фиксированной точкой. В рассматриваемом примере спектр сигнала, рассчитанный фильтром с фиксированной точкой, идентичен сигналу фильтра с плавающей точкой с точностью до 0,007 дБ, как это видно на рисунке 13.

Рис. 13. Разница спектров фильтров с фиксированной и плавающей точкой

Рис. 13. Разница спектров фильтров с фиксированной и плавающей точкой

Для конфигурации FMAC можно использовать драйвер HAL пакета STM32CubeG4 MCU. Перед доступом к любому регистру FMAC необходимо активировать тактовую частоту FMAC (листинг 2):

Листинг 2.


__HAL_RCC_FMAC_CLK_ENABLE();

Необходимо зарезервировать область системной памяти для хранения коэффициентов (листинг 3):

Листинг 3.


static int16_t aFilterCoeffB[51];

Также необходимо задекларировать структуру, содержащую параметры FMAC (листинг 4):

Листинг 4.


FMAC_HandleTypeDef hfmac;

После этого можно конфигурировать FMAC, используя функцию HAL_FMAC_FilterConfig() (листинг 5):

Листинг 5.


/* declare a filter configuration structure */

FMAC_FilterConfigTypeDef sFmacConfig;

/* Set the coefficient buffer base address */

sFmacConfig.CoeffBaseAddress = 0;

/* Set the coefficient buffer size to the number of coeffs */

sFmacConfig.CoeffBufferSize = 51;

/* Set the Input buffer base address to the next free address */

sFmacConfig.InputBaseAddress = 51;

/* Set the input buffer size greater than the number of coeffs */

sFmacConfig.InputBufferSize = 100;

/* Set the input watermark to zero since we are using DMA */

sFmacConfig.InputThreshold = 0;

/* Set the Output buffer base address to the next free address */

sFmacConfig.OutputBaseAddress = 151;

/* Set the output buffer size */

sFmacConfig.OutputBufferSize = 100;

/* Set the output watermark to zero since we are using DMA */

sFmacConfig.OutputThreshold = 0;

/* No A coefficients since FIR */

sFmacConfig.pCoeffA = NULL;

sFmacConfig.CoeffASize = 0;

/* Pointer to the coefficients in memory */

sFmacConfig.pCoeffB = aFilterCoeffB;

/* Number of coefficients */

sFmacConfig.CoeffBSize = 51;

/* Select FIR filter function */

sFmacConfig.Filter = FMAC_FUNC_CONVO_FIR;

/* Enable DMA input transfer */

sFmacConfig.InputAccess = FMAC_BUFFER_ACCESS_DMA;

/* Enable DMA output transfer */

sFmacConfig.OutputAccess = FMAC_BUFFER_ACCESS_DMA;

/* Enable clipping of the output at 0x7FFF and 0x8000 */

sFmacConfig.Clip = FMAC_CLIP_ENABLED;

/* P parameter contains number of coefficients */

sFmacConfig.P = 51;

/* Q parameter is not used */

sFmacConfig.Q = FILTER_PARAM_Q_NOT_USED;

/* R parameter contains the post-shift value (none) */

sFmacConfig.R = 0;

/* Configure the FMAC */

if (HAL_FMAC_FilterConfig(&hfmac, &sFmacConfig) != HAL_OK)

/* Configuration Error */

Error_Handler();

Функция HAL_FMAC_FilterConfig() программирует контрольные и конфигурационные регистры, а также загружает коэффициенты в локальную память FMAC (буфер X2).

Для работы FMAC из данного примера конфигурируются три канала DMA:

  • Канал 1 используется для предварительной загрузки данных. После каждой смены коэффициентов необходима остановка и повторный запуск FMAC, при этом FMAC не начинает работу до тех пор, пока буфер данных не будет заполнен. Поэтому используется 51 выборка данных из предыдущего блока для первоначальной инициализации FMAC после перезапуска. Таким образом, фильтр инициализируется в то же состояние, в котором он был до остановки, и предотвращается потеря данных. Эту операцию можно выполнить программно, но в данном случае используется DMA.
  • Канал 2 используется для записи. По этому каналу входные данные копируются в буфер FMAC, когда он не полностью заполнен.
  • Канал 3 используется для чтения. По этому каналу считываются результаты работы FMAC, когда они доступны.

Листинг 6 показывает, как сконфигурировать каналы DMA. Для хранения параметров каналов используются три структуры:

Листинг 6.


DMA_HandleTypeDef hdma_fmac_preload; /* Preload channel */

DMA_HandleTypeDef hdma_fmac_read; /* Read channel */

DMA_HandleTypeDef hdma_fmac_write; /* Write channel */

Затем структуры инициализируются и передаются функции HAL_DMA_Init() (листинг 7):

Листинг 7.


/* Preload channel initialisation */

hdma_fmac_preload.Instance = DMA1_Channel1;

hdma_fmac_preload.Init.Request = DMA_REQUEST_MEM2MEM;

hdma_fmac_preload.Init.Direction = DMA_MEMORY_TO_MEMORY;

hdma_fmac_preload.Init.PeriphInc = DMA_PINC_ENABLE;

hdma_fmac_preload.Init.MemInc = DMA_MINC_DISABLE;

hdma_fmac_preload.Init.PeriphDataAlignment =

DMA_PDATAALIGN_HALFWORD;

hdma_fmac_preload.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

hdma_fmac_preload.Init.Mode = DMA_NORMAL;

hdma_fmac_preload.Init.Priority = DMA_PRIORITY_HIGH;

if (HAL_DMA_Init(&hdma_fmac_preload) != HAL_OK)

Error_Handler();

/* Connect the DMA channel to the FMAC handle */

__HAL_LINKDMA(hfmac,hdmaPreload,hdma_fmac_preload);

/* Write channel initialisation */

hdma_fmac_write.Instance = DMA1_Channel2;

hdma_fmac_write.Init.Request = DMA_REQUEST_FMAC_WRITE;

hdma_fmac_write.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_fmac_write.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_fmac_write.Init.MemInc = DMA_MINC_ENABLE;

hdma_fmac_write.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

hdma_fmac_write.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

hdma_fmac_write.Init.Mode = DMA_NORMAL;

hdma_fmac_write.Init.Priority = DMA_PRIORITY_HIGH;

if (HAL_DMA_Init(&hdma_fmac_write) != HAL_OK)

Error_Handler();

/* Connect the DMA channel to the FMAC handle */

__HAL_LINKDMA(hfmac,hdmaIn,hdma_fmac_write);

/* Read channel initialisation */

hdma_fmac_read.Instance = DMA1_Channel3;

hdma_fmac_read.Init.Request = DMA_REQUEST_FMAC_READ;

hdma_fmac_read.Init.Direction = DMA_PERIPH_TO_MEMORY;

hdma_fmac_read.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_fmac_read.Init.MemInc = DMA_MINC_ENABLE;

hdma_fmac_read.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

hdma_fmac_read.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

hdma_fmac_read.Init.Mode = DMA_NORMAL;

hdma_fmac_read.Init.Priority = DMA_PRIORITY_HIGH;

if (HAL_DMA_Init(&hdma_fmac_read) != HAL_OK)

Error_Handler();

/* Connect the DMA channel to the FMAC handle */

__HAL_LINKDMA(hfmac,hdmaIn,hdma_fmac_read);

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

Фильтр активируется каждый раз, когда в буфере памяти собирается достаточно данных для фильтрации. Новые выборки хранятся в двойном массиве в системной памяти (листинг 8):

Листинг 8.


static int16_t aInputValues[2][2048];

int CurrentInputArraySize = 2048;

Двойной массив позволяет загружать новые данные в память в то время, когда идет обработка текущих данных. Для этого необходим индекс, который показывает, какой массив обрабатывается в текущий момент времени (листинг 9):

Листинг 9.


int Frame = 1;

Также необходим массив для хранения выходных данных (листинг 10):

Листинг 10.


static int16_t aCalculatedFilteredData[2048];

int ExpectedCalculatedFilteredDataSize = 2048;

Как было показано выше, программное обеспечение загружает 51 выборку предыдущего кадра в буфер предварительной загрузки для восстановления состояния FMAC после загрузки новых коэффициентов (листинг 11):

Листинг 11.


if (HAL_FMAC_FilterPreload_DMA(&hfmac,

&aInputValues[CurrentInputArray][1997], 51, NULL, 0) != HAL_OK)

Error_Handler();

/* Switch frames */

Frame ? Frame=0 : Frame=1;

Когда предварительная загрузка завершена, о чем сигнализирует прерывание канала 1 DMA, программное обеспечение активирует канал DMA, который производит загрузку данных текущего блока (листинг 12):

Листинг 12.


if (HAL_FMAC_AppendFilterData(&hfmac, &aInputValues[CurrentInputArray][0],

&CurrentInputArraySize) != HAL_OK)

Error_Handler();

Затем программное обеспечение включает FMAC (листинг 13):

Листинг 13.



if (HAL_FMAC_FilterStart(&hfmac, aCalculatedFilteredData,

&ExpectedCalculatedFilteredDataSize) != HAL_OK)

Error_Handler();

FMAC начинает вычисления и результаты записывает в выходной буфер. После вычисления каждой выборки FMAC генерирует запрос DMA на чтение, и DMA копирует выборку в системную память. Этот процесс продолжается до окончания обработки всего блока данных без участия программного обеспечения. После завершения обработки блока DMA генерирует прерывание для центрального процессора. Процессор останавливает FMAC (листинг 14):

Листинг 14.


if (HAL_FMAC_FilterStop(&hfmac) != HAL_OK)

Error_Handler();

Программное обеспечение может обновить коэффициенты, если это требуется, путем вызова функции HAL_FMAC_FilterConfig(). Новые коэффициенты должны быть предварительно сохранены в aFilterCoeffB[].

Для обработки следующего блока необходимо повторить шаги, описанные выше, начиная с предварительной загрузки (листинг 15):

Листинг 15.


(HAL_FMAC_FilterPreload_DMA())

Модуль FMAC может работать в режимах малого энергопотребления, как это показано в таблице 3.

Таблица 3. Работа в энергосберегающем режиме

Режим Описание
Run (Работа) Активно
Sleep (Сон) Активно. Прерывания периферии приводят к выходу устройства из режима сна.
Low-Power Run (Работа в режиме энергосбережения) Активно
Low-Power Sleep (Сон в режиме энергосбережения) Активно. Прерывания периферии приводят к выходу устройства из энергосберегающего режима сна.
Stop 0/Stop 1 (Стоп 0/Стоп 1) Недоступно
Stop 2 (Стоп 2)
Stendby (Ожидание)
Shutdown (Выключено)

Заключение

Наличие аппаратного ускорителя функций фильтрации, в частности – модуля FMAC, в устройствах семейства STM32G4 позволяет сократить время вычислений и освободить ресурсы центрального процессора для выполнения других задач. В паре со встроенными устройствами АЦП/ЦАП и модулями периферии это позволяет проектировать недорогие системы с малым числом элементов для решения широкого спектра задач, таких как фильтрация звука, шумов, компенсация в источниках питания, IoT и других. Именно для таких задач были разработаны микроконтроллеры STM32G4 компании STMicroelectronics. Специалисты компании КОМПЭЛ всегда рады помочь в выборе устройства из линейки STM32G4, оптимального для конкретного приложения.

•••

Наши информационные каналы

О компании ST Microelectronics

Компания STMicroelectronics является №1 производителем электроники в Европе. Компоненты ST широко представлены в окружающих нас потребительских товарах – от iPhone до автомобилей разных марок. Лидеры индустриального рынка выбирают компоненты ST за их надежность и выдающиеся технические параметры. В компании ST работает 48 000 сотрудников в 35 странах. Производственные мощности расположены в 12 странах мира. Более 11 тысяч сотрудников заняты исследованиями и разработками – инновационное лидерство ...читать далее

Товары
Наименование
NUCLEO-G474RE (ST)
NUCLEO-G431RB (ST)
B-G474E-DPOW1 (ST)
STM32G431C8T6 (ST)
STM32G431K8T6 (ST)
STM32G441KBU6 (ST)
STM32G473CBU6 (ST)
STM32G473CET6 (ST)
STM32G483VET6 (ST)
STM32G474CBT6 (ST)
STM32G484CEU6 (ST)