Usando PWM - mini tutorial
| #1 Usando PWM - mini tutorial |
| #2 Manejando los tiempos (Parte2 de PWM Mini-Tutorial) |
|
Marcelo
Colaborador
|
1) Manejo de los tiempos
Ahora que sabemos como es la teoría básica del PWM, vamos a programarlo en un PIC 16F84A. Para simplificar un poco la explicación y no hacerla tan larga, supondremos que se poseen conocimientos básicos de cómo funciona un PIC. La forma de aplicación con la que podemos usar las rutinas PWM son básicamente 2: 1) “Stand Alone” o programas que corren sin instrucciones de comando externos. Estos se utilizan normalmente en sistemas autómata, los cuales reaccionan a estímulos externos como por ejemplo un robot que choca contra un obstáculo o el seguimiento por parte del robot de una línea guía en el suelo, pero el programa en si se autocontrola y toma sus propias decisiones (bueno, las que le programamos). 2) Modo Maestro - Esclavo, que utiliza un controlador externo que le dice a un aparato que es lo que debe hacer. Por ejemplo, un circuito que controla un motor que a la vez es comandado desde un computador bien sea por el puerto serial, paralelo, usb, infrarrojo o cualquier otro. En estos casos, el computador “conversa” con el circuito, decide que se debe hacer e instruye al esclavo para que lo haga. Para empezar recordemos que PWM en realidad controla TIEMPO. Por consiguiente es necesario tener un conocimiento relativamente alto de cómo se manejan los tiempos en un PIC 16F84A. En otros integrados de esa familia de semiconductores, ya existen librerías programadas para manejar PWM. Este no es el caso del 16x84, por lo que el control de tiempo hay que hacerlo “a mano”. La frecuencia de trabajo de un microcontrolador es un parámetro primordial a la hora de determinar a que velocidad se ejecutan las instrucciones dentro de él. En estos PICs cada instrucción consume 4 ciclos de reloj que llamaremos Q1, Q2, Q3 y Q4. 1) Con el pulso Q1 se incrementa el “contador de programa”. 2) Con los pulsos Q2 y Q3 se decodifica la instrucción y se ejecuta 3) Durante Q4 se busca el código que corresponde a la próxima instrucción en la memoria del PIC y se carga en el “registro de instrucciones”.
Las instrucciones que generan un “salto” se llevan dos ciclos de instrucciones. Fíjense que pareciera que no cuadra lo de los pulsos y esto se debe a que las dos fases que comprenden las instrucciones se realizan en paralelo y en realidad cada instrucción toma 2 ciclos en ejecutarse. Esto se denomina técnica de segmentación y se le llama “pipeline”; ya la deben de haber escuchado más de una vez.
Las instrucciones de salto llevan 2 ciclos porque no se conoce la instrucción que sigue luego de cada salto, por consiguiente el ciclo en el cual el procesador debería buscar la próxima instrucción secuencial, es sustituido por un ciclo sin operación. (vean la figura anterior) Si la instrucción es de salto condicional es decir, salta si se cumple una condición como decfss o decfsc por ejemplo, la instrucción puede durar 1 ciclo, si no se cumple la condición o 2 ciclos si la condición de salto se cumple. Para el cálculo tomamos 2 ciclos que es el peor de los casos. La frecuencia fundamental de operación del PIC viene dada por el oscilador que utilizamos para su configuración. Así por ejemplo, un programa que tiene 500 instrucciones de las cuales 120 son de saltos y se configura con una frecuencia típica de 4 Mhz, tardará en ejecutarse el siguiente tiempo (recuerden que el 16F84A se puede manejar hasta con 20Mhz): Tiempo del Ciclo de reloj (Qi) = 1/f = 1/4.000.000 = 250 ns (nano segundo) Tiempo del Ciclo de Instrucción = 4 veces Ciclo de reloj = 4 * 250ns = 1.000 ns = 1 us (micro segundo) Tiempo del programa = Instrucciones de 1 ciclo * Ciclo de Instrucción + Instrucciones de 2 ciclos * 2 veces Ciclo de Instrucción Tiempo del programa = (500 – 120) * 1 + 120 * 2 = 620 us Nuestro programa tardará en ejecutarse 620 micro segundos. En la próxima entrega vamos a entrar en la lógica que usaremos para la rutina y su codificación. Saludos. Marcelo. |
|||||||||||
|
Ultima edición por Marcelo el Dom Sep 11, 2005 12:42 am, editado 1 vez |
||||||||||||
| #3 La lógica en la programación |
|
Marcelo
Colaborador
|
La lógica en la programación del PWM
Muchas son las formas, algoritmos e ideas que podemos aplicar para programar nuestra rutina y este no es un caso particular. A cada uno de nosotros se nos ocurrirán formas más o menos complicada, más o menos largas de codificar y más o menos eficientes para escribir nuestro programa. pero todas igual de válidas. Como la idea de este tutorial no es demostrar nada sino retransmitir lo poco que se sabe a fin de que se mejore el conocimiento medio de todos nosotros, lo que trataremos de hacer es reducir al máximo la complejidad sin hacerle mucho caso a la eficiencia, a fin de que cualquiera que lo lea lo pueda entender, aplicar y mejorar. A ustedes les dejo el perfeccionamiento del firmware del PIC. Tampoco consideraremos cual debería ser el tiempo óptimo del pulso, sino que ustilizaremos un tiempo bastante corto en el cual el motor no salte y además tenga tiempo suficiente para responder a la solicitud de movimiento. De igual manera y a fin de simplificar aun más las cosas, trataremos de no utilizar en la rutina de PWM interrupciones, watch dog ni TMR0. Antes de empezar a diseñar la rutina deberemos establecer como vamos a conectar nuestro PIC con el mundo exterior y de que manera lo vamos a controlar. Como circuito de práctica y lineamientos generales haremos que nuestro PIC cumpla con estas condiciones: 1 ) Controlaremos un motor DC 2 ) Usaremos una frecuencia de 4 Mhz 3 ) Usaremos la puerta B 4 ) Pin de control del motor RB4 (SALIDA) 5 ) Pin de control del motor RB5 (SALIDA) 6 ) El pin RB6 indicará con un LED uno de los dos sentidos de giro (SALIDA) 7 ) El pin RB7 indicará con un LED el otro sentido de giro (SALIDA) 8 ) Haremos que el control sea externo es decir, desde un computador. Para esto usaremos los siguientes pines (ojo, porque a veces esto confunde un poco): a. RB1: Recepción DESDE el Puerto Serial. (Deberá conectarse a la pata Tx del serial – pin 2 DB9). Este pin como ENTRADA. b. RB2: Transmisión HACIA el Puerto Serial. (Debera conectarse a la pata Rx del serial – pin 3 DB9). Este pin como SALIDA. 9) RB0/INT la dejamos en standby a ver si la usamos luego para indicar o producir algún evento. Lógica de la rutina, el algoritmo: Supongamos que tenemos una palabra de 8 bits para indicar el Duty Cycle de nuestros pulsos es decir, un byte. Por consiguiente tendríamos 2^8 posibles valores = 256 (desde 0 hasta 255) Lo que vamos a hacer es normalizar a 1 nuestra temporización. Esto quiere decir que si consideramos que 1 es el tiempo total de un pulso completo, podemos afirmar que: TALTA= CICLO/256 TBAJA=1-TALTA Donde CICLO varía desde 0 hasta 255. (El 256 del divisor indica los 256 posibles valores) CICLO es una variable que usaremos al enviar el valor para la determinación del tiempo de alta. La idea es contar desde 0 hasta CICLO manteniendo la alimentación del motor encendida y el tiempo restante, hasta llegar a 256 se colocará la salida en 0. Usemos el acumulador del PIC (W) como contador, teniendo entonces que: W=W + CICLO con CICLO = 0, 1, 2, 3, …. 255 y conteniendo el valor deseado por nosotros. Habíamos dicho que no usaríamos interrupciones ni desbordes de temporizadores, pero necesitamos una forma de saber cuando el contador llegó a 256 o mejor dicho, cuando terminó de dar una vuelta completa. Una forma de hacerlo es utilizando la bandera de CARRY (bit de acarreo) del registro de ESTADO del PIC. Con esto en mente: 1) Si CICLO vale 0, nunca ocurrirá un carry y la salida siempre estará a 0. 2) Si CICLO vale 1 el carry se activará cuando el acumulador W, luego de haber empezado a contar desde 0, llegue a 0xFF y pase de nuevo a 0x00 (de 255 a 0). Entonces la salida estará alimentando al motor la 1/256ava parte del tiempo total. 3) Si CICLO vale 2, W hará un rollover (giro sobre si mismo o vuelta) dos veces es decir, ocurrirán 2 carries y el tiempo de alimentación será la 2/256ava parte del tiempo total. 4) Etc. Etc. Vemos que el carry ocurre siempre excepto cuando CICLO vale 0 en donde el motor está apagado. Si se quiere el motor “siempre” excitado entonces enviaremos CICLO=255, en donde el tiempo de alta será 255/256. No por casualidad se usaron los valores 0 a 255 que corresponden a la codificación de caracteres ASCII. Esto va a servirnos de mucho cuando programemos nuestro software principal en el PC pues deberemos mandar códigos ASCII a nuestra interfaz. Como debemos comunicarnos con nuestro motor, utilizaremos unos número de códigos que reservaremos del rango 0 a 255. Dependiendo de como desarrollemos nuestro "firmware", habrá que tener cuidado de no usar esos caracteres específicos para definir un valor de velocidad para el PWM desde nuestro programa de computador, pues se utilizarán para conocer el estado de nuestro circuito y enviar comandos y recibir respuestas. En nuestro caso, si podremos usar los 256 valores posible porque las comparaciones de comunicación las haremos antes de enviar el caracter de velocidad. Por ejemplo: 1) Envio del carácter 100 desde el computador: Solicita estado de la conexión. 2) Envío de carácter 102 para dirección de giro 1 3) Envío de carácter 104 para dirección de giro 1 4) El PIC responderá: con 100, indicando que la interfaz está conectada y comunicada. 5) El PIC enviará el código 104 para indicar que se está moviendo en cada bucle de 256. 6) El PIC enviará el código 102 para indicar que el motor paró su movimiento En la próxima, el listado del programa. |
|||||||||||
|
Ultima edición por Marcelo el Dom Sep 11, 2005 12:42 am, editado 4 veces |
||||||||||||
| #4 El programa para el PIC |
|
Marcelo
Colaborador
|
Aca estamos de vuelta.
Ahora que ya tuve tiempo para hacer el circuito de prueba y terminar el programa, se los voy a pasar. Si lo quieren bajar hagan click en estos links (botón derecho del mouse y luego "guardar destino como"). Recuerden bajar también el Rs232low.inc que lo van a necesitar cuando quieran hacer un cambio en el programa y tengan que reensamblarlo. MyPWM - assembler : http://www.forosdeelectronica.com/upload/MarceloFiles/PWM/MiPWM.asm MyPWM - código HEX : http://www.forosdeelectronica.com/upload/MarceloFiles/PWM/MiPWM-HEX.zip rs232low.inc : http://www.forosdeelectronica.com/upload/MarceloFiles/PWM/rs232low.zip Palabra de configuración para el PIC16F84A: OSCILADOR: XT WDT: Off Power Up Timer: Off (Si usan 16C84 ponganlo en On) CodeProtect: Off Aqui les voy a dar una breve explicación de lo que hace el programa pues creo que el código está lo suficientemente comentado como para que se entienda paso a paso. Recuerden que la intención de este tutorial es aprender así, paso a paso; por lo que muchísimas cosas en el programa se pueden realizar con menos instrucciones de las que tienen e inclusive omitir algunas. También tiene como idea, alentar a aquellos que le tienen algo de miedo al assembler y hacerles ver que es relativamente fácil programarlo. La forma en que se estructura la codificación está hecha de la manera más secuencial posible para que podamos entenderlo a cabalidad. En resumen el programa hace lo siguiente: 1) Cuando desde el computador enviamos el caracter "d" (ASCII Decimal 100 - Hexadecimal 64), le preguntamos a nuestro circuito: ¿TIENES COMUNICACIÓN?, a lo que la interfaz (es decir, el PIC) reaccionará enviando un 100 al computador como respuesta. Esto sirve para poder comprobar que la interfaz está interconectada al PC. Si no tienen respuesta es que hay algún problema. 2) Cuando queremos decirle a la interfaz que mueva el motor en la dirección A, enviaremos el caracter "f" (ASCII Decimal 102 - Hexadecimal 66). La interfáz quedará en standby esperando que le enviemos el valor de la velocidad que deseamos. En este punto debemos enviar cualquier caracter desde 0 a 255, siendo 0=Parado y 255=Full Velocidad. Cuando enviamos el valor de velocidad, la interfaz mandará el caracter "h" (ASCII Decimal 104 - Hexadecimal 68) para decirle al computador "ME ESTOY MOVIENDO" y cuando termine el ciclo de movimiento la interfaz mandará el caracter "f" (ASCII Decimal 102 - Hexadecimal 66) para informar "ME DETUVE". 3) Si queremos mover el motor en el sentido contrario (Dirección B), deberemos enviarle a la interfaz el caracter "h" (ASCII Decimal 104 - Hexadecimal 68) y las respuestas serán iguales a las explicada en el punto 2. Si esto les pareció complicado, monten el circuito en un protoboard y utilicen un programa terminal como el Comm Port Toolkit o cualquier otro (inclusive el Hyperterminal de Windows) para enviar los carateres y ver como responde. Este envio y recepción de caracteres le permitirá saber que está haciendo el motor y actuar en consecuencia desde el programa de su PC. Este tipo de programas y controladoras (me refiero al circuito) son muy comunes en robótica y control asistido por computadora, por lo que es muy interesante ponerse a experimentar y realizar infinidades de cosas con ellas. El código va a quedar un poco descuadrado en la pantalla por lo de cortar y pegar, pero sigue siendo bastante legible. Para la próxima... El circuitito. Bueno, aqui les va... y Saludosl
|
|||||||||||
|
Ultima edición por Marcelo el Vie Nov 18, 2005 3:47 pm, editado 3 veces |
||||||||||||
| #5 Montando el circuito |
|
Marcelo
Colaborador
|
Montando el circuito:
Ahora que ya tenemos diseñado nuestro firmware, vamos a montar el circuito para probarlo. La alimentación de la etapa lógica y de comunicaciones (PIC16F84 y MAX232) será a 5 voltios. Con respecto al control del motor hay que tener algunas consideraciones. Si alguien se está preguntando si puede conectar directamente las patas del motor a las salidas del PIC la respuesta es NO!. Las señales de salidas (Motor1 y Motor2) del PIC se usarán como control para el circuito de potencia del motor. Aunque yo les voy a dar un esquema sugerido para un motor DC de 9-12V de alimentación y corriente de armadura de 250 mA (lo pueden forzar hasta 1,5 A pero disipen el calor en los transistores BD135), diseñado con elementos discretos (transistores, resistencias, condensadores, etc), queda en sus manos el desarrollo de esta etapa. Para ello podrán emplear un buen número de integrados diseñados para el manejo de motores DC o basarse en cualquiera de los circuitos que podrán encontrar dedicados a eso (pregunten en este foro). Para los que son un poco más avanzados en electrónica: “Deberán poner atención en el diseño del circuito para el control de motores, pues tendrán que verificar que las salidas M1 y M2 deberán estar amortiguadas (con un buffer) mediante un circuito cuya ganancia sea igual a 1, a fin de evitar que las salidas (o los pines mejor dicho) se mantengan en régimen permanente afectando el voltaje entregado por el PWM. Esto debió evitarse cambiando el firmware de manera tal que las salidas de PWM (Motor1 y Motor2) se coloquen como SALIDAS al momento de llamar a la rutina de movimiento y conmutándolas a ENTRADAS (estado de alta impedancia) inmediatamente después de que la rutina PWM haya terminado de realizar sus labores. Esto no está implementado. Aquí el “buffering” lo hice utilizando los optoacopladores en el puente H.” Fin de la cita. Siguiendo con lo anterior, si desean probar el circuito sin utilizar un motor, podrán conectar (aquí si directamente) un LED en cada una de las salidas correspondientes al motor. En los siguientes LINKS se pueden bajar los esquemas en EAGLE para que los modifiquen, los integren y realicen su circuito impreso. Fuente de poder - Input AC: PowerSupply-DC.sch Fuente de poder - Input DC: PowerSupply.sch Esquema Parte Lógica: PWM.sch Esquema Parte de Potencia del Motor: PuenteH.SCH y aquí van los circuitos (discúlpenme si quedaron algo grandes): Si disponen de un transformador DC (corriente contínua) de 12 voltios pueden utilizar la siguiente FUENTE DE PODER:
Si en cambio poseen un transformador de 12 voltios AC (corriente alterna), la pueden diseñar así:
El Circuito Lógico, que comprende el PIC y la comunicación, es el siguiente:
En el circuito anterior, el PIN 5 del PIC debe ir a tierra y el PIN 14 a Vcc (5 voltios). OJO: No aparecen en el esquema. Y para controlar el motor, pueden usar algo como esto:
Ahora bien, lo único que falta para terminar el proyecto es construirnos un cable serial pin a pin para conectarlo al computador y escribir nuestro software de control. Para esto pueden utilizar este esquema:
Bueno amigos “Foristas” creo que esto concluye el mini tutorial de PWM y de todo un poco en realidad, pues hemos podido abarcar desde la teoría hasta la práctica, pasando por la lógica, la diagramación, el desarrollo y la construcción de nuestro proyecto, así es que también hemos podido ver una forma de diseño. Como escribí aquí en más de una oportunidad, mucho se puede hacer para mejorar este trabajo y es lo que deseo que hagamos todos. Espero que se animen a estudiar este y a escribir otros tutoriales, yo por mi parte los estaré esperando. Saludos y hasta la próxima, Marcelo. |
|||||||||||
|
|
||||||||||||
|
| Temas de interés | |
|---|---|
| Conmutador electronico 10 pulsos x seg | |
| Contador de pulsos unido al microcontrolador DLP-245PB | |
| 555 como divisor de frecuencias en un tren de pulsos | |
| Control de pulsos sincronizados con la red electrica | |
| Contador de pulsos | |
| Foros de Electronica |
| ||
Cuestiones Elementales de Electrónica ||
Fuentes de alimentacion ||
Circuitos de radio ||
Diseño de circuitos en general || || Sistemas de Audio: Preamplificadores, Ecualizadores || Amplificadores || Reparación || Discusión || || Microcontroladores y sistemas embebidos || Circuitos logicos combinacionales y secuenciales || Interfaces y Programacion || Dudas en general || Sistemas de Video || PC Hardware || Telematica y comunicaciones || Tecnologias moviles || Software Electronico || Robotica, Domotica y Mecatronica || Autotrónica || Automatizacion, Electronica industrial y de Potencia || Documentacion, circuitos y esquemas || Donde Las Ideas Convergen... || Tutoriales y Manuales || Proyectos Prácticos || |
Site Map
© Foros de Electrónica
Comunidad Internacional de Electrónicos
Powered by phpBB © 2001, 2005 phpBB Group
Acerca de || Política de privacidad
© Foros de Electrónica
Comunidad Internacional de Electrónicos
Powered by phpBB © 2001, 2005 phpBB Group
Acerca de || Política de privacidad

