Problema RSI RB0/INT PIC16F84A

Hola. Me estoy volviendo loco. No doy con la solución y no sé qué hago mal.
Les agradecería un poco de ayuda.

Les explico. Estoy haciendo un programa algo más complejo para la universidad pero he hecho un programa sencillo para comprobar si funcionaba o no la rutina de servicio de interrupciones por la patilla RB0 y nada.

Se trata básicamente de un bucle que va incrementando una variable, de uno en uno, hasta que pulsas el botón.
Entonces debe mostrar el valor de dicha variable de manera intermitente, apagando y encendiendo un display de 7 segmentos tres veces.
Cuando termina, debe volver al bucle hasta que reciba otro estímulo por la patilla RB0/INT.

Aquí les dejo el código.
PHP:
list            p=16F84A
            #include    <P16F84A.inc>
            radix            HEX

VALOR        equ        0x30
TMP            equ        0x31
TMP1        equ        0x32
TMP2        equ        0x33
TMP3        equ        0x34

            org        0x00
            goto            Inicio
            org        0x04
            goto            RSI

Display        addwf    PCL,1
            retlw            b'01111110';0
            retlw            b'00001100';1
            retlw            b'01101110';2
            retlw            b'10011110';3
            retlw            b'10111100';4
            retlw     b'10111010';5
            retlw            b'11111000';6
            retlw            b'00001110';7
            retlw            b'11111110';8
            retlw            b'10011110';9

Inicio        bsf        STATUS,RP0
            movlw    b'00000001'
            movwf    TRISA
            movwf    TRISB
            bsf        OPTION_REG,6
            movlw    b'10010000'
            movwf    INTCON
            bcf        STATUS,RP0
            clrf            PORTA
            clrf            PORTB
            movlw    d'3'
            movwf    VALOR

Bucle        incf            VALOR,1
            movlw    d'10'
            subwf    VALOR,0
            btfsc            STATUS,Z
            clrf            VALOR
            goto            Bucle

RSI            btfsc            INTCON,INTF
            goto            INTRB0
            retfie    

INTRB0        bcf        INTCON,INTF
            call            Mostrar
            call            MedioS
            call            Apagar
            call            MedioS
            call            Mostrar
            call            MedioS
            call            Apagar
            call            MedioS
            call            Mostrar
            call            MedioS
            call            Apagar
            call            MedioS
            retfie

Mostrar        movf            VALOR,0
            call            Display
            movwf    PORTB
            return

Apagar        movlw    b'00000000'
            movwf    PORTB
            call            Delay
            return

Delay        movlw    d'250'
            movwf    TMP
Atras                decfsz    TMP,1
            goto            Atras
            return

MedioS        movlw    d'20'
            movwf    TMP1
Atras3        movlw    d'50'
            movwf    TMP2
Atras2        movlw    d'250'
            movwf    TMP3
Atras1        decfsz    TMP3,1
            goto            Atras1
            decfsz    TMP2,1
            goto            Atras2
            decfsz    TMP1,1
            goto            Atras3
            return

            end


He probado ya tropecientas posibilidades y nada. Gracias de antemano.
 

Adjuntos

  • Sin título.jpg
    Sin título.jpg
    88.7 KB · Visitas: 7
Última edición por un moderador:
Hola Mr.
Tiene algunos errores su código:

No críticos:
- Su programa nunca mostrará el cero.
- Los valores de la tabla para su display CC son erróneas.
- No veo la palabra de configuración. Asegúrese de deshabilitar el WDT

Crítico:
- Durante la interrupción, en algún momento VALOR = 10, lo cual desbordará su tabla y la pila.

Sí, tal vez me dirá que lo está poniendo a cero por programa, pero ese proceso lleva unas instrucciones.
Durante esas instrucciones puede generarse la interrupción. Debe tener más cuidado.

Su programa debe funcionar, aunque con algunos errores como le expliqué. Asegúrese de deshabilitar el WDT y de usar un display de cátodo común.

Saludos.
 
Última edición por un moderador:
Hola, gracias por su respuesta. Dice que el programa debe funcionar, ¿quiere decir eso que el problema estaría en la simulación?

He modificado los errores que mencionó. Aquí está el código corregido:

PHP:
			list		p=16F84A
			#include	<P16F84A.inc>
			radix		HEX

			__CONFIG	_CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON

VALOR		equ		0x30
TMP			equ		0x31
TMP1		equ		0x32
TMP2		equ		0x33
TMP3		equ		0x34

			org		0x00
			goto	Inicio
			org		0x04
			goto	RSI

Display		addwf	PCL,1
			retlw	b'01111110';0
			retlw	b'00001100';1
			retlw	b'10110110';2
			retlw	b'10011110';3
			retlw	b'11001100';4
			retlw	b'11011010';5
			retlw	b'11111010';6
			retlw	b'00001110';7
			retlw	b'11111110';8
			retlw	b'11011110';9
			retlw	b'01111110';10->0

