Начинается тернистый путь освоения цифровой обработки сигналов — ЦОС, по буржуйскому 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
то, что нам и надо!
Далее настроим АЦП
Смотрим на каком пине у нас вход АЦП
Теперь настроим коммуникацию с ПК, а именно 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!











