TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: c-zar en 20 de Octubre de 2004, 21:48:00
-
Saludos desde Cd. Juarez, Mexico, tengo un problema con la interrupcion de los pins mas significativos del puerto B del PIC 16F84, lo que necesito es que cuente 3 interrupciones por medio de RB7 y a la cuarta interrupcion ponga en alto RA0 y que al paso de un minuto pase a bajo el RA0, tengo el programa pero para interrupcion en RB0 y cuando la cambio a la interrupcion de RB4-RB7 se pone en alto a la primera interrupcion, alguien me podria ayudar por favor, a continuacion les anexo el programa... ya he hecho algunas pruebas pero solo funciona para la interrupcion de RB0, en el MPLAB si funciona bien, si espera los cuatro pulsos en RB7, pero al momento de alambrar, al primer pulso en RB7 se enciende un led en RA0, les agradeceria mucho si me ayudaran con este problema..., tengo esa secuencia en el programa por que esta etapa es parte de otro programa....
List p=16F84
include "P16F84.inc"
Contador equ 0x0c
CINC equ 0x0E
MINUTE equ 0x0F
ORG 0x00
goto Inicio
ORG 0x04
goto INTER
ORG 0x05
;*****************************************************************
INTER decfsz Contador,1
goto restaurar
bcf INTCON,0
movlw .4
movwf Contador
movlw 0X14
movwf CINC
bsf PORTA,0
call RETARDO
goto colgar
RETARDO movlw 0x16
movwf TMR0
CHECA btfss INTCON,2
goto CHECA
bcf INTCON,2
DECREMENTA decfsz CINC,1
goto RETARDO
movlw 0X14
movwf CINC
decfsz MINUTE,1
goto RETARDO
movlw 0X3c
movwf MINUTE
movlw b"10010000"
movwf INTCON
return
restaurar movlw 0x3c
movwf TMR0
decfsz CINC,1
goto restaurar
movlw 0x20
movwf CINC
bcf INTCON,0
retfie
colgar movlw 0x33
movwf TMR0
movlw b"10001000"
movwf INTCON
clrf PORTA
movlw 0x20
movwf CINC
movlw 0x33
movwf MINUTE
retfie
Inicio clrf PORTB
clrf PORTA
bsf STATUS, RP0
movlw b"11111001"
movwf PORTB
movlw b"00000000"
movwf PORTA
movlw 0x07
movwf OPTION_REG
bcf STATUS, RP0
movlw b"10001000"
movwf INTCON
movlw 0x04
movwf Contador
movlw 0x20
movwf CINC
movlw 0x30
movwf MINUTE
AQUI goto AQUI
end
-
hola c-zar !
lei tu programa y me llamo la atencion algo en la rutina de "restaurar"
restaurar movlw 0x3c
movwf TMR0
decfsz CINC,1
goto restaurar
movlw 0x20
movwf CINC
bcf INTCON,0
retfie
porque previamente a esto hubo una interrupcion por la pata RB7 y como el contador no llego a cero le digiste que haga esta subrutina.
Ahora, lo que no se si esta bien, es que en esta subrutina en ningun momento volves a inicializar INTCON con la configuracion b"10001000". De la forma como esta, el funcionamiento depende de la forma con que le haces la interrupcion. es decir, como es la señal que provoca la interrupcion.
mi consejo seria:
restaurar movlw 0x3c
movwf TMR0
decfsz CINC,1
goto restaurar
movlw 0x20
movwf CINC
bcf INTCON,0
movlw b"10001000"
movwf INTCON
retfie
TENE EN CUENTA QUE LAS INTERRUPCIONES POR RB4 - RB7 SON INTERRUPCIONES POR CAMBIO DE ESTADO. POR ESO, SI LAS HACES POR INTERMEDIO DE UN PULSO COMO SE HACE GENERALMENTE EN RB0, CUANDO DE COMPLETE EL PULSO VAS A TENER DOS CAMBIOS DE ESTADO, ES POR ESO QUE EL ANCHO DEL MISMO TENES QUE TENERLO EN CUENTA.
-
hola, no se si los has resuelto ya, pero te doy mi parecer
criticar es facil y vos ayudas bastante, tenes un "return" en medio de la interrupcion???? la verdad q leer el prog. sin identar se hace dificil...
ese return hace q si sale por alli la int no se vuelve a activar mas.... (creo)
lo mejor seria q solo tengas un punto de salida de la interrupcion, esto mas q nada por una buena practica de programacion.
antes del retfie, siempre debe ir "bcf intcon,0" , eso es correcto y mejor q mover todo el byte en intcon.
pero creo q lo mas importante q te falta es leer el "data sheet" detenidamente del f84, para rehabilitar la interrupcion debes hacer una lectura del port b por cada interrupcion.
en tu caso es necesario pq el port b(4..7) interrumpe por flanco y deberia distinguier en el prog cual de ellos es.
por cierto no dijiste cual es la velocidad de los pulsos aproximadamente ya q si son muy rapidos tendras otros problemas..
tampoco veo q este salvando el reg WREG y el status al entrar y salir, aunque podria no ser necesario.
la int deberia empezar asi:
btfss INTCON , RBIF ; ve si interrumpio RB
goto EndIntRB ; no interrumpio RB
luego esto es lo mas conveniente....
movfw PORTB ; esto es para terminar la condicion de int
movwf tmpInt
xorwf LastRB , f
donde lastrb y tmpint son 2 variavles auxiliares,
tmpint te dira cual es el estado del pin q interrumpio..
y lastrb te dira cual es el pin q interrumpio.
luego
InitIntRB4
btfss LastRB , 4
goto EndIntRB4 ; no es el pin 4 el q interuumpio...
aqui debe hacer lo q quieras en la interrupcion
por ejemplo ver si el pin q necesitas esta arriba o abajo??
btfsc tmpInt , 4
goto NivelEs1
EndIntRB4
y esto q es importante
debe seguir al proximo por cascada, caida libre, por si interumpieron dos casi junto
analizar por el resto de los pines 5,6,7
cuando termino de analizar los pines q me interesan...
EndIntRBz
movfw tmpInt
movwf LastRB
bcf INTCON , RBIF
goto EndInt
EndInt
aqui recuperar los registros q sean necesarios
retfie
espero q no sea un lio y te sirva, fue lo unico q me dio resultado
las dos variables son muy importantes, una es local y la otra global y se debe inicializar
Suerte.
-
Hola, muchas gracias, me sirvio de mucho la informacion que me mandaron y pues lo que tenia mal es lo que me recomendo escorpion sobre el flanco de la interrupcion del puerto B (RB4-RB7), ya que a diferencia de la int externa, no se programa el flanco de la interrupcion, lo que hice fue que cuando se provocara la interrucion, checar el bit RB7 hasta que se fuera a nivel bajo, esto con el fin de solo obtener una interrupcion por cada pulso que entra, muchas gracias por su ayuda, no habia contestado por que habia estado muy ocupado, ahora el problema que tengo es que me sale un error 0000h! al tratar de programar el PIC16F877A.
Saludos...
-
Revisa el programador , y tambien prueba con otro chip, por si puede haber muerto.