control de brillo del LED mediante PWM
ancho de pulso modulación PWM o es un término que escuche mucho si usted está interesado en el control de la potencia de salida usando un microcontrolador. Tiene muchas aplicaciones, aunque uno de los más populares entre los aficionados es controlar el brillo de los LED. En este tutorial vamos a cubrir los principios básicos detrás de PWM y la forma en que se puede utilizar para el control de brillo del LED incluyendo desapareciendo LEDs en lugar de convertirlos en y fuera.
Este artículo se centrará en algunos de los detalles más específicos de la gama de microcontroladores PIC18F;sin embargo, las técnicas y los principios son los mismos para todos los demás productos del microcontrolador.Algunos microcontroladores incluyen módulos PWM que realizan todo el trabajo duro por usted; sin embargo, este artículo se centra en la técnica más universal (y escalable) de la utilización de las interrupciones.
Contenido[hide] |
Video Tutorial
Este tutorial está diseñado principalmente como un tutorial en vídeo. Usted puede ver el video completo en YouTube, por favor utilice 780p o 1080p para diagramas claros:
Introducción
Para controlar el brillo de un LED se puede variar la potencia que se envía a los LED, por ejemplo usando un potenciómetro (resistencia variable), el más poder que el LED recibe la más brillante es, menos potencia que recibe el dimmer es. Microcontroladores son digitales, lo que significa que sólo tienen dos estados 'poder', dentro y fuera. Aunque es posible suministrar una potencia que varía de un microcontrolador (utilizando un convertidor de digital a analógico (DAC)) esta por lo general requiere un chip adicional. PWM ofrece la capacidad a distintos niveles "simular" de poder por hacer oscilar la salida del microcontrolador.
Si, durante un corto período de tiempo, nos volvemos el LED en el 50% y el 50% fuera, el LED se parece la mitad de brillante desde la salida de luz total sobre el tiempo de duración es sólo la mitad tanto como el 100% en. El factor importante aquí es la 'duración', si rechazamos la luz dentro y fuera demasiado lentamente el espectador va a ver el parpadeo del LED no una salida de luz constante que aparece más tenue. El ancho de pulso (en este caso 50%) es el factor importante aquí. Mediante la variación de (o "modulación") el ancho de impulsos que podemos controlar con eficacia la salida de luz del LED, de ahí el término de PWM o modulación por ancho de pulso.
Al usar PWM que es importante tener en cuenta la lentitud con que podemos 'flash' el LED para que el espectador no percibe la oscilación. La incapacidad del ojo para ver las oscilaciones rápidas de la luz es causado por nuestro "persistencia de la visión", que significa, en términos muy simples, vemos la luz como en incluso después de que se haya apagado. Esta técnica es como televisores muestran una imagen en movimiento en apariencia que en realidad está formada por una serie de diferentes marcos aún se muestra uno tras otro con gran rapidez. La velocidad mínima de un LED oscilante que puede ser visto por el ojo humano varía de persona a persona. Sin embargo, a los efectos de este artículo, vamos a utilizar una velocidad mínima de 50 Hz, o 50 veces por segundo (la misma velocidad que se utiliza por los televisores europeos).
Deber-Ciclo
Al usar PWM hay ciertos términos que se encontrará una y otra vez. El término más importante es «el ciclo de trabajo '. El ciclo de trabajo se refiere a la cantidad total de tiempo que un pulso es 'on' largo de la duración del ciclo, por lo que en 50% de brillo el ciclo de trabajo de la LED es 50%. El "ciclo" en sí se mide (por lo general) en Hertz que nos da el segundo ciclos por visión. Así que a 50Hz nuestro ciclo es de 1 segundo dividido por 50 ciclos, que es de 0,02 segundos. Ya que estamos usando estas medidas de tiempo pequeños, es más útil utilizar microsegundos (hay 1.000.000 de microsegundos en un segundo), esto nos da una duración del ciclo de 20,000 microsegundos, que es de 50 ciclos por segundo o 50 Hz.
Durante los 20.000 microsegundos tenemos que girar el LED encendido o apagado dependiendo del ciclo de trabajo requerido es así, por ejemplo, un ciclo de trabajo del 75% requiere el impulso de estar en para 15.000 microsegundos y luego se apaga para 5.000 microsegundos.
Resolución PWM
La precisión con la que podemos controlar el ciclo de trabajo se conoce como la 'resolución PWM'. Cuanto mayor sea nuestra resolución PWM es, las más niveles de 'brillo' podemos mostrar. Sin embargo, ya que el ciclo de trabajo es 'fija' a 50Hz más de resolución más fina requiere una sincronización desde el microcontrolador. Cuanto más rápido el microcontrolador, las duraciones más pequeños se puede medir el tiempo. Otro factor limitante es la ejecución del código, el microcontrolador debe no sólo el tiempo de la 'interrupción' que hace que la generación de impulsos, sino que también ejecuta el código que controla la salida del LED, que debe completar antes de que se llama la siguiente interrupción. Además, es probable que desee que su microcontrolador a ser la realización de tareas que no sean de control de brillo LED PWM, por lo que no tiene que ser un tiempo de ejecución de repuesto entre las interrupciones para hacer todas las otras tareas de procesamiento más generales.
Con el control de PWM de LEDs la ventaja principal de las resoluciones más altas PWM es que resulta en una menor diferencia entre "off" y el brillo más bajo posible desde el LED. Por ejemplo, si nuestro ciclo de trabajo es de 20.000 microsegundos (50Hz) y nuestra resolución es de sólo 10.000 microsegundos, la diferencia entre el "off" y el brillo más bajo posible será el 50% del total de brillo posible. En una resolución de 2.000 microsegundos la diferencia sería 10% y así sucesivamente. En general, la 'resolución PWM' dicta el número de "niveles" de brillo podemos apoyar entre completamente apagado (0%) y totalmente en (100%). De nuevo, la mayor sea la resolución, se requiere la precisión y el procesamiento de temporización más arriba.
Para su aplicación la resolución requerida y ciclo de trabajo en general pueden variar. Pantallas simples requieren muy poco control de precisión (ya veces un poco de parpadeo no es el fin del mundo), para pantallas más avanzados la capacidad de controlar los niveles de brillo podría ser crítico (piensa en el tema de la mezcla de colores mediante un LED RGB, por ejemplo, ). La disyuntiva es simple, más control y precisión requiere cada vez más recursos del microcontrolador. En este artículo nos centraremos en un ejemplo que proporciona una resolución de 1.000 microsegundos durante un ciclo de trabajo de 20,000 microsegundos (o 50Hz con pasos de 5% que nos da 20 niveles de brillo). Este nivel de control y precisión es adecuado para muchos propósitos.
Medir el tiempo del de interrupción
Para llevar a cabo el PWM utilizando una interrupción que tenemos que llamar a la interrupción una vez cada 1.000 microsegundos y decidir si el LED debe estar encendido o apagado. Para ello tenemos que establecer un temporizador en el microcontrolador que llama a la interrupción cuando expire.
Para este ejemplo vamos a tomar un microcontrolador Microchip PIC18F4550 funcionando a 48Mhz como el ejemplo. 48Mhz significa que el reloj del microcontrolador 'tick' 48000000 veces por segundo. Esto se conoce como 'Fosc' (la frecuencia de oscilación). Un PIC18F4550 requiere 4 ticks del reloj para procesar una sola instrucción. Esto significa que la menor cantidad de tiempo que podemos lidiar con el uso del microcontrolador es un cuarto de la velocidad de reloj, es decir, 48.000.000 / 4 = 12 millones (esto también se conoce como Fosc / 4), si hay 1.000.000 de microsegundos en un segundo, significa esto? ejecutamos un comando de alrededor de una vez cada 0,0834 microsegundos (12 MIPS (millones de instrucciones por segundo)). Aunque esto no es del todo correcto en términos PWM desde la generación de un pulso que necesitaríamos dos comandos (encendido y apagado) que significa un tiempo de ciclo mínimo de 0.167 microsegundos (esto limita efectivamente la frecuencia más alta que podemos producir en el software para 6Mhz, aunque esto es no un máximo muy práctico).
Si el / 4 tasa Fosc es 12000000 esto significa 1 microsegundo de tiempo pasa por cada 12 ciclos de procesador. Esto significa que 1.000 microsegundos es equivalente a 12.000 ciclos de procesador. Esto es importante porque con una 1: 1 prescaler temporizadores del PIC actualizan una vez cada ciclo de procesador (aunque esto se conoce como una mezcla 1: 1 de preescala, realmente significa que no hay preescala en absoluto). Prescaler del temporizador ralentiza la velocidad a la que las actualizaciones de contador del temporizador, con una 1: 2 prescaler se actualiza una vez cada 2 ciclos de procesador, con un 1: 4 prescaler se actualiza una vez cada 4 ciclos de procesador y así sucesivamente.
Para utilizar un temporizador de 8 bits (se puede utilizar un temporizador de 16 bits también si lo desea) el período máximo del temporizador puede medir es de 256 'recuento' (0-255). Por lo tanto tenemos que escoger un valor pre-escalador que nos permite el tiempo de 12.000 ciclos de procesador en menos de 256 pasos de temporizador. Si utilizamos un prescaler 1:64 requerimos 187,5 pasos de temporizador para medir 1.000 microsegundos:
12 ciclos de procesador por microsegundo, por lo que 12 * 1000 = 12000 ciclos de procesador por cada 1.000 microsegundos: 12.000 ciclos / 64 (preescala) = 187,5 temporizador 'ticks'
Ya que no podemos contar con un 'medio' simplemente alrededor de la figura de abajo al entero más cercano (este medio se traduce PWM no será totalmente exacto, pero para el propósito de controlar el brillo del LED no es muy crítico). El valor más alto de preescala usamos, menos preciso será el tiempo llega a ser. Esto se puede corregir mediante el uso de un temporizador de 16 bits lo que nos permite contar mucho más garrapatas y por lo tanto utilizamos un valor preescala inferior.
Para un PIC18F4550 esto se traducirá en un código similar al siguiente extracto donde se configura el módulo timer0, activado y configurado para generar una alarma de baja prioridad:
// Habilitar interrupciones con prioridad IPEN = 1; // Establecer timer0 TMR0IP = 0; // Set timer0 interrumpir a baja prioridad TMR0IF = 0; // Borrar la bandera de interrupción timer0 TMR0L = 255-187; // Restablecer el contador timer0 T0CON = 0b11000101; // Timer0 en, 8 bits y 1:64 prescaler TMR0IE = 1; // Habilitar la interrupción timer0 // Habilitar interrupciones GIEH = 1; // Global habilitar interrupciones todo de alta prioridad GIEL = 1; // Global habilitar interrupciones todo de baja prioridad
Una vez que el temporizador está configurado y funcionando, necesitamos algo de código de interrupción para decidir si el LED debe estar encendido o apagado de la interrupción. Ya que tenemos 20 posibles niveles de brillo (y, por tanto, 20 pasos de resolución en nuestra generación PWM) podemos simplemente utilizar un contador que cuenta 0-19 y se actualiza una vez cada interrupción. Si el brillo del LED se representa mediante un número de 0 a 19 simplemente tenemos que comprobar si el contador PWM es mayor o menor que el número de brillo para ver si el LED debe estar encendido o apagado.
// Globals para PWM sin firmar Char pwmCounter = 0; sin firmar Char ledBrightness = 0; // Procedimiento de interrupción de baja prioridad LOW_PRIORITY interrupción vacío lpHandler (vacío) { // Está interrumpiendo este timer0? si (TMR0IF) { si (ledBrightness> pwmCounter) LED0 = 1; más LED0 = 0; pwmCounter ++; si (pwmCounter> 19) pwmCounter = 0; // ¡Prepárate para la siguiente interrupción TMR0L = 255-187; // Restablecer el contador timer0 TMR0IF = 0; // Borrar la bandera de interrupción timer0 } }
Fading el LED
Como sabemos la duración del ciclo del temporizador timer0 también podemos usar esto para proporcionar efectos de desvanecimiento en el LED. Para ello tenemos que guardar dos valores para el brillo del LED, una variable para almacenar el brillo que aparece real y otra para almacenar el brillo objetivo para el LED. Ya que sólo queremos desaparecer apagado (se podría adaptar esta facilidad para apoyar tanto se desvanecen en y desvanecimiento) si el brillo de destino es mayor que el brillo real, traemos de inmediato el brillo real al mismo nivel.
Sin embargo, para la decoloración de que queremos disminuir el actual nivel de brillo de un paso a la vez hasta que se iguala el brillo blanco. Dado que sólo hay 20 niveles de brillo que no podemos simplemente restamos un nivel en cada llamada de interrupción desde la llamada de interrupción es demasiado rápido para el fundido a ser percibido por el espectador (20 llamadas sólo consumirían 20.000 microsegundos, que es demasiado rápido para ver).
En lugar de ello mantenemos otro contador que cuenta una serie de llamadas de interrupción que debe ocurrir en entre disminuyendo el nivel de desvanecimiento real. Como sabemos la interrupción se llama cada 1.000 microsegundos es bastante recta hacia adelante para trabajar cuántas interrupciones debemos contar hasta obtener una velocidad de decoloración deseado. Por ejemplo, si queremos un fundido desde el nivel del brillo de 19-0 para tomar 0,5 segundos simplemente dividimos el tiempo requerido (en microsegundos) por el tiempo de interrupción de 1,000 microsegundos y luego por el número de niveles. Por lo tanto 0,5 segundos (o 500 000 microsegundos) = 500.000 / 1000 = 500/20 = 25. Esto se muestra en el siguiente fragmento de código:
// Globals para PWM sin firmar Char pwmCounter = 0; sin firmar Char ledActualBrightness = 0; sin firmar Char ledTargetBrightness = 0; sin firmar Char fadeCounter = 0; // Procedimiento de interrupción de baja prioridad LOW_PRIORITY interrupción vacío lpHandler (vacío) { // Está interrumpiendo este timer0? si (TMR0IF) { // Realizar el control de brillo de PWM si (ledActualBrightness> pwmCounter) LED0 = 1; más LED0 = 0; pwmCounter ++; si (pwmCounter> 19) pwmCounter = 0; // Realice la decoloración de control si (ledTargetBrightness> = ledActualBrightness) ledActualBrightness = ledTargetBrightness; más { fadeCounter ++; si (== fadeCounter 24) { ledActualBrightness -; fadeCounter = 0; } } // ¡Prepárate para la siguiente interrupción TMR0L = 255-187; // Restablecer el contador timer0 TMR0IF = 0; // Borrar la bandera de interrupción timer0 } }
Conclusiones
Aunque es perfectamente posible para conseguir controles PWM para trabajar con LEDs usando trabajo de la conjetura pura, el cálculo de los valores óptimos deseados hace un uso más eficiente de los recursos del procesador disponibles que le permite tanto hacer más con el microcontrolador y / o controlar más LEDs simultáneamente de la mismo chip. Las mismas técnicas que se muestran aquí para LEDs también se pueden utilizar para controlar los motores, pantallas metro análogo, bombillas incandescentes, etc.
0 comentarios:
Publicar un comentario