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
valorinicial?
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 rutinaanterior)
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