# Problema con interrupciones en PIC



## TeEstoyMirando (Ene 30, 2006)

Hola buenas. Tengo un problema con las interrupciones en un micro.

el programa es el siguiente


```
LIST P=16f877 ; Tipo del PIC

STATUS EQU 03
INTCON EQU 0B
PORTB EQU 06
TRISB EQU 06

ORG 00
GOTO INICIO
ORG 04
GOTO INTER
ORG 05

INICIO
BSF STATUS,5
MOVLW 0XFF 
MOVWF TRISB ; Configurar Puerto B 
BSF INTCON,3 ; Interrupcion RB47
BSF INTCON,7 ; Interrupcion General.
BCF STATUS,5 

INICIO2
SLEEP 
NOP
NOP
NOP
GOTO INICIO2

INTER
BCF INTCON,0 ;NO ME LA REALIZA....!!!!!!
BSF INTCON,7

RETURN

END
```


Pues resulta que no me pone a cero el bit cero dentro de la interrupcion al registro intcon. No tengo ni idea de a que se debe pero tiene toda la pinta de ser una tonteria pero no doy con ello.

Le agradeceria que me dijeran que es lo que ocurre Muchas gracias un saludo

Me esta costando un mundo


----------



## fdesergio (Ene 30, 2006)

```
LIST P=16f877 ; Tipo del PIC

STATUS EQU 03
INTCON EQU 0B
PORTB EQU 06
TRISB EQU 06

ORG 00
GOTO INICIO
ORG 04
GOTO INTER
ORG 05

INICIO
BSF STATUS,5
MOVLW 0XFF
MOVWF TRISB ; Configurar Puerto B
BSF INTCON,3 ; Interrupcion RB47
BSF INTCON,7 ; Interrupcion General.
BCF STATUS,5
```


*Intenta asi:*


```
INICIO2
SLEEP
NOP
NOP
NOP
GOTO INICIO2

INTER
BCF INTCON,7    ;por sugerencia de Microchip deshabilitar las INTs
BCF INTCON,0    ;NO ME LA REALIZA....!
BSF INTCON,7

RETURN            ;para salir de INTER debes usar RETFIE no RETURN

END
```


----------



## TeEstoyMirando (Ene 31, 2006)

No hay manera amigo. Al entrar en la interrupcion no me pone a cero el bit cero correspondiente al RBIF del registro INCONT.

Este bit indica el cambio de estado en un bit comprendido entre el RB4 a RB7 del puerto B. Entonces si no consigo ponerlo a cero me indica que esta siempre habilitada (mas bien ejecutada) esa interrupcion en perjuicio del codigo siguiente.

No entiendo porque no soy capaz de ponerlo a cero si en el mismo manual del controlador dice que para cambiar su valor se realiza mediante software. 

Estoy desesperado porque necesito realizar esta operacion y sé que se tiene que poder.

Agradeceria cualquier tipo de ayuda.

Un saludo y gracias.


----------



## fdesergio (Ene 31, 2006)

enviame el codigo completo y trato de ayudarte, chauuuuuuuuuuu


----------



## TeEstoyMirando (Ene 31, 2006)

El que esta ahi. Si me consigues que se me ponga a cero no necesito mas jejeje. 
El problema es ese nada mas.

Muchas gracias por tu interes.


----------



## fdesergio (Ene 31, 2006)

Oye es para mirar todo el codigo, pues lo que esta aca no tiene ningun problema, si desconfias para enviar el codigo este no es realmente el sitio para tus consultas pues nadie te va ayudar solo con eso, suerte.


----------



## TeEstoyMirando (Feb 1, 2006)

No, me estas malinterpretando. Yo te lo decia para facilitar el trabajo ya que el programa lo hice yo mas sencillo para que alguien me diera una solucion al problema exacto. De que te sirve que te envie 3 asm ligados con multitud de codigo que no tiene nada que ver con el problema si te lo puedo simplificar en un programa sencillo?

Si te interesa el codigo completo te lo paso si ningun problema jajaja pero que sepas que esta patentado (es broma). 
Es el control de un garaje a traves de dos sensores con un contador para coches y unas luces de control.

