STM32: DSP с использованием библиотеки CMSIS |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Этот апноут (перевод AN4841 [1]) описывает разработку цифровых фильтров для аналоговых сигналов и трансформаций между доменами времени и частоты. Обсуждаемые в этом документе примеры включают FIR-фильтры высокой частоты и низкой частоты, а также преобразования FFT с плавающей точкой и фиксированной точкой на различных частотах. Примечание: FIR означает Finite-Impulse Response, т. е. фильтр с конечной импульсной характеристикой, или КИХ-фильтр. У этого фильтра отсутствуют обратные связи с выхода на вход на ветвях фильтра. FFT означает Fast Fourier Transform, т. е. быстрое преобразование Фурье. Соответствующее firmware (X-CUBE-DSPDEMO), предназначенное для микроконтроллеров (MCU) серий STM32F429xx и STM32F746xx, может быть портировано на любой микроконтроллер STM32. DSP (Digital Signal Processing, цифровая обработка сигнала, ЦОС) это математическая манипуляция над данными сигналов. Сигналы для обработки в различных форматов включат звук, видео или любой аналоговый сигнал, который несет в себе информацию, такую как выходной сигнал микрофона. Модели MCU, основанные на ядрах Cortex®-M4 STM32F4 и Cortex®-M7 STM32F7, предоставляют инструкции для сигнальной обработки, и поддерживают продвинутые инструкции SIMD (Single Instruction Multi Data, одна инструкция и множество данных) одноцикловые инструкции MAC (Multiply and Accumulate, умножение с накоплением). Использование STM32 MCU в приложениях DSP реального времени не только снижает стоимость оборудования, но также снижает общее энергопотребление реализуемой системы. • PM0214 STM32F3 and STM32F4 Series Cortex®-M4 programming manual site:st.com. [DSP: базовые понятия] В цифровой обработке применяются форматы чисел с плавающей точкой (floating point) и фиксированной точкой (fixed point). Floating point. Это метод для представления реальных чисел. Блок плавающей точки (Floating Point Unit, FPU [2]) в Cortex®-M4 работает только с числами одинарной точности (single precision), которые включают 8-битное поле экспоненты (exponent) и 23-битное поле дробной части (fraction) для 32-битного представления числа (см. рис. 1). Рис. 1. Формат числа с плавающей точкой одинарной точности (single precision). Блок FPU Cortex®-M7 поддерживает формат чисел как одиночной, так и двойной точности (double precision), как показано на рис. 2. Рис. 2. Формат числа с плавающей точкой двойной точности (double precision). Значение числа одинарной точности: Value = (-1)s x M x 2(E-127) Значение числа двойной точности: Value = (-1)s x M x 2(E-1023) Здесь S это значение бита знака, M значение мантиссы, E значение экспоненты. Fixed point. Это представление выражает числа с помощью фиксированной целой части (integer part) и фиксированной дробной части (fractional part), в формате двоичного дополнения (2-complement format). Например, 32-битная реализация фиксированной точки, показанная на рис. 3, выделяет 24 бита для целой части 8 бита для дробной части. Рис. 3. Формат числа фиксированной точки. Для ядер Cortex®-Mx доступны данные с фиксированной точкой разрядности 8, 16 и 32 бита. Для операций DSP чаще всего используются форматы Q7, Q15 и Q31, где биты дробной части представляют значения только в диапазоне между -1.0 и + 1.0. Представления числа в формате Q15: Value = (-1)bs x (b14 x 2-1 + b13 x 2-2 + ... + b1 x 2-14 + b0 x 2-15) Здесь bs это бит знака (15-й бит), и bn это значение для бита n. Диапазон чисел, поддерживаемых форматом Q15, представленных дробной частью -1.0 и 1.0, соответствует самому малому и самому большому целому числу -32768 и 32767 соответственно. Например, число 0.25 в формате Q15 будет закодировано как 0x2000 (8192). При выполнении операций с фиксированной точкой выражение представляется следующим образом: c = a < операнд > b Здесь a, b и c это числа с фиксированной запятой, и < операнд > обозначает сложение, вычитание, умножение или деление. То же самое выражение действует и для чисел с плавающей запятой. Замечание: следует уделять особое внимание выполнению операций над числами с фиксированной запятой. Например, если c = a x b, где a и b представлены в формате Q31, то это приведет к неправильному результату, потому что компилятор обработает это выражение как операцию над целыми числами, генерируя код "muls a, b" и сохранит только самые младшие 32 бита результата. Фиксированная точка против плавающей точки. Таблица 1 высвечивает основные достоинства и недостатки операций фиксированной точки и плавающей точки для приложений DSP. Таблица 1. За и против применения фиксированной точки и плавающей точки.
[Инструкции DSP Cortex®] Ядра Cortex®-Mx предоставляют несколько инструкций, предназначенных для эффективной реализации алгоритмов DSP. Инструкции насыщения (saturation). Инструкции насыщения для сложения и вычитания доступны для 8-, 16- и 32-битных значений, некоторые из них перечислены в таблице 2. Таблица 2. Инструкции насыщения.
Инструкция SSAT (аббревиатура от Signed SATurate) используется для масштабирования и насыщения значения со знаком для любой позиции бита, с опциональным сдвигом перед насыщением. Инструкция MAC. Инструкции Multiply ACcumulate (MAC, умножение с накоплением) широко используются в алгоритмах DSP, таких как фильтры FIR и IIR. Примечание: аббревиатура IIR обозначает Infinite Impulse Response, т. е. фильтр с бесконечной импульсной характеристикой (БИХ), у которого присутствуют обратные связи с выхода на вход от ветвей фильтра. Выполнение MAC за 1 такт - ключевое требование достижения высокой производительности DSP. Следующий пример показывает, как работает инструкция SMMLA (Signed Most significant word MuLtiply Accumulate). SMMLA R0, R4, R5, R6 ; умножается R4 и R5, распаковываются верхние 32 бита, ; добавляется R6, отбрасывается остаток и результат ; записывается в R0. Инструкции SIMD. В дополнение к инструкциям MAC, которые делают за 1 такт умножение с накоплением, существуют инструкции SIMD (Single Instruction Multiple Data), выполняющие несколько идентичных операций за 1 такт. Некоторые из таких инструкций перечислены в таблице 3. Таблица 3. Инструкции SIMD.
Следующий пример объясняет, как работает инструкция __shadd8. unsigned int add_and_halve (unsigned int val1, unsigned int val2) { unsigned int res; res = __shadd8(val1, val2); // res[7:0] = (val1[7:0] +val2[7:0]) >> 1 // res[15:8] = (val1[15:8] +val2[15:8]) >> 1 // res[23:16] = (val1[23:16]+val2[23:16]) >> 1 // res[31:24] = (val1[31:24]+val2[31:24]) >> 1 return res; } Встроенный объект компилятора (intrinsic) __shadd8 возвратит: • Поделенный на 2 результат сложения первых байт каждого операнда, в первом байте возвращаемого значения. [Алгоритмы] Фильтр. Чаще всего фильтры бывают: • FIR (Finite Impulse Response): используются, помимо всего прочего, в управлении двигателями, эквалайзерах звука. Преобразование. Это функция, которая преобразует (transform) данные из одного домена в другой. Типичный пример это FFT (Fast Fourier Transform): эффективный алгоритм, используемый для преобразования дискретного сигнала из домена времени в эквивалентный сигнал в домене частоты, работающий на основе Discrete Fourier Transform (DFT). [Разработка приложения DSP] Cortex® Microcontroller Software Interface Standard (CMSIS) это слой абстракции от аппаратуры, устраняющий зависимость от производителя для всех микроконтроллеров, основанных на ядре Cortex®. CMSIS разработала организация Arm® вместе с партнерами - производителями микроконтроллеров (MCU), программных инструментов (компиляторов) и дополнительных промежуточных библиотек (middleware). Идея CMSIS в том, чтобы предоставить целостностный и простой программный интерфейс к аппаратуре MCU, дающий доступ к периферийным устройствам, операционным системам реального времени и библиотекам поддержки. CMSIS призвана упростить повторное использование кода, снижение времени обучения и разработки, и в ускорения выхода на рынок конечных продуктов, основанных на новых MCU. Библиотека CMSIS поставляется вместе firmware от ST, в каталоге \Drivers\CMSIS\. Библиотека CMSIS-DSP включает: • Базовые математический функции для операции над векторами (массивами). Большинство алгоритмов использует числа с плавающей запятой (floating-point) и фиксированной запятой (fixed-point) в различных форматах. Например для случая FIR доступны функции Arm®: arm_fir_init_f32 Обзор демонстрационных приложений DSP. Цель этой демонстрации - показать полную интеграцию с STM32F429 при использовании ADC, DAC, DMA и таймеров, а также вызовы подпрограмм CMSIS. Все это с использованием графики, отображаемой на 2.4" QVGA TFT LCD, установленном на плате Discovery [3]. Демонстрация также показывает простоту миграции с микроконтроллера STM32F4 на один из микроконтроллеров серии STM32F7. Графический интерфейс пользователя разработан с использованием STemWin, чтобы упростить доступ к различным функциям демонстрационного приложения. Основные функции этого примера реализации FFT для STM32F429: • Генерация сигнала данных и передача его через DMA1 Stream6 Channel7 на выход цифро-аналогового преобразователя (DAC Channel2). Для STM32F746: • Генерация сигнала данных и передача его через DMA1 Stream5 Channel7 на выход цифро-аналогового преобразователя (DAC Channel1). Очевидно, что по функционалу реализации STM32F429 и STM32F746 совпадают, и библиотека CMSIS как раз и показывает снижение затрат на портирование приложения с одного MCU на другой. Кусок кода ниже показывает, как инициализировать функцию CFFT для вычисления FFT на 1024, 256 или 64 точки, и выполнить преобразование входных сигналов (aFFT_Input_f32) из домена времени в домен частоты, после чего вычисляется магнитуда каждого бина, и в завершение вычисляется и возвращается значение максимальной магнитуды. // Инициализация модуля CFFT/CIFFT, intFlag=0, doBitReverse=1: arm_cfft_radix4_init_f32(&FFT_F32_struct, FFT_Length, FFT_INVERSE_FLAG, FFT_Normal_OUTPUT_FLAG); // Функция обработки для floating-point Radix-4 CFFT/CIFFT: arm_cfft_radix4_f32(&FFT_F32_struct, aFFT_Input_f32); // Обработка данных с помощью Complex Magnitude Module,
// для вычисления магнитуды каждого бина:
arm_cmplx_mag_f32(aFFT_Input_f32, aFFT_Output_f32, FFT_Length);
// Вычисление максимального значения maxValue: arm_max_f32(aFFT_Output_f32, FFT_Length, &maxValue, &maxIndex); Значение FFT_Length зависит от выбора пользователя, оно может быть 1024, 256 или 64. Инициализацию FFT и обработку других форматов можно найти в исходном файле fft_processing.c. [Производительность FFT] Рис. 4 показывает абсолютное время выполнения и количество тактов расчета FFT на STM32F429, работающем на частоте 180 МГц, в то время как рис. 5 показывает результат с теми же параметрами, измеренный на STM32F746, работающем на частоте 216 МГц. Оба примера кода были собраны с использованием тулчейна MDK-Arm™ (5.14.0.0) с поддержкой компилятора языка C V5.05, с оптимизацией Level 3 (-O3) для времени выполнения. Рис. 4. Производительность вычисления размера FFT на STM32F429. Рис. 5. Производительность вычисления размера FFT на STM32F746. Работа кода на STM32F429I-DISCO. Чтобы запустить один из выбранных примеров FFT, подключите PA5 к PA0. Форма и спектр сигнала будет отображена на LCD. Изменением позиции слайдера Вы можете наблюдать форму нового входного сигнала и его спектр, обновляющиеся в реальном времени (см. рис. 6). Рис. 6. Запуск FFT на 1024 точки с входными данными Float-32 на оценочной плате разработчика STM32F429I-DISCO. Работа кода на STM32F746-DISCO. В этом случае можно оценить достоинства существующего соединения между PA4 и DCMI_HSYNC. Другие соединение не нужны, поскольку порт PA4 сконфигурирован как выход DAC1 и вход ADC1. Форма и спектр сигнала отображаются на LCD. Изменением позиции слайдера пользователь может увидеть форму нового входного сигнала и его спектр, обновляющиеся в реальном времени (см. рис. 7). Рис. 7. Запуск FFT на 1024 точки с входными данными Float-32 на оценочной плате разработчика STM32F746-DISCO. Цель этой демонстрации - устранить сигнал помехи (синусоидальный сигнал 15 кГц) из желаемого сигнала (синусоидальный сигнал 1 кГц), наложив на входные данные разного формата ФНЧ FIR. Когда выбирается формат Q15, можно изолировать сигнал помехи, применив ФВЧ FIR. Блок-схема примера FIR показана на рис. 8. Рис. 8. Блок-схема реализации FIR-фильтра. Код ниже показывает инициализацию для FIR-фильтра плавающей точки (floating-point) и его функцию обработки. // Вызов функции инициализации FIR, которая заполняет поля
// экземпляра структуры фильтра: arm_fir_init_f32(&FIR_F32_Struct, NUM_TAPS, (float32_t *)&aFIR_F32_Coeffs[0], &firStateF32[0], blockSize); for(counter_FIR_f32_p=0; counter_FIR_f32_p=0 < numBlocks; counter_FIR_f32_p++) { arm_fir_f32(&FIR_F32_Struct, aFIR_F32_1kHz_15kHz + (counter_FIR_f32_p * blockSize), aFIR_F32_Output + (counter_FIR_f32_p * blockSize), blockSize); } Инициализацию FIR и обработку других форматов можно найти в исходном файле fir_processing.c. Входные данные для FIR-фильтра это сумма синусоид 1 кГц и 15 кГц (см. рис. 9), которая была сгенерирована в среде MATLAB® в формате данных с плавающей точкой. Для этой цели применялся простой скрипт [4]: % Количество выборок в секунду: Fs = 48000;% Период: T = 1/Fs; % Количество выборок в сигнале: Length=320; t=(0:Length-1)*T; % Генерация входного сигнала: Input_signal = sin(2*pi*1000*t) + 0.5*sin(2*pi*15000*t); Рис. 9. Сгенерированный входной сигнал (сумма двух синусоид 1 кГц и 15 кГц). Магнитуда спектра входного сигнала (рис. 10) показывает 2 частоты 1 кГц и 15 кГц. Рис. 10. Магнитуды спектра входного сигнала. Поскольку шум позиционируется в спектре около 15 кГц, частота среза должна быть установлена на соответствующей более низкой частоте, например на 6 кГц. Дизайн FIR-фильтра. Основные функции фильтра перечислены в таблице 4. Таблица 4. Параметры FIR-фильтра.
ФНЧ был рассчитан также с помощью MATLAB®, следующими командами: % Определение частоты среза фильтра: Cutoff_Freq = 6000; % Частота Найквиста: Nyq_Freq = Fs/2; cutoff_norm = Cutoff_Freq / Nyq_Freq; % Порядок FIR-фильтра: order = 28; % Создание коэффициентов ФНЧ FIR:
FIR_Coeff = firl(order, cutoff_norm);
% Фильтрация входного сигнала FIR-фильтром: Filtered_signal = filter(FIR_Coeff, 1, Input_signal); Примечание: порядок FIR-фильтра равен количеству коэффициентов - 1. Чтобы проверить разработанный фильтр, можно использовать инструмент визуализации данных (Visualization Tool) в MATLAB® с помощью следующей команды: fvtool(FIR_Coeff, 'Fs', Fs);
Инструмент Filter Visualization Tool (FVT) это практическое средство проверки параметров собранного фильтра. На рис. 11 показаны следующие данные (сверху вниз): • Magnitude response (АЧХ фильтра). Рис. 11. Проверка FIR-фильтра с помощью инструментария MATLAB® FVT. Производительность FIR-фильтра. Рис. 12 показывает абсолютное время выполнения и количество потраченных тактов на просчет разработанного выше FIR-фильтра на STM32F429I, работающем на частоте 180 МГц, в то время как рис. 13 показывает результат работы STM32F746, работающего на частоте 216 МГц. Оба примера кода были собраны с использованием тулчейна MDK-Arm™ (5.14.0.0) с поддержкой компилятора языка C V5.05, с оптимизацией Level 3 (-O3) для времени выполнения. Рис. 12. Производительность при обработке FIR-фильтра на STM32F429. Рис. 13. Производительность при обработке FIR-фильтра на STM32F746. Обзор примера реализации FIR-фильтра. Основные функции примера следующие: • Генерируются данные входного сигнала, и они сохраняются в RAM. Результаты на STM32F429I-DISCO. Этот пример рассматривает 2 сценария: 1. ФНЧ FIR, обрабатывающий форматы данных Float-32, Q31 и Q15. Экран осциллографа захватывает 3 разные конфигурации, что показано на рис. 14, слева направо: 1. ФНЧ FIR при обработке данных в формате плавающей запятой (Float-32). Результаты на STM32F746-DISCO. Тот же самый пример FIR-фильтров, результаты показаны на рис. 15, слева направо: 1. ФНЧ FIR при обработке данных в формате плавающей запятой (Float-32). [Обзор DSP-производительности STM32] Одно из назначений этого апноута - показать результаты тестирования производительности на MCU разных серий STM32. Проверялись следующие алгоритмы: • Комплексное FFT по 64 и 1024 точкам (radix-4). Сравнение осуществлялось по времени выполнения (т. е. сколько времени займет обработка алгоритма FFT). Входной вектор данных был сгенерирован в MATLAB® следующими командами: >> Fs=48000; >> T=1/Fs; >> L=1024; >> t=(0:L-1)*T; >> x = sin(2*pi*1000*t) + 0.5*sin(2*pi*15000*t); >> x = x(:);
Результаты сведены в таблицу 5. Код компилировался в среде тулчейна MDK-Arm™ (5.14.0.0) с поддержкой компилятора языка C V5.05, с оптимизацией Level 3 (-O3) для времени выполнения. Таблица 5. Оценка производительности FFT на разных моделях MCU STM32.
[Ссылки] 1. AN4841 Digital signal processing for STM32 microcontrollers using CMSIS site:st.com. |