В одном из видео на канале OpenTechLab рассказывалось о плате под названием Alinx AN108. Плата предназначена для использования совместно с FPGA. Она объединяет в себе АЦП на базе чипа AD9280 (8 bit, 32 Msps, даташит [PDF] ), а также ЦАП на базе AD9708 (8 bit, 100 Msps, даташит [PDF] ). Цена устройства составляет около 20$, на eBay его можно найти по запросу «fpga ad da». Плата показалась мне довольно интересной. Поэтому я решил обзавестись такой же и повторить эксперименты из видео.
Примечание: Если вдруг вы пропустили заметку Генерация синусоидального сигнала, а следовательно и звука, на FPGA , то в ней рассказывалось, как самостоятельно спаять ЦАП на основе R-2R лестницы и операционного усилителя . Что же касается BlackIce II, с этой платой мы познакомились в рамках поста Изучаем BlackIce II, отладочную плату с STM32 и ICE40 .
Alinx AN108 имеет разъем в форме 2 x 17 гнезд с шагом 2.54 мм. Это не самый удобный разъем для подключения к BlackIce II. поэтому мной была спаяна небольшая плата-адаптер, позволяющая подключать Alinx AN108 с помощью трех Pmod-разъемов:
Поскольку не у всех продавцов можно найти описание, какое гнездо платы для чего нужно, я приведу эту информацию здесь:
- Гнезда 1 и 2 — DCOM и VCC, земля и питание платы соответственно. Для нормальной работы плате нужно 5 В. Поскольку на Pmod-разъемы выведено только 3.3 В, мне пришлось использовать дополнительный проводочек. Его не трудно найти на фото;
- Гнездо 5 — DACLK, тактовый сигнал для ЦАП;
- Гнезда 6-13 — DADB7, DADB6, …, DADB0. Шина данных ЦАП;
- Гнезда 21-28 — ADDB0, ADDB1, …, ADDB7. Шина данных АЦП;
- Гнездо 29 — ADCLK, тактовый сигнал для АЦП;
- Все остальные гнезда ни для чего не используются;
Работать с платой крайне просто. Например, если мы хотим пробросить сигнал с АЦП в ЦАП без изменений, это делается так:
// icepll -i 100 -o 32
SB_PLL40_CORE # (
.FEEDBACK_PATH ( «SIMPLE» ) ,
.PLLOUT_SELECT ( «GENCLK» ) ,
.DIVR ( 4’b0011 ) ,
.DIVF ( 7’b0101000 ) ,
.DIVQ ( 3’b101 ) ,
.FILTER_RANGE ( 3’b010 ) ,
) uut (
.REFERENCECLK ( CLK100MHz ) ,
.PLLOUTCORE ( CLK32MHz ) ,
.LOCK ( LD1 ) , // keep this!
.RESETB ( 1’b1 ) ,
.BYPASS ( 1’b0 )
) ;
assign AD_CLK = CLK32MHz ;
assign DA_CLK = CLK32MHz ;
assign DA = 8’b11111111 — AD ;
Обратите внимание на последнюю строчку. Дело в том, что при изучении платы был обнаружен небольшой нюанс. Как и следовало ожидать, чем выше входной сигнал у АЦП, чем большее значение придет в FPGA. Но при этом у ЦАП все наоборот — чем большее значение мы подаем из FPGA, тем меньше выходной сигнал ЦАП. Поэтому, если требуется пробросить сигнал как есть, оцифрованные значения необходимо инвертировать.
Пример того, как выглядят вход и выход в осциллографе (вход на первом канале, выход на втором):
Для получения входной синусоиды был использован генератор сигналов MHS-5200A . Он способен генерировать сигналы разной формы с частотой до 25 МГц. Устройство является двухканальным. Его можно без труда найти на eBay и AliExpress. Кстати, про MHS-5200A я узнал все из того же видео от OpenTechLab. Легко заметить, что сигнал на втором канале слегка искажен (сравните амплитуду) и отстает от оригинального. Оба эффекта были вполне ожидаемы.
Плату Alinx AN108 не обязательно использовать именно для обработки сигналов. Например, используя только ЦАП, можно получить относительно неплохой генератор сигналов. Пример конфигурации:
logic [ 7 : 0 ] counter = 255 ;
always @ ( negedge CLK100MHz )
begin
counter <= counter — 1 ;
end
assign DA = counter ; // ~ 390.6 kHz
Полученный сигнал в осциллографе:
Помним, что сигнал на выходе увеличивается с уменьшением значения counter
.
Само собой разумеется, ничто не мешает использовать в одном проекте сразу несколько плат. Таким образом, можно собрать генератор сигналов, имеющий много каналов. Или какой-нибудь музыкальный микшер. Еще можно прикрутить дисплей на базе ILI9341 и сделать небольшой осциллограф или анализатор спектра. Наконец, используя АЦП совместно с тюнером R820T2 , можно собрать самый настоящий Software Defined Radio.
Полную версию исходников к этому посту вы найдете на GitHub .