Цифро-аналоговое преобразование с использованием Cordic - PullRequest
0 голосов
/ 10 сентября 2018

Я новичок с ЦАПами, но в основном у меня FPGA (DE1-SOC) под управлением Linux. К нему подключен ЦАП LTC2607. Все работает гладко, пока Linux распознает ЦАП через I2C и все такое.

Мой вопрос касается того, как генерировать синусоидальную форму волны, используя кордный алгоритм. У меня есть алгоритм, который выводит массив из 16 шестнадцатеричных значений.

{0x00003243, 0x00001DAC, 0x00000FAD, 0x000007F5 и т. Д. ...}

Код, который запускает I2c / DAC, принимает 16-битный «код ЦАП», который затем преобразуется в аналоговый выход:

uint16_t LTC2607_code(float dac_voltage, float LTC2607_lsb, float LTC2607_offset)
{
  uint16_t dac_code;
  float float_code;
  float_code = (dac_voltage - LTC2607_offset) / LTC2607_lsb;                                      // Calculate the DAC code
  float_code = (float_code > (floor(float_code) + 0.5)) ? ceil(float_code) : floor(float_code);   // Round
  if (float_code >= 65535.0)                                                                      // Limits the DAC code to 16 bits
    float_code = 65535.0;
  dac_code = (uint16_t) (float_code);                                                             // Convert to unsigned integer
  return (dac_code);
}

Я знаю, что для прямого цифрового синтеза необходимо «интерполировать» точки (уровни напряжения) вдоль синусоиды. Я думаю, что я бы отправил эти значения по I2C, один за другим, и как бы быстро эти 16 шестнадцатеричных значений не передавались по I2C (задается тактовыми частотами Master (FPGA) @ ~ 10 МГц), это какая частота синусоидальной волны будет?

Код для записи в ЦАП следующий:

int8_t LTC2607_write(uint8_t i2c_address, uint8_t dac_command, uint8_t dac_address, uint16_t dac_code)
{
    int fd;
    int ret;
    char *device;
    uint8_t command_byte;
    uint8_t buffer[3];

    command_byte = dac_command | dac_address; // Build the DAC command byte

    // Open the I2C device
    device = LTC2607_get_device_name();
    fd = open(device, O_RDWR);
    if (fd < 0)
    {
        return (1);
    }

    // Select the desired address
    ret = ioctl(fd, I2C_SLAVE, i2c_address);
    if (ret < 0)
    {
        close(fd);
        return (1);
    }

    // Build the I2C command
    buffer[0] = command_byte;
    buffer[1] = (dac_code >> 8) & 0xFF;
    buffer[2] = dac_code & 0xFF;

   // Write the command to the I2C bus
   ret = write(fd, buffer, 3);
   if (ret < 3)
   {
     close(fd);
     return (1);
   }

   // Close the device
   close(fd);

   return (0);
 }

Как бы я преобразовал эту строку из 16 шестнадцатеричных значений в синусоиду, используя вышеупомянутую функцию LTC2607_write?

...