Hola, nuevamente acudo a la sabiduría de ustedes, estoy implementando por primera vez la interrupción por RX serial, la idea es que mientras no reciba nada este chequeando el estado de ciertos registro y si están en 1 poner la salida que corresponda en alto, y cuando se activa la interrupción recibe una cadena y chequea que tiene que hacer, esos estados son 3 poner a 1 la correspondiente salida, a bajo o poner a 1 el registro que tiene asignada la salida para luego volver a donde estaba y seguir chequeando.
Bien el problema que tengo es que cuando se activa la interrupción hace correctamente todo pero borra lo anterior, es decir que si había recibido la orden de poner a alto la salida A0 y luego recibía la orden de poner a alto la A2, apaga la "0" y enciende la "2", y si le vuelvo a enviar la "0" apaga la "2" y enciende la "0", es como si una vez que sale de la interrupción borrara lo anterior para poner lo nuevo.
Les dejo los archivos para simularlo
Bien el problema que tengo es que cuando se activa la interrupción hace correctamente todo pero borra lo anterior, es decir que si había recibido la orden de poner a alto la salida A0 y luego recibía la orden de poner a alto la A2, apaga la "0" y enciende la "2", y si le vuelvo a enviar la "0" apaga la "2" y enciende la "0", es como si una vez que sale de la interrupción borrara lo anterior para poner lo nuevo.
Les dejo los archivos para simularlo
Código:
;*******************************************************************
LIST P=16F877, R=HEX ; Usar el PIC16F877A y sistema decimal
#include "P16F877A.INC" ; Incluye datos de PIC16F877A
__CONFIG _CP_OFF & _WDT_OFF & _LVP_OFF & _PWRTE_ON & _XT_OSC
;*******************************************************************
; CONFIGURACION
;*******************************************************************
;*******************************************************************
; VARIABLES
;*******************************************************************
W_Temp EQU 0x30
STATUS_Temp EQU 0x40
PDel0A EQU 0x42
PDel1A EQU 0x43
contador EQU 0x52 ; variable
dato_serie EQU 0x53 ; dato serie desde la PC
puerto_a EQU 'A' ;puerto A
digito_0 EQU '0' ;salida puerto 0
digito_1 EQU '1' ;salida puerto 1
digito_2 EQU '2' ;salida puerto 2
caracter_q EQU 'Q' ;encendido
caracter_w EQU 'W' ;apagado
caracter_p EQU 'P' ;parpadea
CONF_ADCON1 EQU b'00000110' ; Configuracion PORTA E/S digital
;*******************************************************************
ORG 0x00 ; El programa empieza en 0x000
goto configuracion
org 0x04 ;Vector de interrupción
goto interrup
;******************************************************************
configuracion
bsf STATUS,RP0 ; Ir banco 1
bcf STATUS,RP1 ;xxxxxx
movlw b'00000000' ; valor inicial portA
movwf PORTA
movlw b'00000000' ; valor inicial portB
movwf PORTB
movlw b'00000000' ; valor inicial portC
movwf PORTC
movlw b'00000000' ; valor inicial portD
movwf PORTD
movlw b'00000000' ; valor inicial portE
movwf PORTE
movlw b'00000000' ; valor portA
movwf PORTA
movlw b'00000000' ; valor portB 0 SALIDA---1 ENTRADA
movwf PORTB
movlw b'10000000' ; valor portC
movwf PORTC
movlw b'00000000' ; valor portD
movwf PORTD
movlw b'00000000' ; valor portE
movwf PORTE
;*******************************************************************
; BAUD RATE para la comunicación RS232
; y otras definiciones para USART
;*******************************************************************
; Baud Rate = 9600, Sin Paridad, 1 Bit parada
movlw 0x19 ; 0x19=9600 bps (0x0C=19200 bps)
movwf SPBRG
movlw b'00100100' ;
movwf TXSTA ; habilita la transmisión Async
bsf PIE1,RCIE ;Habilita interrupción en la recepción
bcf STATUS,RP0 ; Ir banco 0
movlw b'10010000' ; habilita de recepción Async
movwf RCSTA
bsf INTCON,PEIE ;Activa interrupción de periféricos
bsf INTCON,GIE ;Activa interrupciones
;*******************************************************************
; TIEMPO DE ESTABILIZACION
;*****************************************************************
clrf PDel0A
clrf PDel1A
clrf dato_serie
clrf PORTA
clrf PORTB
clrf PORTC
clrf PORTD
clrf PORTE
clrf contador
clrf 0x31
clrf 0x54
clrf 0x55
clrf 0x56
estab decfsz contador,F
goto estab
movf RCREG,W
movf RCREG,W
movf RCREG,W ; vacía el buffer de recepcion
bsf 0x56,6 ;LED_31 ; ESTA EN ALTO PARA PROBAR
;*******************************************************************
;INICIO
;*******************************************************************
inicio
btfsc 0x31,0 ;LED_1
bsf PORTA,0
btfsc 0x31,1 ;LED_2
bsf PORTA,1
btfsc 0x31,2 ;LED_3
bsf PORTA,2
btfsc 0x31,3 ;LED_4
bsf PORTA,3
btfsc 0x31,4 ;LED_5
bsf PORTA,4
btfsc 0x31,5 ;LED_6
bsf PORTA,5
btfsc 0x31,6 ;LED_7
bsf PORTE,0
btfsc 0x31,7 ;LED_8
bsf PORTE,1
btfsc 0x54,0 ;LED_9
bsf PORTE,2
btfsc 0x54,1 ;LED_10
bsf PORTC,0
btfsc 0x54,2 ;LED_11
bsf PORTC,1
btfsc 0x54,3 ;LED_12
bsf PORTC,2
btfsc 0x54,4 ;LED_13
bsf PORTC,3
btfsc 0x54,5 ;LED_14
bsf PORTD,0
btfsc 0x54,6 ;LED_15
bsf PORTD,1
btfsc 0x54,7 ;LED_16
bsf PORTB,7
btfsc 0x55,0 ;LED_17
bsf PORTB,6
btfsc 0x55,1 ;LED_18
bsf PORTB,5
btfsc 0x55,2 ;LED_19
bsf PORTB,4
btfsc 0x55,3 ;LED_20
bsf PORTB,3
btfsc 0x55,4 ;LED_21
bsf PORTB,2
btfsc 0x55,5 ;LED_22
bsf PORTB,1
btfsc 0x55,6 ;LED_23
bsf PORTB,0
btfsc 0x55,7 ;LED_24
bsf PORTD,7
btfsc 0x56,0 ;LED_25
bsf PORTD,6
btfsc 0x56,1 ;LED_26
bsf PORTD,5
btfsc 0x56,2 ;LED_27
bsf PORTD,4
btfsc 0x56,3 ;LED_28
bsf PORTC,5
btfsc 0x56,4 ;LED_29
bsf PORTC,4
btfsc 0x56,5 ;LED_30
bsf PORTD,3
btfsc 0x56,6 ;LED_31
bsf PORTD,2
call DEMORA1
call DEMORA1 ; 300 milisegundos
call DEMORA1
btfsc 0x31,0 ;LED_1
bcf PORTA,0
btfsc 0x31,1 ;LED_2
bcf PORTA,1
btfsc 0x31,2 ;LED_3
bcf PORTA,2
btfsc 0x31,3 ;LED_4
bcf PORTA,3
btfsc 0x31,4 ;LED_5
bcf PORTA,4
btfsc 0x31,5 ;LED_6
bcf PORTA,5
btfsc 0x31,6 ;LED_7
bcf PORTE,0
btfsc 0x31,7 ;LED_8
bcf PORTE,1
btfsc 0x54,0 ;LED_9
bcf PORTE,2
btfsc 0x54,1 ;LED_10
bcf PORTC,0
btfsc 0x54,2 ;LED_11
bcf PORTC,1
btfsc 0x54,3 ;LED_12
bcf PORTC,2
btfsc 0x54,4 ;LED_13
bcf PORTC,3
btfsc 0x54,5 ;LED_14
bcf PORTD,0
btfsc 0x54,6 ;LED_15
bcf PORTD,1
btfsc 0x54,7 ;LED_16
bcf PORTB,7
btfsc 0x55,0 ;LED_17
bcf PORTB,6
btfsc 0x55,1 ;LED_18
bcf PORTB,5
btfsc 0x55,2 ;LED_19
bcf PORTB,4
btfsc 0x55,3 ;LED_20
bcf PORTB,3
btfsc 0x55,4 ;LED_21
bcf PORTB,2
btfsc 0x55,5 ;LED_22
bcf PORTB,1
btfsc 0x55,6 ;LED_23
bcf PORTB,0
btfsc 0x55,7 ;LED_24
bcf PORTD,7
btfsc 0x56,0 ;LED_25
bcf PORTD,6
btfsc 0x56,1 ;LED_26
bcf PORTD,5
btfsc 0x56,2 ;LED_27
bcf PORTD,4
btfsc 0x56,3 ;LED_28
bcf PORTC,5
btfsc 0x56,4 ;LED_29
bcf PORTC,4
btfsc 0x56,5 ;LED_30
bcf PORTD,3
btfsc 0x56,6 ;LED_31
bcf PORTD,2
call DEMORA1
call DEMORA1 ; 300 milisegundos
call DEMORA1
goto inicio
;******************************************************************************************
;Tratamiento de la interrupción
;******************************************************************************
interrup
movwf W_Temp ;Copiamos W a un registro temporario
swapf STATUS,W ;Invertimos los nibles del registro STATUS
movwf STATUS_Temp ;Guardo STATUS en un registro temporario
btfss PIR1,RCIF ;Ha sido interrupción en la recepción ??
retfie ;No, falsa interrupción
bcf PIR1,RCIF ;Si, restaurar el flag de interrupción
call recibeRS232 ; sí, hay
movwf dato_serie ; guarda dato (para uso de cualquier rutina)
goto testeanumero ; llama rutina para testear clave
fin_isr
swapf STATUS_Temp,W
movwf STATUS
swapf W_Temp,f
swapf W_Temp,W
retfie
;***********************************************************************************
; CHEQUEA QUE PIC ES
;***********************************************************************************
testeanumero
movf dato_serie,w ; Guarda el contenido de la tecla pulsada.
xorlw digito_1 ; ¿Es el pic 1?
btfsc STATUS,Z
goto pic_1 ; Sí, se procede a chequear el puerto
goto fin_isr
;***********************************************************************************
; CHEQUEAR QUE PUERTO ES
;***********************************************************************************
pic_1
movf RCREG,W ; Borra el buffer
loopi btfss PIR1,RCIF ; (5) se fija si hay dato RS232
goto loopi ; no, no llegó
call recibeRS232 ; sí, hay
movwf dato_serie ; Guarda el contenido de la tecla pulsada.
xorlw puerto_a ; ¿Es el puerto A?
btfsc STATUS,Z
goto port_a ; Sí, se procede a chequear el bit
goto fin_isr
;***********************************************************************************
; CHEQUEAR QUE BIT ES DEL PUERTO A
;***********************************************************************************
port_a
movf RCREG,W ; Borra el buffer
loopo btfss PIR1,RCIF ; (5) se fija si hay dato RS232
goto loopo ; no, no llegó
call recibeRS232 ; sí, hay
movwf dato_serie ; Guarda el contenido de la tecla pulsada.
xorlw digito_0 ; ¿Es la salida 0?
btfsc STATUS,Z
goto a_0 ; Sí, se procede a chequear la accion
movf dato_serie,W ; Recupera el contenido de la tecla pulsada.
xorlw digito_1 ; ¿Es la salida 1?
btfsc STATUS,Z
goto a_1 ; Sí, se procede a chequear la accion
movf dato_serie,W ; Recupera el contenido de la tecla pulsada.
xorlw digito_2 ; ¿Es la salida 2?
btfsc STATUS,Z
goto a_2 ; Sí, se procede a chequear la accion
goto fin_isr
;***********************************************************************************
; CHEQUEAR LA ACCION DEL PUERTO A
;***********************************************************************************
a_0
movf RCREG,W ; Borra el buffer
loopp btfss PIR1,RCIF ; (5) se fija si hay dato RS232
goto loopp ; no, no llegó
call recibeRS232 ; sí, hay
movwf dato_serie ; Recupera el contenido de la tecla pulsada.
xorlw caracter_q ; ¿Es el caracter Q? ENCENDIDO
btfsc STATUS,Z
bsf PORTA,0 ;LED_1
movf dato_serie,W ; Recupera el contenido de la tecla pulsada.
xorlw caracter_w ; ¿Es el caracter W? APAGADO
btfsc STATUS,Z
bcf PORTA,0 ;LED_1
bcf 0x31,0
movf dato_serie,W ; Recupera el contenido de la tecla pulsada.
xorlw caracter_p ; ¿Es el caracter P? PARPADEA
btfsc STATUS,Z
bsf 0x31,0 ; Sí,
goto fin_isr
a_1
movf RCREG,W ; Borra el buffer
l_oopp btfss PIR1,RCIF ; (5) se fija si hay dato RS232
goto l_oopp ; no, no llegó
call recibeRS232 ; sí, hay
movwf dato_serie ; Recupera el contenido de la tecla pulsada.
xorlw caracter_q ; ¿Es el caracter Q? ENCENDIDO
btfsc STATUS,Z
bsf PORTA,1 ;LED_2
movf dato_serie,W ; Recupera el contenido de la tecla pulsada.
xorlw caracter_w ; ¿Es el caracter W? APAGADO
btfsc STATUS,Z
bcf PORTA,1 ;LED_2
bcf 0x31,1
movf dato_serie,W ; Recupera el contenido de la tecla pulsada.
xorlw caracter_p ; ¿Es el caracter P? PARPADEA
btfsc STATUS,Z
bsf 0x31,1 ; Sí,
goto fin_isr
a_2
movf RCREG,W ; Borra el buffer
lo_opp btfss PIR1,RCIF ; (5) se fija si hay dato RS232
goto lo_opp ; no, no llegó
call recibeRS232 ; sí, hay
movwf dato_serie ; Recupera el contenido de la tecla pulsada.
xorlw caracter_q ; ¿Es el caracter Q? ENCENDIDO
btfsc STATUS,Z
bsf PORTA,2 ;LED_3
movf dato_serie,W ; Recupera el contenido de la tecla pulsada.
xorlw caracter_w ; ¿Es el caracter W? APAGADO
btfsc STATUS,Z
bcf PORTA,2 ;LED_3 ; Sí,
bcf 0x31,2
movf dato_serie,W ; Recupera el contenido de la tecla pulsada.
xorlw caracter_p ; ¿Es el caracter P? PARPADEA
btfsc STATUS,Z
bsf 0x31,2 ; Sí,
goto fin_isr
;***********************************************************************************
; ENVIA CARACTER SERIE - RS232 - A LA Placa Y ESPERA A QUE HAYA SALIDO
;***********************************************************************************
enviaRS232
movwf TXREG ; envío el dato en acunulador w
bsf STATUS,RP0 ; Pág 1 RAM
Espere btfss TXSTA,TRMT ; transmision completa si es alto
goto Espere
bcf STATUS,RP0 ; Pág 0 RAM
return
;***********************************************************************************
; RECIBE CARACTER SERIE - RS232 - DESDE LA PC
;***********************************************************************************
recibeRS232
movf RCREG,W ; guarda dato recibido en acumulador
return
;-------------------------------------------------------------
; TEMPORIZADOR 100 MS
;-------------------------------------------------------------
DEMORA1 movlw .110 ; 1 set numero de repeticion (B)
movwf PDel0A ; 1 |
PLoop1A movlw .181 ; 1 set numero de repeticion (A)
movwf PDel1A ; 1 |
PLoop2A clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1A,1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2A ; 2 no, loop
decfsz PDel0A,1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1A ; 2 no, loop
PDelL1A goto PDelL2A ; 2 ciclos delay
PDelL2A goto PDelL3A ; 2 ciclos delay
PDelL3A clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
END