¿Dices que ya esta solucionado en ese que pongo en la pagina y me da pensar que a lo mejor pueda ser algo de configuracion del MPLAB?.


EDITADO
********
Pues va ser que es la version del MPLAB. Tengo actualmente instalada la MPLAB IDE v7.30 y no funciona. No pone a cero el bit que antes digo.

En cambio en la version 6.20 si me lo hace. 


Me interesaría que la gente que lo probara y le funcionara me dijera la version exacta que tien del MPLAB

Un saludo y gracias.


----------



## fdesergio (Feb 1, 2006)

Disculpa si te malinterprete, mira a veces los problemas sencillos son raros porque buscas donde no estan, si tengo un problema en las INTs busco en la rutina de interrupciones o no? bueno pero si configuras mal el INTCON, o el OPTION tambien te falla me explico?? no veo la configuracion del OPTION en el programa para saber las RBPU como estan  puedes tener una falla por ahi, en fin puede ser y de hecho lo es una cosita sencilla, por otro lado la version de l MPLab no te afecta para nada, yo uso varias versiones y funcionan igual, espero te sirva, chauuuuuuuuuuu


----------



## TeEstoyMirando (Feb 2, 2006)

Bueno, ya solucione el problema, aunque mas bien me lo solucionaron. Lalo_soft me dijo que pusiera la instruccion delante del borrado del  intcon "MOVF portB,f" y a continuacion por arte de magia me lo borra jeje.

Solucionado. Gracias de todas maneras.


----------



## maunix (Feb 2, 2006)

TeEstoyMirando dijo:
			
		

> Bueno, ya solucione el problema, aunque mas bien me lo solucionaron. Lalo_soft me dijo que pusiera la instruccion delante del borrado del  intcon "MOVF portB,f" y a continuacion por arte de magia me lo borra jeje.
> 
> Solucionado. Gracias de todas maneras.




A ver, te quiero ayudar pero a 'entender' lo que te ha ocurrido.  Pongamos algunas cosas en claro.

1) El Mplab 6.2 y el 7.3 difieren mucho en la parte del simulador.  El 7.3 es mucho mas exacto y menos permisivo.  Refleja mas la realidad.  Si en el 7.3 no se borraba entonces seguro en el pic no se iba a borrar.

2) La interrupcion el puerto B, es por diferencias.  Para que se borre la diferencia debes realizar una operación de lectura del puerto.  Esta operacion de lectura quita la condición de 'match' como le dicen los de Microchip.

No ha sido ciencia, simplemente si leías la datasheet del PORTB hubieras visto esto.  Está muy bien documentado.

Para la próxima un consejo.  Es raro que algo no esté en las datasheet... lee lee lee y luego recien consulta.  Te quiero aclarar que no quiero que pienses que es mala voluntad, de hecho me la paso posteando y a mi no me beneficia ni me perjudica que preguntes, pero el ver la solución por ti mismo te ayudará a poder aprender y comprender la solución solo.

Saludos


----------



## TeEstoyMirando (Feb 4, 2006)

Entiendo lo que me quieres decir, pero si postee aqui es porque busque mire y observe durante mucho tiempo y no consiguia la solucion. No entendita porque si le decia ponme un cero no me lo ponia jeje.
Tampoco soy un experto sobre el tema, mas bien todo lo contrario. Y si empiezas a programar en un nuevo lenguaje cuando encuentras trabas enseguida te siente desbordado y desistes.

Gracias por tu post y aqui estare intentando ordenar en mi cabeza este mundo algo complejo de los PICS.

Un saludo.


----------



## maunix (Feb 4, 2006)

TeEstoyMirando dijo:
			
		

> Entiendo lo que me quieres decir, pero si postee aqui es porque busque mire y observe durante mucho tiempo y no consiguia la solucion. No entendita porque si le decia ponme un cero no me lo ponia jeje.
> Tampoco soy un experto sobre el tema, mas bien todo lo contrario. Y si empiezas a programar en un nuevo lenguaje cuando encuentras trabas enseguida te siente desbordado y desistes.
> 
> Gracias por tu post y aqui estare intentando ordenar en mi cabeza este mundo algo complejo de los PICS.
> ...



