Convertidor Digital - Analógico con PWM

 

Hay proyectos en los que tenemos que controlar el nivel de voltaje como: la referencia de una fuente regulada, la salida de audio, o bien queremos hacer nuestro generador de funciones. Pero estas señales son analógicas y la mayoría de los microcontroladores de gama baja y media (PICs, AVRs, etc) no tienen un convertidor DAC.

 

Una solución muy frecuente es usar un circuito DAC (convertidor digital analógico) aparte del micro controlador, lo que es muy útil, pero tiene dos inconvenientes: es un circuito mas, lo que es mas espacio y costo, aparte de que puede requerir muchas lineas de señales por parte de nuestro procesador, en el caso de que la interfaz sea paralela.

 

Pero todos los microcontroladores tienen por lo menos un timer y en la mayoria de los casos se puede usar como un modulador de ancho de pulso (PWM)

 

En el caso de que se cuente con estos recursos. se puede usar el timer/PWM para hacer conversiones de digital a analogico usando un arreglo de una resistencia, un capacitor y un amplificador operacional.

 

 
El circuito es un filtro pasabaja de primer orden y el amplificador operacional sirve para evitar que se caiga el voltaje de salida debido a la carga que le coloquemos.

 

Sin adentrarnos mucho en el tema, los filtros pasabaja dejan pasar las señales con frecuencia menor a la frecuencia de corte. En pocas palabras, de la frecuencia de corte para abajo. Para calcular la frecuencia de corte, en este caso se puede usar la siguiente formula f_0 = \frac{1}{2 \pi RC}

 

 
Esta frecuencia de corte es importante, ya que nos da la pauta de las frecuencias que podemos suministrar como señal de salida analógica. Es decir, si nuestra frecuencia de corte es de 1000Hz, con nuestro dac pwm podemos sacar frecuencias menores de 1000Hz, por ejemplo podemos sacar senoidales a 600Hz sin problema.

 

Ahora bien, ya tenemos la frecuencia de corte, pero hace falta otra frecuencia importante a considerar, que es la frecuencia del PWM. La frecuencia del pwm es la que usara el timer para generar la señal de salida analógica. No podemos elegir una frecuencia de pwm menor que la frecuencia de corte del filtro, ya que prácticamente solo veríamos la señal del timer. Tampoco podemos igualarla con la de corte ya que la señal de salida presentaría mucho ruido debido a que la atenuación empieza en la frecuencia de corte, es decir, todavía veríamos la señal del timer en la salida analógica.

 

Asi, debemos elegir una frecuencia de pwm mucho mayor que la frecuencia de corte, para asegurar que la frecuencia del timer no llegue a la salida de nuestro convertidor ya que estaría muy atenuada según nuestro filtro.

 

En lo personal me ha funcionado bien el convertidor cuando he elegido frecuencias de pwm por lo menos 20 veces mas alta que la frecuencia de corte. De hecho, generalmente empezaremos viendo cual es la frecuencia máxima de pwm que podemos tener en el timer/pwm y de allí propondremos la frecuencia de corte. Al final del día, la velocidad del microprocesador es nuestro limite.

 

Ejemplo de aplicación

 

Para ilustrar un poco sobre como es el procedimiento de diseño, vamos a implementar un pequeño ejemplo usando un micro controlador AVR. El modelo que vamos a usar es el ATmega8, ya que cuenta con varios timers que podemos usar.

 

Como habíamos comentado anteriormente, la velocidad del procesador sera nuestro eje de diseño, asi que empecemos…

 

El procesador tendrá una frecuencia de operación de 8 MHz, que pueden ser generados internamente o, de preferencia, a través de un cristal. Esto significa que el timer que elijamos tendrá una frecuencia de operación también de 8 MHz. Los timers del avr tienen un “prescaler”, que en otras palabras es un divisor de la frecuencia principal. Dejaremos que trabaje al máximo posible para tener el mayor ancho de banda disponible (frecuencias que podremos generar con el convertidor DAC) por lo que dejaremos el prescaler con división de 1.

 

