Hola a todos y gracias de antemano.
Estoy programando un PIC16F628A para controlar la maqueta de un pequeño ascensor desde el PC.
Desde el PC le envío uno de los siguientes caracteres para que entienda lo siguiente:
A - Activar el sistema.
P - Parar el sistema.
D - Para que el PIC envíe el estado de sus entradas y salidas (PORTA y PORTB).
Las dos primeras funciones las entiende y las cumple perfectamente, pero la última (D) sólo la ejecuta cuando el sistema está parado. Cuando está activo parece que ni siquiera entra en la interrupción.
Les dejo la parte del código a ver si detectan algún fallo y me pueden echar un cable.
Gracias de antemano.
;****************************************************************************************
;** DECLARACIONES E INICIO DEL PROGRAMA **
;****************************************************************************************
INCLUDE <P16F628A.INC>
LIST P=16f628A ;Procesador utilizado.
LIST R=hex ;Trabajo en numeracion hexadecimal.
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _LVP_OFF
;********************************* MAPA DE MEMORIA **********************************
dato equ 0x24
activo equ 0x25
A equ 0x26
P equ 0x27
D equ 0x28
CBLOCK 0x29
W_Temp ;guarda el valor del WREG durante la interrupción.
Status_Temp ;guarda el valor del STATUS durante la interrupción.
Pclath_Temp ;guarda el valor del PCLATH (Program counter) durante la int.
ENDC
;************************************* INICIO ***************************************
reset ORG 0x00 ; El programa comienza en la dirección 0.
GOTO inicio
ORG 0x04 ; Cuando se da una interrupción, vamos a la rutina RSI
GOTO RSI ; (RUTINA DE SERVICIO DE INTERRUPCIÓN)
ORG 0x05
inicio
;************************************ CONFIGURACIONES ***********************************
;.......1. Configuración de puertos I/O.................................... ..................
Bank1 ; Cambiamos al banco 1 de memoria.
MOVLW b'11000011' ; 4 entradas (RA1, RA0, RA7 Y RA6 = pulsadores de llamada),
MOVWF TRISA
MOVLW b'11110010' ; 4 entradas (Sensores REED)
MOVWF TRISB ; 2 salidas (RB3 no se usará, RB2 se usará como TX)
Bank0 ; Cambiamos al banco 0 de memoria.
MOVLW b'11111111' ; inicialmente ponemos todas las entradas a 1 (apagamos los LED).
MOVWF PORTA
MOVLW b'11111001' ; inicialmente ponemos todas las entradas a 1 (apagamos los LED).
MOVWF PORTB
BCF PORTA,2 ;paro el motor hacia abajo
BCF PORTA,3 ;paro el motor hacia arriba
;[...]
;.......3. Habilitamos las interrupciones ....................................................
BSF INTCON,GIE ; Habilitamos permiso global de las interrupciones.
BSF INTCON,PEIE ; Que sean interrupciones para periféricos no controlados con INTCON.
Bank1 ; Cambiamos al BANCO 1.
BSF PIE1, RCIE ; Habilitamos las interrupciones para RECEPCIÓN DE DATOS.
Bank0 ; Volvemos al BANCO 0.
;.......4. Configuración de la conexión serial................................................
Bank1 ; Cambiamos al BANCO 1.
BCF TRISB,2 ; Configura el pin RB2 (TX) como salida
BSF TRISB,1 ; Configura el pin RB1 (RX) como entrada
Bank0 ; Volvemos al BANCO 0.
BSF RCSTA,SPEN ; Habilita el puerto serial
BSF RCSTA,CREN ; Enable continuous reception
Bank1 ; Cambiamos al banco 1 de memoria.
BSF TXSTA,TXEN ; Enable transmit
BSF TXSTA,BRGH ; Select high baud rate
; Trabajamos a 4 Mhz y 9600 bauds -> 25,
; (Si fuera 2400 bauds -> 103)
MOVLW .25 ; 9600 baud @ 4 MHz
MOVWF SPBRG
Bank0 ; Volvemos al banco 0 de memoria.
;.......5. Inicialización de registros .......................................................
CLRF activo ;inicialmente mantenemos inactivo el proceso.
MOVLW 0x41 ;Asignamos al registro A su valor en Hexadecimal (ASCII).
MOVWF A
MOVLW 0x50 ;Asignamos al registro P su valor en Hexadecimal (ASCII).
MOVWF P
MOVLW 0x44 ;Asignamos al registro D su valor en Hexadecimal (ASCII).
MOVWF D
;*******************************************************************
;** RUTINA PRINCIPAL **
;*******************************************************************
principio nop
BTFSS activo,1 ;salta la siguiente linea si se solicita activar el proceso.
GOTO parada ;si no, esperamos.
;[...]
GOTO principio
;***********************************************************
;** RUTINA DE PARADA **
;***********************************************************
;Esta subrutina inicializa los puertos I/O para parar el sistema
parada nop
MOVLW b'11111111' ; inicialmente ponemos todas las entradas a 1 (apagamos los LED).
MOVWF PORTA
MOVLW b'11111111' ; inicialmente ponemos todas las entradas a 1 (apagamos los LED).
MOVWF PORTB
BCF PORTA,2 ;paro el motor hacia abajo
BCF PORTA,3 ;paro el motor hacia arriba
GOTO principio
;=========================================================================
;== RUTINA DE ATENCIÓN A LA INTERRUPCIÓN ==
;== "RECEPCIÓN DE DATOS" ==
;=========================================================================
; Creamos una rutina que se encargue de recibir los datos de la UART.
RSI:
;.........................................................................................
; 1. Guardamos la configuración del sistema para dejarla como estaba
; antes de la interrupción
MOVWF W_Temp ; Guarda el valor de W en W_Temp
MOVF STATUS,W ; Guarda el valor de STATUS en W
MOVWF Status_Temp ; Guarda el valor de STATUS en Status_Temp
MOVF PCLATH,W ; Guarda PCLATH en WREG
MOVWF Pclath_Temp ; Guarda el valor de PCLATH
CLRF PCLATH ; Selecciona el PC en la pos 0
;.........................................................................................
;.......2. Comprobamos que la interrupción fue correcta...................................
Bank0 ; Nos colocamos en eL banco 0, por si a caso.
BTFSS PIR1,RCIF ; ¿la interrupción ha sido provocada por RECEPCIÓN UART?
GOTO FIN_RSI ; Si es que si, saltamos la linea y la atendemos.
; Si no, vamos al final.
;.......3. Rescatamos el dato que recibimos................................................
MOVF RCREG,W ; si hay dato, lo movemos a W y
MOVWF dato ; luego lo guardamos en "dato"
;.......4. Enviamos lo recibido............................................................
Bank1 ; Cambiamos al BANCO 1
EsperaUart
BTFSS TXSTA,TRMT ; Testeamos hasta que el registro de transmisión
GOTO EsperaUart ; quede libre.
Bank0 ; Volvemos al BANCO 0
MOVF dato,W
MOVWF TXREG ; Enviar lo que hay en W por la UART
;..........................................................................................
;.......5. Observamos qué es lo que se solicita............................................
SUBWF A,0 ; Si la letra recibida por UART es A --> Activamos el proceso.
BTFSC STATUS,Z
BSF activo,1
MOVF dato,W
SUBWF P,0 ; Si la letra recibida por UART es P --> Paramos el proceso
BTFSC STATUS,Z
BCF activo,1
MOVF dato,W
SUBWF D,0 ; Si la letra recibida por UART es D --> Enviamos datos
BTFSS STATUS,Z
GOTO FIN_RSI ; Si no, vamos al final de la RSI.
;ENVIAMOS DATOS ****************************************************************
;.......... Primero enviamos CABECERA ('H')........................
Bank1 ; Cambiamos al BANCO 1
EsperaUartH
BTFSS TXSTA,TRMT ; Testeamos hasta que el registro de transmisión
GOTO EsperaUartH ; quede libre.
Bank0 ; Volvemos al BANCO 0
MOVLW 0x48 ; Mueve el valor 48hex (H) al acumulador.
MOVWF TXREG ; Enviar lo que hay en W por la UART
;..................................................................
;............... Enviamos el PORTA ................................
Bank1 ;Cambiamos al BANCO 1
EsperaUart1
BTFSS TXSTA,1 ; Testeamos hasta que el registro de transmisión
GOTO EsperaUart1 ; quede libre.
Bank0 ; Volvemos al BANCO 0
MOVF PORTA,0 ; Mueve el estado del PORTA al W.
MOVWF TXREG ; Enviar lo que hay en W por la UART
;..................................................................
;................ Luego enviamos el PORTB ......................
Bank1 ;Cambiamos al BANCO 1
EsperaUart2
BTFSS TXSTA,1; Testeamos hasta que el registro de transmisión
GOTO EsperaUart2 ; quede libre.
Bank0 ; Volvemos al BANCO 0
MOVF PORTB,0 ; Mueve el estado del PORTB al W.
MOVWF TXREG ; Enviar lo que hay en W por la UART
;..................................................................
;********************************************************************************
FIN_RSI
Bank0
MOVF Pclath_Temp,W ;devolvemos el valor anterior del PCLATH
MOVWF PCLATH
MOVF Status_Temp,W ;devolvemos el valor anterior del STATUS
MOVWF STATUS
SWAPF W_Temp,F ;devolvemos el valor anterior del WREG
SWAPF W_Temp,W
BCF PIR1,RCIF ; Limpio la bandera de la interrupción del UART
RETFIE ;Regresamos
;========================================================================================