Generación de ondas sinusoidales dentro del rango audible usando un DAC

0

Estoy intentando generar una onda sinusoidal de hasta 20 khz con el TLC5615 DAC pero Solo se han podido obtener un máximo de 100 hz. Estoy utilizando una MCU atmega328 de 20 MHZ para transferir los 16 bits necesarios (2 rellenos, precisión de 10 bits, 4 bits ficticios) y también para actuar como el reloj definido por software para el dispositivo. Para generar la onda sinusoidal, tengo una tabla de búsqueda con ~ 64 valores para obtener una onda sinusoidal decente.

Aquí está todo el código

int sine[] = {0x7fc ,0x868 ,0x8d4 ,0x93c ,0x9a8 ,0xa10 ,0xa78 ,0xadc 
,0xb3c ,0xba0 ,0xbfc ,0xc58 ,0xcb0 ,0xd04 ,0xd58 ,0xda4 ,0xdf0 ,0xe34 ,0xe74 
,0xeb0 ,0xee8 ,0xf1c ,0xf4c ,0xf74 ,0xf98 ,0xfb8 ,0xfd0 ,0xfe4 ,0xff0 ,0xff8 
,0xffc ,0xff8 ,0xff0 ,0xfe4 ,0xfd0 ,0xfb8 ,0xf98 ,0xf74 ,0xf4c ,0xf1c ,0xee8 
,0xeb0 ,0xe74 ,0xe34 ,0xdf0 ,0xda4 ,0xd58 ,0xd04 ,0xcb0 ,0xc58 ,0xbfc ,0xba0 
,0xb3c ,0xadc ,0xa78 ,0xa10 ,0x9a8 ,0x93c ,0x8d4 ,0x868 ,0x7fc ,0x794 ,0x728 
,0x6bc ,0x654 ,0x5ec ,0x584 ,0x520 ,0x4bc ,0x45c ,0x400 ,0x3a4 ,0x34c ,0x2f4 
,0x2a4 ,0x258 ,0x20c ,0x1c8 ,0x188 ,0x148 ,0x110 ,0xe0 ,0xb0 ,0x88 ,0x64 ,0x44 
,0x2c ,0x18 ,0xc ,0x0 ,0x0 ,0x0 ,0xc ,0x18 ,0x2c ,0x44 ,0x64 ,0x88 ,0xb0 ,0xe0 
,0x110 ,0x148 ,0x188 ,0x1c8 ,0x20c ,0x258 ,0x2a4 ,0x2f4 ,0x34c ,0x3a4 ,0x400 
,0x45c ,0x4bc ,0x520 ,0x584 ,0x5ec ,0x654 ,0x6bc ,0x728 ,0x794};

#define samples 120

#define intL 16

void setup(){

  pinMode(11,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(13,OUTPUT);
}


int j = 0;
int k = intL-1;

unsigned int cval = 0;
int current = 0;

byte currentBit = 0;

void loop(){

  PORTB = B00000000;

   cval = sine[j];

  while(k != 0)
  {
    currentBit = (cval >> k) & 1;

    if(currentBit)
    {
      PORTB = B00010000;
      PORTB = B00110000;
      PORTB = B00010000;
    }
    else
    {
      PORTB = B00100000;
      PORTB = B00000000;
    }



      k--;
  }

   PORTB = B00001000;

  k=intL-1;

  j++;

  if(j == samples)
  {
    j = 0;
  }
}

Dentro del método de bucle mantengo un contador del valor actual de la onda. También mantengo un contador del bit actual que debe escribirse y para escribir en orden LSb, ese contador tiene que contar hacia atrás. Luego cambio la palabra por esa cantidad especificada. Después de que conozco el valor, disparo el reloj, escribo el valor y configuro el reloj una vez más. Después de que la palabra haya sido cambiada a la DAC, debe conducir la entrada de Selección de Chip a un nivel alto.

Me temo que esto tiene que ver con el rendimiento, ya que podría usar el método de búsqueda, así que me gustaría saber si hay alguna alternativa o lo que necesito para lograr frecuencias de ~ 20 khz.

    
pregunta AlanZ2223

1 respuesta

3

Si desea obtener señales de 20 kHz, debe hacer al menos 3 cosas.

El primero es obtener 50k / s o más de transferencia a su DAC. Eso significa ejecutar el reloj SPI a alrededor de 1MHz o más. Leyendo entre líneas, el DAC debe poder aceptar al menos un reloj SPI de 10MHz. El desafío es encontrar la biblioteca de MCU que puede transmitir SPI a 1MHz.

El segundo es generar muestras sinusoidales a la velocidad correcta. Después de haber guardado 64 muestras de una onda sinusoidal en su mesa, no necesita pasar por ellas una por una, puede hacer 2 pasos a la vez o más. De hecho, si generara una señal de 20 kHz a una frecuencia de muestreo de 50 kHz, estaría avanzando 0.4 de un círculo = 144 grados = aproximadamente 25 pasos de una tabla de 64 entradas.

Para una manera de hacerlo sin tablas, busque CORDIC. Debería encontrar que un atmega328 de 20MHz sea lo suficientemente rápido para hacerlo.

La tercera cosa es diseñar y construir un filtro anti-alias para ir tras su DAC, que debe pasar el fmax de 20kHz, y bloquear todas las frecuencias desde (samples_rate - fmax) hacia arriba. Con una frecuencia de muestreo de 50 kHz, es un pase de 20 kHz, bloque de 30 kHz y superior. Puede facilitar el requisito de inclinación del filtro aumentando la frecuencia de muestreo. A 100 kHz, solo necesitarías bloquear las frecuencias por encima de 80 kHz, un filtro mucho más fácil de construir.

Algunos DAC de audio se muestrean en exceso dentro del DAC con filtros digitales para hacer las cosas mucho más fáciles. El DAC que ha citado no hace esto.

    
respondido por el Neil_UK

Lea otras preguntas en las etiquetas