Si, supuse que eras nuevo en el mundo de los pics pero eso no quita que leas y leas antes de postear.  Como te dije antes,  no me molesta responder cuando demuestran esfuerzo, pero te lo dije a modo de consejo porque preguntar todo el tiempo no es la forma de aprender, a veces es mejor leer en el manual y de paso creas la costumbre.  Cuando estas solo , no tengas a nadie  o quieras hacer algo y no tengas internet podras hacerlo 

Saludos


----------



## xugua (May 22, 2006)

En este momento me incorporo al foro y lo que he leido de este episodio de problemas se parece al mio. Posteo el codigo que estoy manejando para controlar un teclado y 5 displays. Lo que pretendo es controlar temperatura - tal vez sea algo muy sencillo pero no salgo del problema. Con el teclado programo una referencia y en los 2 displays menos significativos quiero mostrar ese dato. Para que en tres displays (mas significativos) muestre el datos obtenido por el convertidor y por lazo cerrado controlar una termoresistencia, aun no esta desarrollada la parte del convertidor. La razon es que pareciera que se muere el PIC y no entiendo que estoy haciendo mal. 
Con los datos que acabo de leer hare los ajustes y mando respuestas. Sin embargo, si me gustaria que revisaren el codigo que he desarrollado pienso que aprenderè mucho de sus sugerencias.


