modulación por ancho de pulsos
TRANSCRIPT
Modulación por ancho de pulsos
Fig. 1: una señal de onda cuadrada de amplitud acotada (ymin,ymax) mostrando el ciclo de trabajo D.
La modulación por ancho de pulsos (también conocida como PWM, siglas en inglés de pulse-width
modulation) de una señal o fuente de energía es una técnica en la que se modifica el ciclo de trabajo de una
señal periódica (unasenoidal o una cuadrada, por ejemplo), ya sea para transmitir información a través de un
canal de comunicaciones o para controlar la cantidad de energía que se envía a una carga.
El ciclo de trabajo de una señal periódica es el ancho relativo de su parte positiva en relación con el período.
Expresado matemáticamente:
D es el ciclo de trabajo
τ es el tiempo en que la función es positiva (ancho del pulso)
T es el período de la función
La construcción típica de un circuito PWM se lleva a cabo mediante un comparador con
dos entradas y una salida. Una de las entradas se conecta a un oscilador de onda
dientes de sierra, mientras que la otra queda disponible para la señal moduladora. En la
salida la frecuencia es generalmente igual a la de la señal dientes de sierra, y el ciclo de
trabajo está en función de la portadora.
La principal desventaja que presentan los circuitos PWM es la posibilidad de que haya
interferencias generadas por radiofrecuencia. Éstas pueden minimizarse ubicando el
controlador cerca de la carga y realizando un filtrado de la fuente de alimentación.
Contenido
[ocultar]
1 Parámetros importantes
2 Aplicaciones
o 2.1 En los motores
o 2.2 Como parte de un conversor ADC
3 Véase también
[editar]Parámetros importantes
Algunos parámetros importantes de un PWM son:
La relación de amplitudes entre la señal portadora y la moduladora, siendo
recomendable que la última no supere el valor pico de la portadora y esté centrada
en el valor medio de ésta.
La relación de frecuencias, donde en general se recomienda que la relación entre la
frecuencia de la portadora y la de señal sea de 10 a 1.
Sin embargo, cuando se utilizan servomotores hay que tener cuidado en las marcas
comerciales ya que hay ocasiones en que los valores varian entre 1ms y 2ms y estos
valores propician errores.
[editar]Aplicaciones
Diagrama de ejemplo de la utilización de la modulación de ancho de pulsos en un variador de
frecuencia.
En la actualidad existen muchos circuitos integrados en los que se implementa la
modulación PWM, además de otros muy particulares para lograr circuitos funcionales
que puedan controlar fuentes conmutadas, controles de motores, controles de
elementos termoeléctricos, choppers para sensores en ambientes ruidosos y algunas
otras aplicaciones. Se distinguen por fabricar este tipo de integrados compañías
como Texas Instruments, National Semiconductor, Maxim, y algunas otras más.
[editar]En los motores
La modulación por ancho de pulsos es una técnica utilizada para regular la velocidad de
giro de los motores eléctricos de inducción o asíncronos. Mantiene el par
motor constante y no supone un desaprovechamiento de la energía eléctrica. Se utiliza
tanto en corriente continua como en alterna, como su nombre lo indica, al controlar: un
momento alto (encendido o alimentado) y un momento bajo (apagado o desconectado),
controlado normalmente por relevadores (baja frecuencia)
o MOSFET o tiristores(alta frecuencia).
Otros sistemas para regular la velocidad modifican la tensión eléctrica, con lo que
disminuye el par motor; o interponen unaresistencia eléctrica, con lo que se pierde
energía en forma de calor en esta resistencia.
Otra forma de regular el giro del motor es variando el tiempo entre pulsos de duración
constante, lo que se llama modulación por frecuencia de pulsos.
En los motores de corriente alterna también se puede utilizar la variación de frecuencia.
La modulación por ancho de pulsos también se usa para controlar servomotores, los
cuales modifican su posición de acuerdo al ancho del pulso enviado cada un cierto
período que depende de cada servo motor. Esta información puede ser enviada
utilizando un microprocesador como el Z80, o un microcontrolador (por ejemplo,
un PIC 16F877A de la empresa Microchip).
[editar]Como parte de un conversor ADC
Otra aplicación es enviar información de manera analógica. Es útil para comunicarse de
forma analógica con sistemas digitales.
Para un sistema digital, es relativamente fácil medir cuanto dura una onda cuadrada.
Sin embargo, si no se tiene un conversor analógico digital no se puede obtener
información de un valor analógico, ya que sólo se puede detectar si hay una
determinada tensión, 0 o 5 voltios por ejemplo (valores digitales de 0 y 1), con una
cierta tolerancia, pero no puede medirse un valor analógico. Sin embargo, el PWM en
conjunción con un oscilador digital, un contador y una puerta AND como puerta de
paso, podrían fácilmente implementar un ADC.
Usando PWM - mini tutorial
Usando PWM (Pulse with Modulation).
Casi todos los que lean este post, habrán hecho en algún momento, un proyecto para
prender un led o accionar un motor mediante un microcontrolador o por medio de cualquier
otro circuito.
Pero que sucede si queremos controlar la luminosidad del led que estamos encenciendo o
deseamos regular la velocidad del motor?.
Pudiéramos pensar que si prendemos y apagamos la señal de alimentación de la carga (led
o motor) lo suficientemente rápido como para que el parpadeo no se note, podríamos
“simular” la variación de luminosidad de un led o el cambio en la velocidad del motor:
Esto funciona siempre y cuando no hagamos este “switcheo” más allá de 30 veces por
segundo. A partir de allí. El "blink" del led se empezará a notar y El ojo humano captará ese
parpadeo. En el caso de un motor, éste se moverá en una forma pulsante.
La idea general del PWM es esta, solo que soluciona este problema de tiempo.
La forma de lograrlo es dejar el pulso fijo en el tiempo y variar su amplitud.
Supongamos que logramos ajustar el período T a su valor óptimo mínimo en el cual un led
no parpadee y un motor no salte.
Esto es aproximadamente a una frecuencia de 30 pulsos o ciclos por segundos para el caso
de un led. En el caso del motor habrá que determinarlo empíricamente ya que depende de
sus características eléctricas y mecánicas,
Volviendo al led, quiere decir que trabajamos con un período de tiempo de:
f= 30 cps ==> T=1/f ==> T=1/30 ==> T= 0.0333 s ==> T=33.3 ms
El esquema anterior representa un pulso con un “duty cycle” o ciclo de servicio igual al 50%
es decir, la mitad del período está a 0 y la otra mitad está a Vcc.
Lo que se hace con PWM es variar dinámicamente el “duty cycle” de manera que el tiempo
de alta disminuya o aumente y en proporción inversa, el de baja aumente o disminuya
dependiendo de si queremos una led más atenuado o más brillante, o un motor más lento o
más rápido, respectivamente.
LED MENOS ILUMINADO
LED MAS ILUMINADO
Recuerden que este período se repite constantemente en el tiempo:
De esta forma tenemos 2 formulitas muy sencillas para el cálculo de los tiempos:
1) Si variamos, fijamos o controlamos t alta entonces: t baja= T- t alta
2) Si variamos, fijamos o controlamos t baja entonces: t alta= T- t baja
Y el ciclo de servicio o “Duty Cycle” lo calculamos así:
DT= t alta / (t alta + t baja)
Manejando los tiempos (Parte2 de PWM Mini-Tutorial)
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.
La lógica en la programación
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
El programa para el PIC
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/up.../PWM/MiPWM.asm
MyPWM - código HEX : http://www.forosdeelectronica.com/up.../MiPWM-HEX.zip
rs232low.inc : http://www.forosdeelectronica.com/up...M/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 informaciónrmar "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.
;++++++++++++ PROGRAMA PARA CONTROLAR UN MOTOR DC
;++++++++++++ INCLUYE RUTINA PWM
;++++++++++++ INCLUYE RUTINA DE COMUNICACIÓN SERIAL
;++++++++++++ Marcelo Saavedra - 06/09/2005
List p=16F84A;Tipo de procesador
include "P16F84A.INC" ;Definiciones de registros internos
;
;Declaración de Variables.
;
CICLO equ 0x21 ;Duración del tiempo de servicio
RECIBIDO equ 0x22 ;Guarda el carácter recibido por el
serial
M1 equ 0x23 ;Bandera del motor. Con un solo pin
podemos controlar.
BANDERA equ 0x24 ;Contador de bucle
NVECES equ 0x25 ;Variable de control de bucle para
reenviar a PWM
Rs232_var equ 0x0C ;Inicio de las variables para rutinas
RS232low.inc para comunicación
;
;Parámetros de la rutina de comunicación
;
CLKIN equ .4000000 ;Frecuencia
BAUDIOS equ .9600 ;Velocidad de comunicación
T_MODO equ 1 ;Transmite primero bit LSB
R_MODO equ 1 ;Recibir primero bit LSB
T_Nbit equ 8 ;Transmite caracteres de 8 bits
R_Nbit equ 8 ;Recibe caracteres de 8 bits
Sbit equ 1 ;Transmite 2 bits de stop
org 0
goto INICIO
org 4 ;La Interrupción comienza aquí.
nop
include "RS232LOW.INC" ;Incluir rutinas de comunicación
;
;********Rutina de Inicio
;
INICIO
;Desabilita e impide todas las
interrupciones
bcf INTCON,GIE ;GIE=0
bcf INTCON,EEIE ;EEIE=0
bcf INTCON,T0IE ;T0IE=0
bcf INTCON,INTE ;INTE=0
bcf INTCON,RBIE ;RBIE=0
bcf INTCON,T0IF ;T0IF=0
bcf INTCON,INTF ;INTF=0
;
;********Configuración de los BYTES de STATUS y OPTION
bsf STATUS,RP0 ;Pone el RP0 a 1 - Seleccionando
BANCO 1 de datos
movlw b'11010000' ;Coloca el Byte de OPTION en W
;- Prescaler en 000
;- Prescaler al TMR0 - 0
;- Incremento TMR0 con flanco
ascendente - 1
;- Pulsos por Fosc/4 - 0
;- Flanco ascendente para la
interrupción - 1
;- Pull-up desactivadas - 1
movwf OPTION_REG ;Coloca el valor anterior de W en el
literal OPTION_REG
movlw b'00000011' ;Establece en W, el Byte de
configuración para PORTB
;RB0=Sensor (ENTRADA) - 1
;RB1= Recibir desde TX del
serial(ENTRADA) – 1
;RB2= Enviar hacia RX del serial
(SALIDA) - 0
;RB3=Sin conexión (SALIDA) - 0
;RB4=MOTOR 1 (SALIDA) - 0
;RB5= MOTOR 2 (SALIDA) - 0
;RB6= LED para indicar sentido 1
(SALIDA) - 0
;RB7= LED para indicar sentido 2
(SALIDA) - 0
movwf TRISB ;Se asignan los puertos RBi
salvando W en TRISB
bcf STATUS,RP0 ;Pone el RP0 a 0 para regresar
al BANCO 0 de datos.
;
;********Inicialización pines de Rx y Tx
bsf Txd_pin ;Línea de transmisión a "1" en
RS232Low.Inc
bsf Rxd_pin ;Línea de recepción a "1" en
RS232Low.Inc
;
;********Motor parado
bcf M1,0 ;Inicializamos la bandera del motor a 0
(Solo usamos el bit 0)
movlw 0xAA ;Número de veces que vamos a reenviar a
PWM - Esto es para Compensación
;y pueden ajustarlo para que el
encendido total sea mayor o menor (de 0 a ff)
movwf NVECES ;Cargamos la variable.
;
;********Rutina de recepción de datos
RECEPCION
;
;*************Apagamos todo
bcf PORTB,4 ;Apagamos pin RB4 de PORTB
bcf PORTB,5 ;Apagamos pin RB5 de PORTB
bcf PORTB,6 ;Apagamos el led 1
bcf PORTB,7 ;Apagamos el led 2
;
;*************Transmitimos "Motor Parado"
movlw 0x66 ;Coloca 102 (0x66) en W – Señal de
motor parado
movwf Txdreg ;Carga W en Txdreg para transmitirlo
call T ;y lo transmite indicando que los
motores están parados.
;
;*************Escuchamos el puerto serial
ESCUCHAR
call R ;Llama la rutina de recepción en
RS232Low.Inc
movf Rxdreg,W ;Coloca el caracter recibido por Rxdreg
en W
movwf RECIBIDO ;y lo salva en RECIBIDO
;
;*********Rutina de comparación del caracter recibido
;Empieza la comparación.
movlw 0x66 ;Coloca 102 (h66) en W – Es el sentido
de giro 1?
subwf RECIBIDO,0 ;Resta W (h66) del caracter recibido y
el resultado lo almacena en W
btfss STATUS,Z ;Está a 1 el bit ZERO de STATUS? (Si
está a 1 la resta anterior es 0)
goto SALTAR1 ;No, no está a 1, vete a SALTAR1
bsf M1,0 ;Si, Z está a 1, entonces pon M1 a 1
goto MOVIMIENTO ;y luego ve a MOVIMIENTO para seguir
con el programa.
SALTAR1
movlw 0x68 ;Coloca 104 (h68) en W – Es el sentido
de giro 2?
subwf RECIBIDO,0 ;Resta W (h68) del caracter recibido y
el resultado lo almacena en W
btfss STATUS,Z ;Está a 1 el bit ZERO de STATUS? (Si
está a 1 la resta anterior es 0)
goto SALTAR2 ;No, no está a 1, vete a SALTAR2
bcf M1,0 ;Si, Z está a 1, entonces pon M1 a 0
goto MOVIMIENTO ;y luego ve a MOVIMIENTO para seguir
con el programa.
SALTAR2
movlw 0x64 ;Coloca 100 (h64) en W – Me preguntan
si hay conexión?
subwf RECIBIDO,0 ;Resta W (h64) del caracter recibido y
el resultado lo almacena en W
btfss STATUS,Z ;Está a 1 el bit ZERO de STATUS? (Si
está a 1 la resta anterior es 0)
goto ESCUCHAR ;No,ZERO esta a 0 entonces se va a
buscar otro BYTE VÁLIDO.
;
;*********Rutina de enviar confirmación de LINK de la interfaz
;Si llega aquí se recibió el 100,
solicitando la confirmación de LINK
movlw 0x64 ;y comienza el ECO del caracter 100
(0x64) para decir SI, HAY LINK.
;Carga 100 en W
movwf Txdreg ;Carga W en Txdreg para transmitirlo
call T ;lo transmite.
goto ESCUCHAR ;y regresa a RECEPCION a esperar otro
carácter.
;
;*********Rutina de MOVIMIENTO / PARO
MOVIMIENTO
;ESPERAMOS EL VALOR DE CICLO. Ya
tenemos el sentido de giro.
call R ;Llama la rutina de recepción en
RS232Low.Inc
movf Rxdreg,W ;Coloca el caracter recibido por Rxdreg
en W
movwf CICLO ;y lo salva en CICLO
btfsc STATUS,Z ;Si se activo el bit Z de STATUS no se
ha recibido nada (W está en 0)
goto MOVIMIENTO ;y esperamos el caracter de CICLO. Si
Z=0 entonces saltamos este paso.
;
;Enviamos el caracter 104 para indicar
que el motor se va a mover.
movlw 0x68 ;Coloca 104 (0x68) en W – Señal de
motor en movimiento
movwf Txdreg ;Carga W en Txdreg para transmitirlo
call T ;y lo transmite indicando que los
motores se están moviendo.
;
;*********Encendido del LED
btfsc M1,0 ;Si M1 es 0, salta el próximo paso
goto LED2 ;Si M1 es 1 salta a LED2
bsf PORTB,6 ;Prendemos el led 1
bcf PORTB,7 ;Apagamos el led 2
goto ARRANCAR
LED2
bcf PORTB,6 ;Apagamos el led 1
bsf PORTB,7 ;Prendemos el led 2
;
;*********Comienzo del bucle
ARRANCAR
clrf BANDERA ;Borrar contador de bucle para recorrer 256
veces el bucle
call PWM ;llamamos la rutina PWM
decfsz NVECES,f ;Decrementamos la rutina de
compensación
goto ARRANCAR ;Mientras no llegue a 0, nos mantenemos
en el bucle
goto RECEPCION ;Cuando NVECES sea 0 regresamos a
esperar otro character.
;
;*********Rutina PWM
PWM
;
;*********Chequeo del CARRY y suma de W
addwf CICLO, w ; W=W+CICLO
btfss STATUS, C ;Chequeamos el CARRY
goto APAGAR ;Si no hay CARRY apagamos el
motor
btfsc STATUS, C ;Chequeamos el CARRY
goto PRENDER ;Si hay CARRY prendemos el motor
(pasamos de 255 a 0)
goto SEGUIR
;
;*********
PRENDER ;ENCENDIDO DE MOTOR
btfsc M1,0 ;Si M1 es 0, salta el próximo paso
goto REVERSA ;Si M1 es 1 se va a REVERSA
nop ;Los nop están para
compensar los tiempos de la comparación y los saltos
;COMO EJERCICIO CALCULEN
LOS TIEMPOS DE LA RUTINA PWM!!!.
bcf PORTB,4 ;Apagamos pin RB4 de PORTB
bsf PORTB,5 ;Prendemos pin RB5 de PORTB
goto SEGUIR ;y se va a SEGUIR
REVERSA
bsf PORTB,4 ;Prendemos pin RB4 de PORTB
bcf PORTB,5 ;Apagamos pin RB5 de PORTB
goto SEGUIR
APAGAR
nop
nop
nop ;APAGADO DE MOTOR
bcf PORTB,4 ;Apagamos pin RB4 de PORTB
bcf PORTB,5 ;Apagamos pin RB5 de PORTB
nop
nop
SEGUIR
;Si es necesario un
Delay colcarlo aquí
decfsz BANDERA,f ;Decrementamos BANDERA y saltamos si es
cero. Hacerlo 256 veces.
goto PWM
return
;**********Fin
Montando el circuito
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.