STM32 быстрое преобразование Фурье.

STM32 быстрое преобразование Фурье.

Давно хотелось прикрутить к осциллографу, который описывал тут, преобразование Фурье, но почему-то руки не доходили. Совсем недавно, месяц назад решил увеличить частоту сэмплирования ослика, заменив stm32F103VE с частотой сэмплирования 1М на stm32F303VC c частотой сэмплирования 5М. После замены чипа и изменения программы решил всё-таки разобраться с быстрым преобразованием Фурье(БФП или FFT).

Можно попробовать написать БФП самому, но это займет много времени, поэтому решил воспользоваться библиотекой CMSIS-DSP, но теорию всё-таки пришлось подтянуть.

У нас есть АЦП, которое с некоторой частотой отдаёт нам результаты преобразования. Мы накапливаем эти результаты в буфер перед тем, как подать их на вход БФП. Размер буфера должен быть кратен степени двойки и содержать 128(2 в 7),256(2 в 8) отсчётов и тд.
От количества точек, участвующих в БФП, зависит разрешающая способность.
Для нахождения шага между гармониками мы просто делим частоту дискретизации на количество точек, участвующих в БФП. Если при частоте дискретизации 512KHz в БФП участвует 256 точек, мы получим амплитуды гармоник с шагом 2КHz. Если же точек будет 512, то получим амплитуды гармоник с шагом 1КHz.
И ещё один пример для закрепления.
Например, при частоте дискретизации 1MHz и количестве точек 1024, спектральный отсчёт с номером 512 будет соответствовать частоте 500KHz.
STM32 быстрое преобразование Фурье.


Как писалось выше, на вход БФП мы подаём вещественный сигнал, то есть данные полученные с АЦП, а на выходе получим комплексные числа, причём их будет в два раза больше. С теорией всё, предлагаю перейти непосредственно к реализации БФП на STM32.

Для начала надо подключить библиотеку и включить поддержку FPU.
STM32 быстрое преобразование Фурье.

STM32 быстрое преобразование Фурье.

Теперь можно приступать к написанию программы. Код представленный ниже для STM32F303.

#define ARM_MATH_CM4// указываем на каком ядре построен МК
#include <arm_math.h> //подключаем библиотеку
#define FFT_SIZE 256//указываем размер FFT

//Создаём два буфера, в одном будем хранить выборки АЦП, во втором результаты БФП
q15_t fft_Sbuff[FFT_SIZE] = {0};
q15_t fft_Dbuff[FFT_SIZE*2] = {0};

uint16_t k;
uint8_t status;
arm_rfft_instance_q15 S;
		
status = arm_rfft_init_q15(&S, FFT_SIZE, 0, 1);//функция инициализации необходима для БФП
if(status == ARM_MATH_SUCCESS)
{	
    arm_rfft_q15(&S,fft_Sbuff, fft_Dbuff);//выполнение БФП
    arm_cmplx_mag_q15(fft_Dbuff, fft_Sbuff, FFT_SIZE);//вычисляем амплитуды гармоник
}


Надо отметить, что формат входных и выходных данных отличается, как показано в таблице.
STM32 быстрое преобразование Фурье.

Это надо учитывать при построении графика.

Вот, что получилось в итоге.
STM32 быстрое преобразование Фурье.

STM32 быстрое преобразование Фурье.

Хотелось бы напомнить, что результат БФП вещественного сигнала симметричен относительно нулевой частоты и на дисплей выведена только половина спектральных отсчётов(с 0 по 128).
комментарии
0