Микронтроллеры STM32: работа с DDS-синтезатором AD9850

9 мая 2022

Ранее в этом блоге приводилось множество проектов на основе Si5351. Могло сложится впечатление, что это единственный подобный чип, по крайней мере, из бюджетных. На самом деле, это не так. Другим популярным выбором среди радиолюбителей является синтезатор частот AD9850. Давайте же разберемся, каковы его плюсы и минусы.

AD9850 продается на AliExpress и eBay в виде готовых модулей:

Модуль на основе AD9850

На момент написания статьи цена модуля составляла 10-12$, против 2-3$ за модуль на Si5351.

Подробное описание AD9850 и его протокола доступно в даташите [PDF]. Синтезатор допускается питать напряжением 3.3 В или 5 В. Он понимает и такую, и такую логику. Максимальная синтезируемая частота — 33% от частоты опорного генератора. Последняя составляет 125 МГц, значит выход ограничен 41.25 МГц. Синтезатор одноканальный. Выходной импеданс составляет минимум 50 кОм, типично 120 кОм.

Fun fact! Существуют такие же модули на основе AD9851 (даташит [PDF]). AD9851 аналогичен AD9850, но использует опорный генератор 180 МГц и способен выдавать до 40% от этой частоты. Таким образом, максимальная синтезируемая частота AD9851 составляет 72 МГц.

AD9850 поддерживает два протокола — параллельный и последовательный. Обычно используют последовательный, потому что ему нужно меньше пинов. Протокол очень простой:

#define AD9850_WCLK_GPIO GPIOA
#define AD9850_WCLK_PIN GPIO_PIN_0

#define AD9850_FQUD_GPIO GPIOA
#define AD9850_FQUD_PIN GPIO_PIN_1

#define AD9850_DATA_GPIO GPIOA
#define AD9850_DATA_PIN GPIO_PIN_2

#define AD9850_RESET_GPIO GPIOA
#define AD9850_RESET_PIN GPIO_PIN_3

void AD9850_Init() {
  // set all pins low
  HAL_GPIO_WritePin(AD9850_WCLK_GPIO, AD9850_WCLK_PIN,
    GPIO_PIN_RESET);
  HAL_GPIO_WritePin(AD9850_FQUD_GPIO, AD9850_FQUD_PIN,
    GPIO_PIN_RESET);
  HAL_GPIO_WritePin(AD9850_DATA_GPIO, AD9850_DATA_PIN,
    GPIO_PIN_RESET);
  HAL_GPIO_WritePin(AD9850_RESET_GPIO, AD9850_RESET_PIN,
    GPIO_PIN_RESET);

  // pulse reset
  HAL_GPIO_WritePin(AD9850_RESET_GPIO, AD9850_RESET_PIN,
    GPIO_PIN_SET);
  HAL_Delay(1);
  HAL_GPIO_WritePin(AD9850_RESET_GPIO, AD9850_RESET_PIN,
    GPIO_PIN_RESET);

  // pulse clock
  HAL_GPIO_WritePin(AD9850_WCLK_GPIO, AD9850_WCLK_PIN,
    GPIO_PIN_SET);
  HAL_Delay(1);
  HAL_GPIO_WritePin(AD9850_WCLK_GPIO, AD9850_WCLK_PIN,
    GPIO_PIN_RESET);

  // pulse fqud
  HAL_GPIO_WritePin(AD9850_WCLK_GPIO, AD9850_FQUD_PIN,
    GPIO_PIN_SET);
  HAL_Delay(1);
  HAL_GPIO_WritePin(AD9850_WCLK_GPIO, AD9850_FQUD_PIN,
    GPIO_PIN_RESET);
}

void AD9850_WriteByte(uint8_t byte) {
    uint8_t i;
    for(i = 0; i < 8; i++) {
        if((byte >> i) & 1) {
          HAL_GPIO_WritePin(AD9850_DATA_GPIO, AD9850_DATA_PIN,
            GPIO_PIN_SET);
        } else {
          HAL_GPIO_WritePin(AD9850_DATA_GPIO, AD9850_DATA_PIN,
            GPIO_PIN_RESET);
        }

        HAL_GPIO_WritePin(AD9850_WCLK_GPIO, AD9850_WCLK_PIN,
          GPIO_PIN_SET);
        HAL_GPIO_WritePin(AD9850_WCLK_GPIO, AD9850_WCLK_PIN,
          GPIO_PIN_RESET);
    }
}

void AD9850_SetFrequency(uint32_t freq) {
  // don't forget to add '-u _printf_float' to LDFLAGS
  uint32_t tuningWord = 4294967296*(((double)freq)/125000000);

  AD9850_WriteByte((tuningWord >> 0) & 0xFF);
  AD9850_WriteByte((tuningWord >> 8) & 0xFF);
  AD9850_WriteByte((tuningWord >> 16) & 0xFF);
  AD9850_WriteByte((tuningWord >> 24) & 0xFF);
  AD9850_WriteByte(0);

  HAL_GPIO_WritePin(AD9850_FQUD_GPIO, AD9850_FQUD_PIN,
    GPIO_PIN_SET);
  HAL_GPIO_WritePin(AD9850_FQUD_GPIO, AD9850_FQUD_PIN,
    GPIO_PIN_RESET);
}

void init() {
  AD9850_Init();
  AD9850_SetFrequency(1000000);
}

// ...

В результате выполнения кода на пинах ZOUT1 и ZOUT2 мы увидим:

Синусоидный сигнал, генерируемый AD9850

Сигнал один и тот же, но с фазовым сдвигом 180°. Обратите внимание на постоянную составляющую.

Еще с пинов QOUT1 и QOUT2 можно получить меандры:

Меандр, генерируемый AD9850

Скважность регулируется при помощи потенциометра на модуле.

В радиолюбительском деле AD9850 кажется не слишком удобным. Его выход нужно фильтровать, усиливать и согласовывать с 50 Ом. Модули на Si5351 при меньшей стоимости дают сразу 3 канала, сигнал приличного уровня, покрывают куда больший интервал частот и обладают большей гибкостью. А еще Si5351 использует I2C и этим экономит пины МК. Тем не менее, знать о возможностях и ограничениях AD9850 (или AD9851) не повредит. Вдруг в каком-то проекте понадобится именно такой синтезатор.

Метки: , .