Paso 4: Salida de Audio estéreo con DAC de 8 bits y frecuencia de muestreo de 44,1 kHz
En este código estoy enviando una onda sinusoidal a DACA y una onda de sierra a DACB al mismo tiempo y a una tasa de 44.1 kHz. Se trata de audio estéreo, dos canales independientes de audio. Para conseguir que funcione, había combinado seno elementos y VI código mono desde el último paso y utiliza los pernos WR y DACA/DACB para alternar entre las dos salidas DAC.
Configurar una interrupción como en el ultimo paso, pero esta vez la puse a una velocidad de 2 * 44.1 = 88,2 kHz. Entonces cada vez que la interrupción que se ejecuta, alternaba entre mandando algo a DACA y DACB, por lo que cada uno recibió una muestra durante cada interrupción de otros. Esto hace que la frecuencia de muestreo en ambas las salidas 44.1 kHz. El contenido de la rutina de interrupción se copia a continuación:
digitalWrite (WR, alto); //hold salidas-para que nuevos datos de CAD no Haz enviados hasta que estemos listos
Si {} (canal)
PORTD = seno [índice]; seno //send a los pines digitales 0-7
digitalWrite (outputSelector, LOW); //select DACA
Índice ++; valor de índice de //increment por uno
Si (índice == 100) {índice de //reset si llega a 100
índice = 0;
}
}
Else {}
PORTD = Sierra; //send vio a los pines digitales 0-7
digitalWrite (outputSelector, HIGH); //select DACB
Sierra ++; //increment Sierra valor por uno
Si (VI == 255) {//reset vio si llega a 256 (salida mantiene dentro siempre de 0-255)
VI = 0;
}
}
digitalWrite (WR, LOW); //enable la salida otra vez
canal ^ = 1; //toggle canal
Cuando las interrupciones, los conjuntos de Arduino el WR perno alto, temporalmente tiene las salidas DAC en sus tensiones actuales y nos permite enviar datos en CAD sin necesidad de cambiar la salida DAC seleccionado actual. La variable "canal" alterna entre valores de 0 y 1 cada vez que la interrupción se ejecuta alternando el seno y salida de la sierra. Cuando el "canal" = 1, se establece un valor de la matriz "seno" a la DAC por PORTD. La siguiente línea establece el outputSelector pin (pin DACA/DACB) bajo, que DACA que se seleccionarán. Entonces WR se encuentra baja, causando el nuevo valor del seno a través de DACA. En la siguiente rutina de interrupción, una serie similar de eventos provoca un valor de sierra a la salida de la DACB.
<pre>//stereo audio out, sampling rate <=44.1kHz //by Amanda Ghassaei //Nov 2012
Como en el ultimo paso, mi tasa de muestreo no fue precisamente 88.2 kHz, fue realmente 88,398 kHz (ligeramente mejor que 88.2), así que usaré ese número en los siguientes cálculos:
duración de cada muestra = 2 * 1/velocidad de muestreo
duración de cada muestra = 2 * 1/88398 Hz = 22.6us
al igual que en el último paso el período de los seno y la sierra son las siguientes:
VI periodo = 22.6us * 256 = 5.8ms
período de seno = 22.6us * 100 = 2.3ms
pero si observas higos 2 y 3 veremos en que la duración de la muestra y período de las ondas de salida es mucho más largo. Esto es porque el código en la rutina de interrupción es ineficiente y está tomando más de 22.6us para ejecutar. Para solucionarlo tuve que reemplazar el comando Arduino de la biblioteca "digitalWrite" con comandos de manipulación directa pin mucho más eficientes en el código siguiente. Puedes leer más sobre como funcionan aquí, también puede leer los comentarios me he puesto en el código siguiente. Higos 4 y 5 muestran las salidas de este código optimizado, se puede ver que la duración del período y muestra es lo que esperamos de los cálculos.
<pre>//stereo audio out with 44.1kHz sampling rate //by Amanda Ghassaei //Nov 2012
Te observo también, que desde el CS pin se mantiene baja para la duración de este código (ajuste alto se desactivará escribir datos nuevos en cada salida), puede liberar un pin adicional de Arduino por CS a tierra permanentemente y eliminar las instancias del CS en el código de Arduino.