Bueno desde ya unas cosas asi vamos mejorando
Trata de poner el codigo y no una captura asi uno puede copiarlo y modificarlo,es mas facil
Con respecto a la forma de programar, por ahi es simple y mejor escribir el nombre del bit
En ves de INTCON,7 que sea INTCON,GIE
Es mas intuitivo que andar recordando uno por uno cuales eran los bits, el GIE es de Global Interrupt Enable.
EL codigo tiene varias fallas. Asi que voy a intentar nombrarlas y explicarlas a todas
- Una interrupcion puede ocurrir en cualquier momento del programa. Suponete estas instrucciones:
0x41 = SUBLW 0x10
0x42 = BTFSS STATUS,Z
(Le puse valores de memoria para que sea mas facil de explicar)
Mientras se esta ejecutando SUBLW ocurre una interrupcion, al ocurrir una interrupcion se guarda la direccion de la proxima instruccion es decir 0x42 o BTFSS, Observaras que esta instruccion utiliza las banderas Z del STATUS, y que esa bandera depende de la instruccion pasada. Pero bueno entro a la interrupcion, fue a la direccion 0x04, y salto a hacer la interrupcion.
El primer paso que uno debe realizar es... guardar STATUS y W por que cuando salgamos de la interrupcion, todo tiene que seguir como estaba.
Para eso Microchip ofrece en su datasheet un codigo.
interrupcion:
MOVWF W_TEMP
SWAPF STATUS, W
BCF STATUS, RP0
MOVWF STATUS_TEMP
; Aca codigo de la interrupcion
SWAPF STATUS_TEMP, W
MOVWF STATUS
SWAPF W_TEMP, F
SWAPF W_TEMP, W
RETFIE
Lo que hace es tomar 2 registros y guardar W y STATUS en esos registros, y luego los vuelve a su estado original antes que entrara a la interrupcion. Para que el programa siga su curso.
La interrupcion es como un programa completamente aparte, solamente se ejecuta cuando se activa y se sale de alli, el codigo de la interrupcion debe ser rapido, nada de delays, ni funciones que tarden demasiado.
- Activar las interrupciones antes de configurar todo, es otro problema
- No poner el puertoA como digital
Todos los pines con ANx , son analogicos, y comienzan como analogicos en el reset, es tu deber ponerlos como digitales, para eso tenes que poner un 0x07 en CMCON
- La interrupcion del puertoB por cambio de nivel se tiene que borrar leyendo y luego borrando el flag
Para un solo boton, por ahi es mas conveniente la interrupcion del RB0, que es por flanco, ya que sino la interrupcion de nivel entraria tanto si pasa de 0 a 1, o de 1 a 0.
-----------------------
Aunque no se claramente que estas intentando hacer aca un ejemplo de hacer un toggle con el boton, es decir tocas enciende, tocas de nuevo y apaga. Todo realizado con interrupciones de cambio de nivel
#include <P16F628A.inc>
__config 0x3F10
CBLOCK 0x70
STATUS_TEMP
W_TEMP
ENDC
org 0x00
GOTO start
org 0x04
GOTO interrupcion
start:
BANKSEL TRISA ; Selecciono banco donde esta TRISA
CLRF TRISA ; Pongo todo el puerto A como salida
BANKSEL PORTA ; Vuelvo al banco 0, donde esta CMCON y los PORTx
CLRF PORTA ; Pongo a 0 el PORTA
MOVLW 0x07
MOVWF CMCON ; Puerto A todo como digital
MOVF PORTB, W ; Leo el puertoB asi me permite borrar el flag
BCF INTCON, RBIF ; Borro el flag
BSF INTCON, RBIE ; Activo interrupciones
BSF INTCON, GIE
principal: ; Loop principal, aca podrias encender otro led con una demora
GOTO principal
interrupcion:
MOVWF W_TEMP
SWAPF STATUS, W
BCF STATUS, RP0
MOVWF STATUS_TEMP
BTFSC INTCON, RBIF ; Esto lo pongo para que veas como es cuando existen varias interrupciones juntas
CALL int_RB ; En caso de estar en 1 haga este codigo, sino sale
SWAPF STATUS_TEMP, W
MOVWF STATUS
SWAPF W_TEMP, F
SWAPF W_TEMP, W
RETFIE
int_RB
MOVF PORTB, W ; Aca podria comprobar cual de los RB4 a 7 fue el que cambio
BCF INTCON, RBIF ; y de paso leo asi puedo borrar el flag
BTFSS PORTB, 4 ; Pregunto si esta en 1, recorda que entra tanto cuando esta en 0 como en 1
RETURN ; En caso de ser 0 salgo
MOVF PORTA, W
XORLW 0x01 ; Hago una XOR del bit0, si estaba en 0 pasa a 1, si estaba en 1 pasa a 0
MOVWF PORTA ; Actualizo el puerto y salgo
RETURN
END