Estoy creando un temporizador con el PIC16F887, algunos botones y pantallas de siete segmentos. Estoy escribiendo el código en ensamblaje, y todo funciona muy bien, excepto el botón de inicio / parada que se maneja como parte de una rutina de servicio de interrupción. La rutina de servicio complementa la variable RUN que inicia el temporizador / incrementador. La rutina de incremento se omite si el bit de RUN menos significativo es 0. Puedo iniciar el temporizador, pero no puedo detenerlo. Borro el indicador INTF en el registro INTCON dentro del ISR, pero parece que el ISR sigue deshabilitado.
;******************************************************
;PIC Configuration for PIC16F887
#include "p16F887.inc"
; CONFIG1
; __config 0x2032
__CONFIG _CONFIG1, _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_ON & _CPD_ON & _BOREN_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF
; CONFIG2
; __config 0x3FFF
__CONFIG _CONFIG2, _BOR4V_BOR40V & _WRT_OFF
;******************************************************
DCOUNT EQU 20H
CNT_100th EQU 21H ; counter for 0.01s
CNT_10th EQU 22H ; counter for 0.1s
CNT_sec EQU 23H ; counter for seconds
CNT_10sec EQU 24H ; counter for tens of seconds
CNT_min EQU 25H ; counter for minutes
CNT_10min EQU 26H ; counter for tens of minutes
RUN EQU 70H ;the run variable that does stuff to things
OCOUNT EQU 28H
ICOUNT EQU 29H
ORG 000H
GOTO MAIN
ORG 004H
GOTO ISR
ORG 008H
GOTO LOOP
;*******************************************************
MAIN
CLRF STATUS
CLRF CNT_100th
CLRF CNT_10th
CLRF CNT_sec
CLRF CNT_10sec
CLRF CNT_min
CLRF CNT_10min
CLRF RUN
BSF STATUS,RP1 ;change to bank 3
BSF STATUS,RP0
CLRF ANSEL ;Using all digital mode, turns off analog
CLRF ANSELH ;Make all analog ports digital
BCF STATUS,RP1 ;change to correct bank to configure TRIS registers
;MAKE RA0 OUTPUT, RB0 INPUT, PORTC AND PORTD ALL OUTPUTS
CLRF TRISA
CLRF TRISB
COMF TRISB,1
CLRF TRISD
CLRF INTCON
BSF INTCON,7
BSF INTCON,4
MOVLW 040H
MOVWF OPTION_REG
BCF STATUS,RP0
GOTO LOOP
LOOP
MOVF CNT_100th,0 ; Put count of 1/100ths of second in W
CALL TABLE ; Get value to write out to PORTD from table
MOVWF PORTD ; Put value out to PORTD
BCF PORTA,5 ; Turn on and off display to show digit
CALL DELAY
BSF PORTA,5
MOVF CNT_10th,0 ; Put count of 1/100ths of second in W
CALL TABLE ; Get value to write out to PORTD from table
MOVWF PORTD ; Put value out to PORTD
BCF PORTA,4 ; Turn on and off display to show digit
CALL DELAY
BSF PORTA,4
MOVF CNT_sec,0 ; Put count of 1/100ths of second in W
CALL TABLE ; Get value to write out to PORTD from table
MOVWF PORTD ; Put value out to PORTD
BCF PORTA,3 ; Turn on and off display to show digit
CALL DELAY
BSF PORTA,3
MOVF CNT_10sec,0 ; Put count of 1/100ths of second in W
CALL TABLE ; Get value to write out to PORTD from table
MOVWF PORTD ; Put value out to PORTD
BCF PORTA,2 ; Turn on and off display to show digit
CALL DELAY
BSF PORTA,2
MOVF CNT_min,0 ; Put count of 1/100ths of second in W
CALL TABLE ; Get value to write out to PORTD from table
MOVWF PORTD ; Put value out to PORTD
BCF PORTA,1 ; Turn on and off display to show digit
CALL DELAY
BSF PORTA,1
MOVF CNT_10min,0 ; Put count of 1/100ths of second in W
CALL TABLE ; Get value to write out to PORTD from table
MOVWF PORTD ; Put value out to PORTD
BCF PORTA,0 ; Turn on and off display to show digit
CALL DELAY
BSF PORTA,0
CALL WAIT
BTFSC RUN,0
CALL INCCNT
GOTO LOOP
WAIT
MOVLW 08H
MOVWF OCOUNT
MOVLW 0FFH
MOVWF ICOUNT
OLOOP
ILOOP
DECFSZ ICOUNT,1
GOTO ILOOP
DECFSZ OCOUNT,1
GOTO OLOOP
RETURN
ISR
COMF RUN,1
BCF INTCON,1
RETFIE
Cualquier orientación sería muy apreciada aquí. Mi sospecha es que hay algo en la forma en que he estructurado el programa que está causando este error.
Actualizar
Resolví el problema borrando los siguientes registros asociados con PORTB:
- CCP1CON
- IOCB
- WPUB
También reformateé el código de acuerdo con algunos de los estrictos consejos a continuación, y el PIC que estoy usando tiene registros ANSEL y ANSELH. Está ahí, en blanco y negro, en la hoja de datos .
Gracias a todos