Детектор Tayloe и цифровая обработка сигналов #5 анализ результата преобразования АЦП на ПК

Автор: | 23.10.2025

Начинается тернистый путь освоения цифровой обработки сигналов — ЦОС, по буржуйскому DSP!

Я планирую использовать АЦП STM32H723ZGT6 для оцифровки сигналов I/Q от SDR стенда, который собрал на предыдущих этапах, в данной стмке очень неплохой 16-битный АЦП, вот картинка измерений 16-битного АЦП от ST

И вот от них же сравнение серий F7 и H7

Цель подать сигнал на один из входов АЦП, и для его анализа использовать подключение по USB как VirtualComPort на ПК, а скриптом Python смотреть спектр оцифрованного сигнала и собирать WAV файл для анализа в программах, например как SpectraPLUS. Таким образом мы увидим именно то, что оцифровывает АЦП.

Для данного примера буду использовать платку с STM32F401CCU6.

Тут есть все, что надо и 12-бит АЦП, правда для SDR это далеко не самый лучший вариант, и USB интерфейс.

В STM32CubeIDE создаем новый проект с нашим чипом, включаем тактирование и отладку

На вкладке Clock Configuration настраиваем следующим образом

Тут видим, что шины тактирования таймеров настроены на частоту 84 МГц. АЦП стмки будем тактировать от таймера TIM2 с частотой дискретизации Fs = 48 кГц. Для этого настроим таймер соответствующим образом

Почему именно такие значения прескалера и счетчика таймера? Нам нужен таймер, который выдаёт событие (TRGO) с частотой 48 000 Гц, т.е. один триггер каждые

T = 1/48000 = 20.833 мкс.

Таймер работает так

48000 = 84000000/((PSC+1)*(ARR+1))

где PSC — прескалер, ARR — счетчик, самые подходящие комбинации PSC = 34, ARR = 49, тогда

84000000/((34+1)*(49+1)) = 84000000/1750 = 48000

то, что нам и надо!

Далее настроим АЦП

И настроим DMA АЦП

Смотрим на каком пине у нас вход АЦП

Теперь настроим коммуникацию с ПК, а именно USB порт стмки, чтобы он определялся в системе как VirtualComPort

Тут среда ругается на клоки

Исправляем ситуацию, кликаем Ok, и кликаем по голубой кнопке Resolve clock issues, выставляем опять максимальную частоту 84 МГц

Теперь все в порядке.

Включаем режим USB как VirtualComPort

При выборе режима работы USB можно обратить внимание, что в списке есть Audio Device Class. Т.е. платка может работать на ПК как аудиоустройство, вроде внешней аудиокарты, казалось бы подключил к ПК и завел аудиопоток сразу в программу для анализа, но тут не все так просто, как говориться из коробки это работать не будет. Об этом в следующий раз, и по итогу мне надо, чтобы устройство определялось и как виртуальный COM порт для дальнейшего CAT управления и как аудиоустройство с входом и выходом, т.е. композитный USB.

Собираем проект, прошиваем платку, подключаем платку к ПК по USB и наблюдаем как у нас появился COM порт

Замечательно!

Теперь напишем обработку данных от АЦП и отправку их в USB порт. Для этого создадим два файла adc.h и adc.c. В них и будем кодить.

В файле adc.h опишем наши определения, а именно размер буфера данных АЦП и прототип функции инициализации

В файле adc.c опишем наши объявления, внешние определения

и сами функции

В функции void ADC_DMA_Init(void) мы запускаем таймер TIM2 и непрерывное преобразование АЦП, буфер АЦП заполняется через DMA в цикле не мешая основному циклу программы, но у нас он тут и не используется.

В функции void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) мы по событию от DMA что первая половина буфера АЦП заполнена, передаем готовые данные в USB.

В функции void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) мы по событию от DMA, что вторая половина буфера АЦП заполнена, передаем очередную порцию результата преобразования АЦП в USB.

Теперь в файле main.c подключаем наши файлы

и в секции int main(void) добавляем вызов функции инициализации АЦП

Собираем проект и прошиваем платку. Теперь нам надо чтобы пин АЦП не болтался в воздухе, обычно подключают так

Через конденсатор делителем нормализуем сигнал на входе АЦП в районе 1,65v.

Далее используя скрипт среды Python можем посмотреть, что там оцифровывает наш АЦП. Для этого необходимо установить среду Python и необходимые библиотеки, а именно:

  • numpy — работа с массивами, FFT;
  • matplotlib — отрисовка спектра.

В скрипте надо указать номер COM порта на котором определилась платка стмки

На вход АЦП ничего не подаем, смотрим, что получилось

вот тут мы видим реальный шум ацп стмки, а пик в районе 4 кГц это скорее всего помеха по питанию от USB ноутбука. Далее через звуковую карту ноутбука я подаю на вход АЦП сигнал частотой 1 кГц и уровнем -0,5 дБ, смотрим

Результат ожидаем, и хорошо видно постоянную составляющую на 0 Гц.

Скрипт во время работы собирает WAV файл capture.wav, открываем его в SpectraPLUS

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

В архиве проект под STM32CubeIDE 1.19.0 и скрипт Python с BAT файлом для запуска скрипта.

Продолжение следует…

73!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *