El Circuito
Diseño
de un sistema digital
que permita el control de una
antena parabólica, de tal modo que permita ser construido
de manera sencilla, con pocos componentes, y que además
cuente con un diseño
flexible. Se usará para ello los conceptos sobre motores de paso,
control digital,
así como se introducirán los conceptos relacionados
al uso del microcontrolador PIC16F84, y que serán
estudiados más adelante con mayor detalle en otros
cursos afines.
Así mismo se describirá el posicionamiento
de las antenas
parabólicas desde un punto de vista básico.
Para cumplir con el objetivo de un
diseño sencillo se optó por el uso de un
microcontrolador de la familia
Microchip, el famoso PIC16F84, el cual simplifica enormemente la
implementación del hardware necesario. Este PIC
constituye el "corazón"
del controlador, y en donde la única dificultad de su
utilización reside en la programación del mismo. Se escogió
este elemento por su relativo bajo costo, las
herramientas
de programación están disponibles
gratuitamente (MPLAB y compiladores/programadores de terceros, set de
instrucciones, ejemplos). Por tanto, en el firmware
realizado con estas herramientas
se describe las rutinas necesarias para el accionamiento
secuencial de dos motores de paso
en respuesta a los datos obtenidos
desde un teclado, en el
cual el usuario ingresará el sentido y los ángulos
de rotación y elevación que posicionarán la
antena en el lugar deseado. Sin embargo, el PIC genera niveles
compatibles con lógica
TTL, es por ello que el resto del circuito se encarga de la
adaptación de estos a través de una interface
implementada con el C.I. ULN2803 capaz de manejar altas
corrientes en su salida (500mA máx. por cada salida).
También se hace uso de un Flip-flop octal 74LS374 con la
finalidad de registrar los datos de salida
del PIC y separarlos del momento en que este se pone en modo de
recibir los datos del teclado. A la
salida del 374 se ubica también 8 LED’s a modo de
visualizador de las secuencias enviadas a los motores. Hay
además 3 LED’s indicadores
del momento en que se ingresan los datos respectivos por el
teclado. Finalmente, todo el circuito está alimentado a
través de un C.I. 7805 que regulará a 5V los
9-18VDC de la entrada principal de poder.
En lo que respecta a la flexibilidad, el PIC16F84 tiene
una capacidad de reprogramación de poco más de un
millar de veces (si es nuevo), lo que hace posible el optimizar
el firmware. En el circuito aún queda un pin libre
(RA4 – pin3) que puede servir con propósitos de
sensar la última ubicación de la antena y servir
como referencia para una nueva secuencia. También hay la
posibilidad de usar una fuente de alimentación externa
además de la principal del circuito, y aumentar la
capacidad de voltaje de las salidas del ULN2803 (máx.
30V), sólo se tendrá que desconectar los
jumpers marcados como JP1 y JP2, y utilizar el conector J4
como entrada de la nueva fuente.
Diagrama esquemático
Ubicación de Componentes y Circuito
Impreso
Programa fuente para el PIC16F84
(Parabolk.asm):
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;$ $
;$ Programa para
control de dos motores de paso $
;$ $
;$ Proposito: Control de Antena Parabolica
$
;$ $
;$ Realizado y documentado por: David Chumpitaz
Alfaro $
;$ $
;$ UNAC-FIEE Esc: Ing. Electronica Cod: 962043B
$
;$ $
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;
list p=16f84a
include <p16f84a.inc>
__config _XT_OSC & _WDT_OFF &
_PWRTE_ON
;
;DECLARACION DE VARIABLES— Variables
creadas por el usuario con un valor
inicial?
LCD_TEMP_1 EQU 0X0C ;LCD_TEMP_1=12
LCD_TEMP_2 EQU 0X0D ;LCD_TEMP_2=13
TECLA EQU 0X0E ;TECLA=14
KEY_1 EQU 0X0F ;KEY_1=15
KEY_2 EQU 0X10 ;KEY_2=16
KEY_DELAY_1 EQU 0X11 ;KEY_DELAY_1=17
KEY_DELAY_2 EQU 0X12 ;KEY_DELAY_2=18
SENTIDO EQU 0X13 ;SENTIDO=19
DIGITO EQU 0X14 ;DIGITO=20
DIGITO_1 EQU 0X15 ;DIGITO_1=21
DIGITO_2 EQU 0X16 ;DIGITO_2=22
COMBINADO EQU 0X17 ;COMBINADO=23
NUM_PASOS_M1 EQU 0X18 ;NUM_PASOS_M1=24
NUM_PASOS_M2 EQU 0X19 ;NUM_PASOS_M2=25
SENTIDO_M1 EQU 0X1A ;SENTIDO_M1=26
SENTIDO_M2 EQU 0X1B ;SENTIDO_M2=27
SECUENCIA_M1 EQU 0X1C ;SECUENCIA_M1=28
SECUENCIA_M2 EQU 0X1D ;SECUENCIA_M2=29
CONTADOR EQU 0X1E ;CONTADOR=30
DATO EQU 0X1F ;DATO=31
;
;
;
ORG 0 ;El programa empieza
en la direccion 0x00
GOTO PRINCIPIO ;Salta a la rutina PRINCIPIO
ORG 5 ;el programa sigue en la direccion
0x05
PRINCIPIO: ;Rutina de inicializacion
BSF STATUS,RP0 ;Bit RP0 de STATUS se pone a 1 (Bank
1)
CLRF TRISA ;Todos los bits de TRISA se ponen a 0
(Puerto A salida)
CLRF TRISB ;Todos los bits de TRISB se ponen a 0
(Puerto B salida)
BCF STATUS,RP0 ;Bit RP0 de STATUS se pone a 0 (Bank
0)
CLRF PORTA ;Todos los bits de PORTA se ponen a 0
(RaX=0)
BSF PORTA,3 ;luego, bit 3 de PORTA se pone a 1
(Ra3=1,Ra2=Ra1=Ra0=0)
MOVLW 0X77 ;El registro W se
carga con 0x77
MOVWF PORTB ;El contenido de W se copia en PORTB
(PORTB=01110111b)
BSF PORTA,0 ;Bit 0 de PORTA se pone a 1
(Ra0=1)
CALL LCD_DELAY ;Llamada a subrutina de
retardo
BCF PORTA,0 ;Bit 0 de PORTA se pone a 0
(Ra0=0)
MOVLW 0X77 ;El registro W se
carga con 0x77
MOVWF SECUENCIA_M1 ;Registro W se copia en SECUENCIA_M1
(SECUENCIA_M1=0x77)
MOVWF SECUENCIA_M2 ;Registro W se copia en SECUENCIA_M2
(SECUENCIA_M2=0x77)
CLRF CONTADOR ;Todos los bits de CONTADOR se ponen a
cero (CONTADOR=0x00)
GOTO PROGRAMA ;Salto al programa principal
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;Subrutina de retardo
;
LCD_DELAY movlw 40 ;Carga W con el valor
40
movwf LCD_TEMP_1 ;W se copia en LCD_TEMP_1
(LCD_TEMP_1=40)
clrf LCD_TEMP_2 ;Registro LCD_TEMP_2=0
LCD_DELAY_1 decfsz LCD_TEMP_2,F ;Decremento de
LCD_TEMP_2 (LCD_TEMP_2=255)
goto LCD_DELAY_1 ;Bucle LCD_DELAY_1 hasta que
LCD_TEMP_2=0
decfsz LCD_TEMP_1,F ;Decremento de LCD_TEMP_1
(LCD_TEMP_1=39)
goto LCD_DELAY_1 ;Bucle LCD_DELAY_1 hasta que
LCD_TEMP_1=0
return ;Retorno de subrutina
;2+1+1+1+((3*255+2)+3)*38+((3*255+2)+2)+2=30036
microsec
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
KEY_SCAN: ;Subrutina de inicializacion del
teclado
bsf STATUS,RP0 ;Selecciona Bank 1
movlw b'00001111' ;W=0x0F
movwf PORTB ;PORTB=0x0F (00001111b)
bsf OPTION_REG,NOT_RBPU ;Bit NOT_RBPU=1 (Desactiva
cargas pull-up)
bcf STATUS,RP0 ;Selecciona Bank 0
movlw 4 ;W=0x04
movwf KEY_1 ;KEY_1=0x04 (# de columnas a
explorar)
movlw b'01111111' ;W=0x7F
movwf TECLA ;TECLA=0x7F (Columna a activar)
KEY_SCAN_1: ;Busqueda de una pulsacion
movf TECLA,W ;W=0x7F
movwf PORTB ;PORTB=0x7F, 01111111b (Activa
fila)
movf PORTB,W ;W=PORTB (Si ha habido pulsacion PORTB
habra cambiado)
movwf KEY_2 ;KEY_2=W (KEY_2 guarda el cambio si lo
hubiese)
subwf TECLA,W ;W=TECLA-W, si W<>0 entonces Z=0
(Lee columnas)
btfss STATUS,Z ;Si Z=0 ejecuta goto sino salta (Hay
alguna pulsada?)
goto KEY_SCAN_2 ;Si hay alguna pulsada
bsf STATUS,C ;No hay ninguna en esa columna, bit
C=1
rrf TECLA,F ;TECLA=0xBF Selecciona siguiente
fila
decfsz KEY_1,F ;KEY_1=3 Salta si se han terminado las
filas
goto KEY_SCAN_1 ;Repite el scan de columnas
movlw 0x80 ;W=0x80
goto VOLVER ;Retorna codigo 0x80
(no hay pulsacion)
KEY_SCAN_2: ;Subrutina Antirrebote
movlw .120 ;Bucle de temporización de unos 20
ms para
movwf KEY_DELAY_1 ;KEY_DELAY_1=0x78 evitar rebote de
pulsadores
KEY_SCAN_3:
clrf KEY_DELAY_2 ;KEY_DELAY_2=0x00
clrwdt ;Clear Watchdog timer
KEY_SCAN_4:
decfsz KEY_DELAY_2,F ;KEY_DELAY_2=0xFF
goto KEY_SCAN_4 ;Bucle hasta que
KEY_DELAY_2=0
decfsz KEY_DELAY_1,F ;KEY_DELAY_1=0x77
goto KEY_SCAN_3 ;Bucle hasta que
KEY_DELAY_1=0
movf TECLA,W ;W=0x7F Tras la temporizacion se lee
nuevamente
movwf PORTB ;PORTB=0x7F si la tecla es la
misma.
movf PORTB,W ;W=PORTB
subwf KEY_2,W ;W=KEY_2-W
btfss STATUS,Z ;Es la misma?
goto KEY_SCAN_1 ;No, seguir con la
exploracion
movf KEY_2,W ;Sí, W=KEY_2
VOLVER:
movwf TECLA ;TECLA=0x80
RETURN ;Retorno de subrutina (Fin de
exploracion)
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
KEY_TABLA: movf KEY_1,W ;W=KEY_1 (Ultimo valor de KEY_1
en la rutina anterior)
addwf PCL,F ;PCL=W+PCL Calcula
desplazamiento
retlw 0x7D ;Tecla 0
retlw 0xEE ;Tecla 1
retlw 0xED ;Tecla 2
retlw 0xEB ;Tecla 3
retlw 0xDE ;Tecla 4
retlw 0xDD ;Tecla 5
retlw 0xDB ;Tecla 6
retlw 0xBE ;Tecla 7
retlw 0xBD ;Tecla 8
retlw 0xBB ;Tecla 9
retlw 0x7E ;Tecla A
retlw 0x7B ;Tecla B
retlw 0x77 ;Tecla C
retlw 0xB7 ;Tecla D
retlw 0xD7 ;Tecla E
retlw 0xE7 ;Tecla F
KEY_HEX:
movf TECLA,W
movwf KEY_2 ;Almacena el código
temporalmente
clrf KEY_1 ;Contador HEX a 0
KEY_HEX_2 call KEY_TABLA ;Busca código
en la tabla
subwf KEY_2,W ;Compara con el de la tecla
btfsc STATUS,Z ;Coincide ?
goto KEY_HEX_1 ;Sí
incf KEY_1,F ;No, incrementa contador HEX
goto KEY_HEX_2
KEY_HEX_1 movf KEY_1,W
movwf TECLA ;Carga contador HEX en la variable de
salida
return
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
LEER_TECLA:
CALL KEY_SCAN
MOVLW 0X80
SUBWF TECLA,0
BTFSC STATUS,Z
GOTO LEER_TECLA
CALL KEY_HEX
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
LEER_ENTER:
CALL LEER_TECLA
MOVLW 0X0C
SUBWF TECLA,0
BTFSS STATUS,Z
GOTO LEER_ENTER
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
PULSO_BAJO:
BCF PORTA,3
CALL LCD_DELAY
CALL LCD_DELAY
CALL LCD_DELAY
CALL LCD_DELAY
BSF PORTA,3
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
LEER_SENTIDO:
CALL LEER_TECLA
MOVLW 0X0F ;HORARIO
SUBWF TECLA,0
BTFSC STATUS,Z
GOTO SALIR_SENTIDO
MOVLW 0X0E ;ANTIHORARIO
SUBWF TECLA,0
BTFSS STATUS,Z
GOTO LEER_SENTIDO
SALIR_SENTIDO:
MOVF TECLA,0
MOVWF SENTIDO
CALL PULSO_BAJO
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
LEER_NUMERO:
CALL LEER_TECLA
MOVLW 0X0A
SUBWF TECLA,0
BTFSC STATUS,Z
GOTO LEER_NUMERO
MOVLW 0X0B
SUBWF TECLA,0
BTFSC STATUS,Z
GOTO LEER_NUMERO
MOVLW 0X0C
SUBWF TECLA,0
BTFSC STATUS,Z
GOTO LEER_NUMERO
MOVLW 0X0D
SUBWF TECLA,0
BTFSC STATUS,Z
GOTO LEER_NUMERO
MOVLW 0X0E
SUBWF TECLA,0
BTFSC STATUS,Z
GOTO LEER_NUMERO
MOVLW 0X0F
SUBWF TECLA,0
BTFSC STATUS,Z
GOTO LEER_NUMERO
SALIR_LEER_NUMERO:
MOVF TECLA,0
MOVWF DIGITO
CALL PULSO_BAJO
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
COMBINAR:
CLRF COMBINADO
MOVF DIGITO_1,0
BTFSC STATUS,Z
GOTO MENOR_DE_DIEZ
LAZO:
MOVLW 0X0A
ADDWF COMBINADO,1
DECFSZ DIGITO_1,1
GOTO LAZO
MOVF DIGITO_2,0
ADDWF COMBINADO,1
SALIR_COMBINAR:
RETURN
MENOR_DE_DIEZ:
MOVF DIGITO_2,0
MOVWF COMBINADO
GOTO SALIR_COMBINAR
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
MOTOR1:
CALL LEER_SENTIDO
MOVF SENTIDO,0
MOVWF SENTIDO_M1
CALL LEER_NUMERO
MOVF DIGITO,0
MOVWF DIGITO_1
CALL LEER_NUMERO
MOVF DIGITO,0
MOVWF DIGITO_2
CALL COMBINAR
MOVF COMBINADO,0
MOVWF NUM_PASOS_M1
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
MOTOR2:
CALL LEER_SENTIDO
MOVF SENTIDO,0
MOVWF SENTIDO_M2
CALL LEER_NUMERO
MOVF DIGITO,0
MOVWF DIGITO_1
CALL LEER_NUMERO
MOVF DIGITO,0
MOVWF DIGITO_2
CALL COMBINAR
MOVF COMBINADO,0
MOVWF NUM_PASOS_M2
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
GIRO_M1:
MOVF NUM_PASOS_M1
BTFSC STATUS,Z
GOTO SALIR_GIRO_M1
MOVLW 0X0F
SUBWF SENTIDO_M1,0
BTFSC STATUS,Z
GOTO GIRO_H_M1
GIRO_A_M1:
BSF PORTA,1
BSF STATUS,C
BTFSS SECUENCIA_M1,7
BCF STATUS,C
RLF SECUENCIA_M1,1
CALL ENVIO
DECFSZ NUM_PASOS_M1,1
GOTO GIRO_A_M1
GOTO SALIR_GIRO_M1
GIRO_H_M1:
BSF PORTA,1
BSF STATUS,C
BTFSS SECUENCIA_M1,0
BCF STATUS,C
RRF SECUENCIA_M1,1
CALL ENVIO
DECFSZ NUM_PASOS_M1,1
GOTO GIRO_H_M1
SALIR_GIRO_M1:
BCF PORTA,1
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
GIRO_M2:
MOVF NUM_PASOS_M2
BTFSC STATUS,Z
GOTO SALIR_GIRO_M2
MOVLW 0X0F
SUBWF SENTIDO_M2,0
BTFSC STATUS,Z
GOTO GIRO_H_M2
GIRO_A_M2
BSF PORTA,2
MOVF CONTADOR,0
BTFSC STATUS,Z
GOTO SALIR_GIRO_M2
DECF CONTADOR,1
BSF STATUS,C
BTFSS SECUENCIA_M2,7
BCF STATUS,C
RLF SECUENCIA_M2,1
CALL ENVIO
DECFSZ NUM_PASOS_M2,1
GOTO GIRO_A_M2
GOTO SALIR_GIRO_M2
GIRO_H_M2:
BSF PORTA,2
MOVLW D'90'
SUBWF CONTADOR,0
BTFSC STATUS,Z
GOTO SALIR_GIRO_M2
INCF CONTADOR,1
BSF STATUS,C
BTFSS SECUENCIA_M2,0
BCF STATUS,C
RRF SECUENCIA_M2,1
CALL ENVIO
DECFSZ NUM_PASOS_M2,1
GOTO GIRO_H_M2
SALIR_GIRO_M2:
BCF PORTA,2
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
ENVIO:
BSF STATUS,5
CLRF PORTB
BCF STATUS,5
MOVLW 0XF0
ANDWF SECUENCIA_M2,0
MOVWF DATO
MOVLW 0X0F
ANDWF SECUENCIA_M1,0
ADDWF DATO,0
MOVWF PORTB
BSF PORTA,0
CALL LCD_DELAY
CALL LCD_DELAY
CALL LCD_DELAY
CALL LCD_DELAY
CALL LCD_DELAY
CALL LCD_DELAY
BCF PORTA,0
RETURN
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
PROGRAMA:
CALL MOTOR1
CALL MOTOR2
CALL LEER_ENTER
CALL GIRO_M1
CALL GIRO_M2
GOTO PROGRAMA
END
Autor:
Profesor: Ing. Jorge Moscoso S.
2003-A