¿Cómo hacer PWM con la menor cantidad de software?

3

Estoy interesado en generar una señal PWM en software en un micro (no es posible usar hardware PWM en este caso). Es fácil de usar (por ejemplo) un bucle con un contador que cuenta hasta 255 y se ajusta, y las transiciones de alto-bajo cuando el contador llega a N y de bajo-alto cuando se ajusta, para un N de 255 pulsos.

Sin embargo, debido a que este PWM es bastante lento, me gustaría suavizarlo de la siguiente manera: si la salida es (por ejemplo) alta para 2 de 255 conteos, me gustaría que la salida fuera alta durante el 0º y 127º cuentan, no el 0º y 1º. Si es 127 de 255, me gustaría hacer una transición de bajo-alto y alto-bajo en cada cuenta, en lugar de permanecer alto para el primer 127 y bajo para el último 128.

En otras palabras, los mínimos y máximos deben estar lo más uniformemente extendidos posible. Me doy cuenta de que cuando el PWM está cerca de cualquiera de los extremos del rango, todavía tendrá una ondulación grande, pero esto reducirá la ondulación mucho cerca de la mitad del rango. ¿Cómo hacer esto de una manera eficiente?

EDIT: Parece que he redescubierto Modulación de la densidad del pulso . Todavía no estoy seguro de cómo hacer esto en la práctica, especialmente en un bucle rápido.

    
pregunta Alex I

3 respuestas

5

El siguiente algoritmo hará lo que quieras:

period = 256;
on_time = 34; // Or whatever you want
off_time = period-on_time;
count = 0;
while (1);
{
    if (count >= 0) {
        count -= off_time;
        output_high();
    } else {
        count += on_time;
        output_low();
    }
    wait_for_next_cycle();
}

Hice algo como esto para generar un reloj de muestra de 44100 Hz con una relación no simple del reloj maestro, pero su pregunta me motivó a generalizarlo, gracias.

    
respondido por el Austin
4

Lo que estás describiendo, si lo piensas un momento, es bastante simple. Mientras que normalmente en PWM usted mantiene la misma frecuencia pero varía el ancho del pulso, lo que usted describe es efectivamente mantener el ancho del pulso igual pero varía la frecuencia.

Para un ciclo de trabajo de 1/256, tiene un impulso cada 256 cuentas.

Para un ciclo de trabajo de 2/256 tiene dos pulsos (tradicionalmente unidos en un pulso de ancho 2x) cada 256 cuentas.

2/256 se puede reducir a 1/128 (matemáticas simples, ¿sí?), por lo que 2 pulsos cada 256 es lo mismo que 1 pulso cada 128 cuentas.

128/256 (50% de servicio) se puede reducir a 1/2, que es un pulso cada 2 cuentas, o una onda cuadrada de encendido y apagado rápido.

Por lo tanto, mantenga el ancho de su pulso en solo 1 conteo (enciéndalo en 0 y apáguelo en 1) y simplemente cambie el valor que está contando.

    
respondido por el Majenko
3

Parece que desea un modulador delta-sigma en lugar de PWM "normal". Un modulador delta-sigma emite una salida modulada por densidad de impulsos, moviendo el ruido principalmente a altas frecuencias para que sea más fácil filtrarlo. En general, esto se hace con hardware dedicado para obtener una tasa de salida muy alta, aunque supongo que no hay ninguna razón por la que no se pueda compilar uno en software.

    
respondido por el alex.forencich

Lea otras preguntas en las etiquetas