Ahora bien, usaremos el timer2 ya que es muy sencillo de usar, ya que es de 8 bits y tiene un modo de trabajo llamado “fast pwm” en donde hay un registro de comparación. La forma de trabajo de este modo es el siguiente: la frecuencia del reloj principal alimenta el timer, contado de manera ascendente. También se configura un pin como salida de comparación, que de hecho sera nuestra señal que alimentara al filtro pasabajas. Cuando el registro de conteo se resetea a cero, la salida de comparación se pondrá a 1 lógico (5V) y mientras el contador sea menor que el registro de comparación, la salida continuara en ese estado. El registro de comparación seguirá incrementándose a cada pulso de reloj, cuando el registro de conteo alcance al registro de comparación, la salida invertirá la señal, es decir tendrá un cero logico (GND) y continuara así hasta que el contador se reinicie (pase de 0xFF -> 0x00), donde el proceso vuelve a empezar.

 

Como el contador es de 8 bits la frecuencia máxima de salida que podremos tener para el filtro pasabajas será de f_{pwm} = \frac{f_{osc}}{N 256} con f_{osc} = 8MHz y con N = 1 ya que N es el valor puesto en el prescaler, en este caso, sin división. Lo que nos da un total de 31250Hz como fpwm.

 

Ahora bien, ya tenemos la frecuencia del pwm. Como comentábamos hace poco, la frecuencia del pwm debe ser mas grande que la frecuencia de corte del filtro pasa bajas, así que ahora haremos la frecuencia de corte lo suficientemente baja para que la frecuencia de pwm no se vea en la salida. Si seguimos nuestro propio consejo de  que la frecuencia de pwm sea por lo menos 20 veces mayor que la frecuencia de corte del filtro, entonces nuestra frecuencia de corte será 31250/20=1562.5Hz máximo.

 

Para el diseño del filtro pasabajas, la formula requiere de 2 variables, así que propondremos una y obtenemos el valor de la otra por medio de la formula. Vamos a proponer el valor del capacitor, ya que en el peor caso un arreglo de resistencias es mas fácil de armar que un arreglo de capacitores. Ta formula entonces será R=\frac{1}{2\pi 1562.5 C} y si proponemos un valor de capacitancia de 100nF la resistencia resultante es de 1018.59 ohm. Redondeando esta cantidad a 1k ohm la frecuencia que resultaría es de 1591.5 Hz que no esta mal ni muy alejado de lo que pretendíamos como ideal.

 

Bien, ya tenemos los valores de resistencia y capacitancia de 1k ohm y 100nF respectivamente. Lo siguiente es el amplificador operacional. El detalle es que un amplificador operacional común, como el clásico LM358 no satura hasta Vcc es decir que por mas que aumentemos el voltaje de entrada, el voltaje de salida no alcanzará Vcc, para solucionar esto, tenemos de dos sopas: o alimentamos al amplificador operacional con un poco mas de voltaje, o bien, alimentamos al procesador con un poco menos de voltaje. Por sencillez, haré la segunda opción, alimentaré al AVR con 3.3V, así no saturaremos al LM358 y la señal de salida sera lo que esperamos. si desean alimentar al operacional con voltaje mas alto, que sea por lo menos 1.5V mas que lo que alimentan el procesador (al final depende del operacional).

 

Bueno, ya están todos los cálculos. Ahora a ensusiarnos las manos. Aquí dejo el diagrama, el código fuente y un video con los resultados.  

 

 

 

 

// Inicializacion del timer2
 
// Clock source: System Clock
// Clock value: 8000.000 kHz
// Mode: Fast PWM top=0xFF
// OC2 output: Non-Inverted PWM
// Timer Period: 0.032 ms
// Output Pulse(s):
// OC2 Period: 0.032 ms Width: 0.016063 ms
ASSR=0<<AS2;
TCCR2=(1<<PWM2) | (1<<COM21) | (0<<COM20) | (1<<CTC2) | (0<<CS22) | (0<<CS21) | (1<<CS20);
TCNT2=0x00;
OCR2=0x80;
 
...
...
 
//loop principal   (PWM = OCR2)
 
while (1)
      {
       //minimo
       PWM = 0;
       delay_ms(2000);
       //maximo
       PWM = 255;
       delay_ms(2000);
       //diente sierra              
       for(i=0; i<50; i++)
       for( PWM = 0; PWM <255; PWM++)
          {
           delay_ms(1);
          }
       // senoidal
       f=0.0;
       for(i=0; i<50; i++)
       for(f = 0.0; f < (2*3.141592654); f+=0.01)
          {
           PWM = 128 + (unsigned char) ( 127.0 * sin(f) ) ;
           delay_us(100);
          }
           
 
      }

Escribir comentario

Comentarios: 0