```
title 'Servo control de temperatura'
	;////////Objetivo controlar los cuatro dig0s en un conteo descendente///////////////

	LIST P = 16F877	 ;Indicamos el modelo de PIC a utilizar
	include <p16f877.inc>				; Definición de registros
			
;¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ Definición de constantes
w EQU 0 	; Destino de operación = w
f EQU 1		; Destino de operación = registro
RBPU EQU 7
TMROcharge64us EQU -d'64'
up EQU d'1'
;¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ Definición de variables
contador EQU 0X22 	; Contador
dig0 EQU 0X23 	; Para almacenar el dígito
R1	EQU 0X24
R2	EQU 0X25
dig1 EQU 0X26
dig2 EQU 0X27
dig3 EQU 0X28
dig4 EQU 0X33
;gradoC EQU 0X29
w2 EQU 0X2A
;flagUpDown EQU 0X15	;bandera de subida y bajada.
dataRef	   EQU 0X2B	;Variable de referencia
lmax	   EQU 0X2C
lmin	   EQU 0X2F
temp	   EQU 0X30
temp2	EQU 0X31
temp3   EQU 0X32
mdig0 EQU 0X34 	; Para almacenar el dígito
mdig1 EQU 0X35
mdig2 EQU 0X36
mdig3 EQU 0X37
mdig4 EQU 0X38
conta EQU 0x39
tecla EQU 0X3A
cont1 EQU 0X3B
cont2 EQU 0X3C
cont3 EQU 0X3D
guardaW	EQU 0X3E
guardaSTATUS EQU 0X3F
registroA EQU 0X40
guardaRegistroA EQU 0X41
registroB EQU 0X42
guardaRegistroB EQU 0X43
	
	
				; Comienzo del programa.
	ORG 0X00 		; Cubrimos el vector de reset 
	GOTO inicio 	; Saltamos a la primera dirección tras el vector de interrupción
; ************************ Inicialización de variables *************************
	ORG 0X04			
	GOTO servicioInterrupcion
	
inicio 
 	BCF STATUS,RP1 ;BANCO UNO
 	BSF STATUS,RP0  ; Cambiamos a la segunda página de memoria
 	
	CLRF TRISC
	CLRF TRISD 			; Programa la puerta B como de todo salidas
	MOVLW 0xF0		; Las patillas RB0-RB3 representan las filas del
	MOVWF TRISB					; teclado, y son salidas
	BCF OPTION_REG,RBPU					; Las patillas RB4-RB7 representan las columnas,
						; y son entradas
					
	BCF STATUS,RP0	 ; Volvemos a la página 0.
	MOVLW b'10101000'	;Autoriza interrupcion TOI, RBIE Y GIE.
	MOVWF INTCON	
	MOVLW TMROcharge64us
	MOVWF TMR0
	
	CLRF PORTC  ;LIMPIA LOS PUERTOS
	CLRF PORTD 			; Apaga el display, por si había residuos
	CLRF contador 		; Borra el contador (dirección 0x0C)
	CLRF w2
	CLRF dig0
	CLRF dig1
	CLRF dig2
	CLRF dig3
	CLRF mdig0
	CLRF mdig1
	CLRF mdig2
	CLRF mdig3
	CLRF mdig4
	CLRF dataRef
	CLRF lmax
	CLRF lmin
	CLRF temp
	CLRW 			; Borramos el registro W
	;********************************Carga de variables
	MOVLW d'4'
	MOVWF w2
	CALL converto7seg
	CALL refreshAct

main		;CARGA DE LIMITES...........
	CALL converto7seg
	CALL refreshRef
	MOVF tecla,W
	BCF  STATUS,Z
	XORLW up 				; Chekea si el dígito sobrepasa el valor 9
	BTFSC STATUS,Z	 
	GOTO main
	INCF contador,f
	MOVF contador,W
	MOVWF w2
	GOTO main
	
	
;############# SERVICIO DE INTERRUPCION  ##############################

servicioInterrupcion	;Guarda registros que pueden ser modificados
	MOVWF guardaW
	SWAPF STATUS,W
	MOVWF guardaSTATUS
	
	BCF STATUS,RP0	;Para asegurarse que trabaja dentro del Banco 0
	BCF STATUS,RP1
	MOVLW TMROcharge64us ;Recarga TMR0
	MOVWF TMR0
	;Verficar la causa de la interrupcion
	BTFSC INTCON,RBIF
	CALL InterrupcionRBI
	BTFSC INTCON,T0IF
	CALL InterrupcionTOI
	;Aqui se efectua el servicio de interrupcion
	
	
	
	SWAPF guardaSTATUS,W
	MOVWF STATUS
	SWAPF guardaW,F
	SWAPF guardaW,W
	
	BCF INTCON,T0IF
	BCF INTCON,RBIF	
	RETFIE

;+++++++++++++++++++++++++Surutinas
InterrupcionRBI ;lectura de las teclas
	CALL borrar
cuerpo CLRF tecla		 		; Tecla actual=0
		MOVLW 0x0E
		MOVWF PORTB		 ; Saca 0 a la fila 1, para testearla
chkcol  BTFSS PORTB,4  		; Chequea la columna 0 en busca de un '0'
		GOTO numtecla   	 ; si encuentra un 0 muestra el número
					 ; de tecla pulsada
		INCF tecla,1	 ; si no encuentra el 0, incrementa el número de tecla (el numero 1 indica como y donde se ejecuta la instrucción.)
		BTFSS PORTB,5	  ; Chequea la columna 1 en busca de un '0'
		GOTO numtecla 	; si encuentra un 0 muestra el número				 ;de tecla pulsada
		INCF tecla,1	; si no encuentra el 0, incrementa el número de tecla
		BTFSS PORTB,6 	; Chequea la columna 2 en busca de un '0'
		GOTO numtecla   	; si encuentra un 0 muestra el número de tecla pulsada
		
		INCF tecla,1	; si no encuentra el 0, incrementa el número de tecla
		BTFSS PORTB,7  	; Chequea la columna 3 en busca de un '0'
		GOTO numtecla	 ; si encuentra un 0 muestra el número de tecla pulsada
		
		INCF tecla,1 	 ; si no encuentra el 0, incrementa el número de tecla

UltTec?	MOVLW 0x10		 ; Carga W con el número de tecla +1
		BCF	STATUS,Z	;Antes de probar si hubo tecla+1, borramos el indicador  para asegurar
		SUBWF tecla,w 	 ; y lo compara con el valor actual de tecla
		BTFSC STATUS,Z 		 ; Si hemos llegado a Tecla+1 acabamos
							; el ciclo de filas
		GOTO cuerpo 		 ; y no se habrá pulsado ninguna tecla
		BSF STATUS,C		 ; Y ponemos a 1 el bit C para...
		RLF PORTB,1  ; que la fila 1 pase a ser un 1 							; y el 0 se desplace
		GOTO chkcol
numtecla MOVF tecla,W ;0	
		;MOVF tecla,W
		;MOVWF w2
		RETURN					;Fin de lectura de teclas
		
InterrupcionTOI
		
	CALL DISP0		;control del display correspondiente
	MOVF mdig0,W  	; Coloca el siguiente dígito a evaluar en W
	CALL Tablac
	MOVWF PORTD 		;mostramos el resultado en el display
	CALL DELAY			;retardo para apreciar la visualización.
		
	CALL DISP1			;control de display
	MOVF mdig1,W  
	CALL Tablac
	MOVWF PORTD 
	CALL DELAY	
	
	CALL DISP2
	MOVF mdig2,W
	CALL Tablac
	MOVWF PORTD 
	CALL DELAY	
		
	CALL DISP3
	MOVF mdig3,W
	CALL Tablac
	MOVWF PORTD 
	CALL DELAY	
	
	CALL DISP4
	MOVF mdig4,W
	CALL Tablac
	MOVWF PORTD 
	CALL DELAY	
	RETURN

borrar  CLRF cont1 	 		 ; Borra el contador
		CLRF cont2 		 ; Borra el contador
		MOVLW 0x08
		MOVWF cont3		 ; Carga el retardo de 0.5 segundos
		RETURN
	
pausa	DECFSZ cont1,1 	 ; Bucle anidado de 3 niveles
		GOTO pausa 		 ; que retarda aprox. 0.5 segundos
		DECFSZ cont2,1
		GOTO pausa
		DECFSZ cont3,1
		GOTO pausa
		RETURN	
		       ;cargar datos transformadores para marcar dato inicial en el display
		       ;el dato a convertir se carga en w2
converto7seg   
	CLRF temp
	CLRF dig0
	CLRF dig1
	CLRF dig2
	CLRF dig3
asigna 	CALL UNIDADES_ASC
  	INCF temp,f 			 
	MOVF temp,W
  	BCF STATUS,Z
	SUBWF w2,W
	BTFSS STATUS,Z ;2;	XORLW 0xFA 		;BTFSC STATUS,Z
	GOTO asigna
	return

refreshRef
	MOVF dig0,W
	MOVWF mdig0
	MOVF dig1,W
	MOVWF mdig1
	RETURN
	
refreshAct
	MOVF dig0,W
	MOVWF mdig2
	MOVF dig1,W
	MOVWF mdig3
	MOVF dig2,W
	MOVWF mdig4
	RETURN			       

UNIDADES_ASC		;Tranform to seven segment display (ONLY COUNT ASCENDENT)
	INCF dig0,f
	MOVF dig0,W 	; Pone el valor del dígito en W
	BCF STATUS,Z
	XORLW 0x0A 	; Chekea si el dígito sobrepasa el valor 9
	BTFSC STATUS,Z	; Comprobando con un xor si W vale 0 (Z=1)
	CALL DECENAS_ASC 	; Si Z=1 resetea el dígito y comienza de nuevo la cuenta
	RETURN		; con el siguiente dígito
	
DECENAS_ASC
Reset1 CLRF dig0		; Comienza a contar por el 0
	INCF dig1,f 	; Incrementa el valor del dígito al siguiente
	MOVF dig1,W 	; Pone el valor del dígito en W
	BCF STATUS,Z
	XORLW 0x0A 	; Chekea si el dígito sobrepasa el valor 9
	BTFSC STATUS,Z	 ; Comprobando con un xor si W vale 0 (Z=1)
	CALL CENTENAS_ASC    ; Si Z=1 resetea el dígito y comienza de nuevo la cuenta
	return
	
CENTENAS_ASC
Reset2 CLRF dig1		; Comienza a contar por el 0

	INCF dig2,f 	; Incrementa el valor del dígito al siguiente
	MOVF dig2,W 	; Pone el valor del dígito en W
	BCF STATUS,Z
	XORLW 0x0A 	; Chekea si el dígito sobrepasa el valor 9
	BTFSC STATUS,Z	; Comprobando con un xor si W vale 0 (Z=1)
	CALL MILLARES_ASC 	; Si Z=1 resetea el dígito y comienza de nuevo la cuenta
	return
	
MILLARES_ASC
Reset3 CLRF dig2		 	; Comienza a contar por el 0
	INCF dig3,f 			; Incrementa el valor del dígito al siguiente
	MOVF dig3,W 			; Pone el valor del dígito en W
	BCF STATUS,Z
	XORLW 0x0A 	; Chekea si el dígito sobrepasa el valor 9
	BTFSC STATUS,Z	 ; Comprobando con un xor si W vale 0 (Z=1)
	CLRF dig3
	return
					
					
Tablac ADDWF PCL,f 	; Suma al ffset, es decir,
		; el valor del dígito. Así se genera un PC distinto según su valor,
		; asegurando que vaya a la línea correcta de la tabla
	RETLW 0x3F ; 0 en código 7 segmentos
	RETLW 0x06 ; 1 en código 7 segmentos
	RETLW 0x5B ; 2 en código 7 segmentos
	RETLW 0x4F ; 3 en código 7 segmentos
	RETLW 0x66 ; 4 en código 7 segmentos
	RETLW 0x6D ; 5 en código 7 segmentos
	RETLW 0x7D ; 6 en código 7 segmentos
	RETLW 0x07 ; 7 en código 7 segmentos
	RETLW 0x7F ; 8 en código 7 segmentos
	RETLW 0x6F ; 9 en código 7 segmentos

	
DELAY   MOVF 0X04,W
	    MOVWF R2 
CICLO1  DECFSZ  R1,1
        GOTO CICLO1
CICLO2  DECFSZ  R2,1
        GOTO CICLO1
        RETURN
        
DISP0
	BCF PORTC,4
	BCF PORTC,3		;Habilita )
	BCF PORTC,2
	BCF PORTC,1
	BSF PORTC,0	
	RETURN
	
DISP1
	BCF PORTC,4
	BCF PORTC,3		;Habilita display )
	BCF PORTC,2
	BCF PORTC,0	
	BSF PORTC,1	
	RETURN
	
DISP2
	BCF PORTC,4
	BCF PORTC,3		;Habilita display)
	BCF PORTC,1
	BCF PORTC,0	
	BSF PORTC,2	
	RETURN
	
DISP3
		;Habilita display )
	BCF PORTC,4	
	BCF PORTC,2
	BCF PORTC,1
	BCF PORTC,0	
	BSF PORTC,3
	RETURN
	
DISP4
		;Habilita display)
	BCF PORTC,3	
	BCF PORTC,2
	BCF PORTC,1
	BCF PORTC,0	
	BSF PORTC,4
	RETURN	
	
	END
```