Inicio		bsf		STATUS,RP0
			movlw	b'00000001'
			movwf	TRISA
			movwf	TRISB
			bcf		OPTION_REG,6
			movlw	b'10010000'
			movwf	INTCON
			bcf		STATUS,RP0
			clrf	PORTA
			clrf	PORTB
			movlw	d'3'
			movwf	VALOR

Bucle		incf	VALOR,1
			movlw	d'10'
			subwf	VALOR,0
			movlw	d'0'
			btfsc	STATUS,Z
			movwf	VALOR
			goto	Bucle

RSI			btfsc	INTCON,INTF
			goto	INTRB0
			retfie	

INTRB0		bcf		INTCON,INTF
			movf	VALOR,0
			call	Mostrar
			call	MedioS
			call	Apagar
			call	MedioS
			call	Mostrar
			call	MedioS
			call	Apagar
			call	MedioS
			call	Mostrar
			call	MedioS
			call	Apagar
			call	MedioS
			retfie

Mostrar		movf	VALOR,0
			call	Display
			movwf	PORTB
			return

Apagar		movlw	b'00000000'
			movwf	PORTB
			call	Delay
			return

Delay		movlw	d'250'
			movwf	TMP
Atras		decfsz	TMP,1
			goto	Atras
			return

MedioS		movlw	d'20'
			movwf	TMP1
Atras3		movlw	d'50'
			movwf	TMP2
Atras2		movlw	d'250'
			movwf	TMP3
Atras1		decfsz	TMP3,1
			goto	Atras1
			decfsz	TMP2,1
			goto	Atras2
			decfsz	TMP1,1
			goto	Atras3
			return

			end

Gracias de nuevo, saludos.
 
Hola

PHP:
list        p=16F84A 
            #include    <P16F84A.inc> 
            radix        HEX 
 
            __CONFIG    _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON 
 
VALOR       equ        0x30 
TMP         equ        0x31 
TMP1        equ        0x32 
TMP2        equ        0x33 
TMP3        equ        0x34 
 
SAVE_W        equ            0x35
SAVE_STATUS equ            0x36
 
            org        0x00 
            goto    Inicio 
            org        0x04 
            goto    RSI 
 
Display     addwf    PCL,1 
            retlw    b'01111110';0 
            retlw    b'00001100';1 
            retlw    b'10110110';2 
            retlw    b'10011110';3 
            retlw    b'11001100';4 
            retlw    b'11011010';5 
            retlw    b'11111010';6 
            retlw    b'01001110';7 
            retlw    b'11111110';8 
            retlw    b'11011110';9 
            retlw    b'01111110';10->0 
 
Inicio      bsf        STATUS,RP0 
            movlw    b'00000001' 
            movwf    TRISA 
            movwf    TRISB 
            bcf        OPTION_REG,6 
            bcf     STATUS,RP0 
            movlw    b'10010000' 
            movwf    INTCON 
 
            clrf    PORTA 
            clrf    PORTB 
            movlw    d'3' 
            movwf    VALOR 
 
Bucle       incf    VALOR,1 
            movlw    d'10' 
            subwf    VALOR,0 
            btfsc    STATUS,Z 
            clrf    VALOR 
            goto    Bucle 
 
RSI         btfsc    INTCON,INTF 
            goto    INTRB0 
            retfie     
 
INTRB0      movwf    SAVE_W
            movf    STATUS,W
            movwf   SAVE_STATUS
 
            call    Mostrar 
            call    MedioS 
            call    Apagar 
            call    MedioS 
            call    Mostrar 
            call    MedioS 
            call    Apagar 
            call    MedioS 
            call    Mostrar 
            call    MedioS 
            call    Apagar 
            call    MedioS 
 
            movf    SAVE_STATUS,W
            movwf    STATUS
            swapf    SAVE_W,F
            swapf    SAVE_W,W        
            bcf        INTCON,INTF 
            retfie 
 
Mostrar        movf    VALOR,0 
            call    Display 
            movwf    PORTB 
            return 
 
Apagar        movlw    b'00000000' 
            movwf    PORTB 
            call    Delay 
            return 
 
Delay        movlw    d'250' 
            movwf    TMP 
Atras        decfsz    TMP,1 
            goto    Atras 
            return 
 
MedioS        movlw    d'20' 
            movwf    TMP1 
Atras3        movlw    d'50' 
            movwf    TMP2 
Atras2        movlw    d'250' 
            movwf    TMP3 
Atras1        decfsz    TMP3,1 
            goto    Atras1 
            decfsz    TMP2,1 
            goto    Atras2 
            decfsz    TMP1,1 
            goto    Atras3 
            return 
 
            end

Le agregue el proceso de context.
 

Adjuntos

  • sim.PNG
    sim.PNG
    8.1 KB · Visitas: 6
Última edición por un moderador:
Después de todo no sé muy bien que es lo que pasaba. He hecho otro proyecto de Proteus y arreglado.

picasion.com_35c43db93d9979ba8c8f141269eafb6b.gif

Gracias por tu colaboración @AngryGirl.
 
Última edición:
Hola.
Qué bueno que lo hayas solucionado, pero no olvides el proceso de context. (Guardar y devolver valores de registros críticos)

Saludos.
 
Última edición por un moderador:
Arriba