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