He probado teclado y displays en el 16f84 pero aqui se me ha complicado y mas con las interrupciones.

Estoy preparando material para un nuevo curso en mi trabajo y estoy aprendiendo a dominar esta tecnologìa, ya que en su momento no hubo esa oportunidad. Es una maravilla estos foros.

Espero su respuesta gracias.


----------



## zidaemon (Abr 14, 2009)

No va return, es retfie

He tenido tantos problemas con las interrupciones, y te doy los siguientes consejos viendo tu codigo

En todo servicio de interruptor, hay que guardar primero el valor de Wreg, FSR, PClath y status en registros de la ram.
Posteriormente cuando ya realizaste el servicio de interrupcion, los valores guarddos deben ser puestos de nuevo en sus respectivos registros.

Esto por lo siguiente:

cuando atiendes una interrupcion, las operaciones que realizas tienden a modificar estos registros, y los valores que tienen antes de la interrupcion son perdidos despues de la interrupcion. 

Por cierto, te recomiendo las localidades generales que poseen los pics, para que no tengas problemas con la posicion de los bancos. En el 16f877 son los marcados con access 0x70 0x7F


----------



## bomarv (May 6, 2010)

jajaj te pasat taba buscando soluciones para eso y justo lo encontré tu solución.
Tampoco sabia del refresco de memoria(MOVF REGISTRO,f) , pensé que como la interrupción externa RB0 no necesitaba mas, este tampoco necesitaría.
Graxias x postear


----------

