TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: ECHEARANJUEZ en 13 de Abril de 2013, 19:40:04

Título: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: ECHEARANJUEZ en 13 de Abril de 2013, 19:40:04
El programa  genera un pulso de 12us cada 60ms, lo que necesito es interrumpir ese pulso cuando halla un pulso en RB0 que se encienda un led en el puerto RB1, pero no logro que se ejecute la interrupción correctamente. agradecería cualquier ayuda.

Citar
; PIC16F887 Configuration Bit Settings

#include "p16F887.inc"

; CONFIG1
; __config 0xEFF1
 __CONFIG _CONFIG1, _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _IESO_ON & _FCMEN_ON & _LVP_OFF
; CONFIG2
; __config 0xFFFF
 __CONFIG _CONFIG2, _BOR4V_BOR40V & _WRT_OFF

; CONFIGURAR REGISTROS
temporal1 EQU 0X23
temporal2 EQU 0X24
PDel0   EQU 0X21
PDel1   EQU 0X22



        ORG 0X00
        GOTO INIT


        ORG 0X04
        GOTO INTERRUPCION




INIT

;*********************************
;*CONFIGURACION DE PUERTOS y de la interrupciones
;*********************************
    ORG 0X05
    banksel TRISB   ;Pasamos al banco 1
    MOVLW B'11111101'  ; RB0  COMO ENTRADA
    MOVWF TRISB
    CLRF  TRISA      ;configura PORTA todo como salida
    CLRF  TRISE        ; PUERTO A COMO SALIDA
    CLRF  TRISC         ;PUERTO C COMO SALIDA
    banksel  ANSELH   ;vamos al banco 3
    CLRF     ANSELH          ;ENTRADAS DIGITALES
    CLRF   ANSEL
    BANKSEL PORTA

;BORRAR PUERTOS
    CLRF PORTA
    CLRF PORTB
    CLRF PORTC
    CLRF PORTD

;CONFIGURACION INTERRUPCIONES
    BANKSEL OPTION_REG
   MOVLW B'01000000'
    MOVWF OPTION_REG
    MOVLW B'10010000'
    MOVWF INTCON
    BANKSEL PORTA


Inicio
   call TRIGER
   goto Inicio


;*********************************
;*CONFIGURACION DEl disparo para el ultrasonido, BUCLE INFINITO
;*********************************
TRIGER
        BSF PORTA,0
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        BCF PORTA,0
        CALL DELAY_60MS
        GOTO TRIGER
   ;RUTINA RETARDOS

DELAY_60MS
                  movlw     .66       ; 1 set numero de repeticion  (B)
                  movwf     PDel0     ; 1 |
PLoop1            movlw     .181      ; 1 set numero de repeticion  (A)
                  movwf     PDel1     ; 1 |
PLoop2            clrwdt              ; 1 clear watchdog
                  clrwdt              ; 1 ciclo delay
                  decfsz    PDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
                  goto      PLoop2    ; 2 no, loop
                  decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
                  goto      PLoop1    ; 2 no, loop
                  clrwdt              ; 1 ciclo delay
                  return              ; 2+2 Fin.
;*********************************
;*Servicio de rutinas de interrupción
;*********************************
INTERRUPCION    MOVWF temporal1
                MOVF STATUS,W
                MOVWF temporal2
                BTFSC INTCON,INTF   ;salta si la interrupción no es interna
                GOTO INT_RBO

FIN_INTER
        MOVF     temporal2,w
        movwf STATUS
        MOVF temporal1,w
        BCF INTCON,INTF
        retfie

INT_RBO
        BTFSS PORTB,1
        GOTO ENCENDER
        GOTO APAGAR



ENCENDER
   BSF PORTB,1
        GOTO FIN_INTER

APAGAR
        BCF PORTB,1
        GOTO FIN_INTER


    END





Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: Chenao en 13 de Abril de 2013, 20:30:10


Para poder ayudarte deberías poner más información la primera que máquina utilizas y segundo el hardware que estas utilizando.
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: soymoe en 13 de Abril de 2013, 22:05:57
El programa  genera un pulso de 12us cada 60ms, lo que necesito es interrumpir ese pulso cuando halla un pulso en RB0 que se encienda un led en el puerto RB1, pero no logro que se ejecute la interrupción correctamente. agradecería cualquier ayuda.

Citar
; CONFIGURAR REGISTROS
temporal1 EQU 0X23
temporal2 EQU 0X24
PDel0   EQU 0X21
PDel1   EQU 0X22



        ORG 0X00
        GOTO INIT


        ORG 0X04
        GOTO INTERRUPCION
        ORG 0X05



INIT

;*********************************
;*CONFIGURACION DE PUERTOS y de la interrupciones
;*********************************
   
    banksel TRISB   ;Pasamos al banco 1
    MOVLW B'11111101'  ; RB0  COMO ENTRADA
    MOVWF TRISB
    BCF   OPTION_REG,6
    CLRF  TRISA      ;configura PORTA todo como salida
    CLRF  TRISE        ; PUERTO A COMO SALIDA
    CLRF  TRISC         ;PUERTO C COMO SALIDA
    CLRF  ANSELH          ;ENTRADAS DIGITALES
    banksel PORTA   ;volvemos al banco 0

;BORRAR PUERTOS
    CLRF PORTA
    CLRF PORTB
    CLRF PORTC
    CLRF PORTD

;CONFIGURACION INTERRUPCIONES

    MOVLW B'10010010'
    MOVWF INTCON
    CLRF PORTB


Inicio
   call TRIGER
   goto Inicio


;*********************************
;*CONFIGURACION DEl disparo para el ultrasonido
;*********************************
TRIGER
        BSF PORTA,0
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        BCF PORTA,0
        CALL DELAY_60MS
        GOTO TRIGER
   ;RUTINA RETARDOS

DELAY_60MS
                  movlw     .66       ; 1 set numero de repeticion  (B)
                  movwf     PDel0     ; 1 |
PLoop1            movlw     .181      ; 1 set numero de repeticion  (A)
                  movwf     PDel1     ; 1 |
PLoop2            clrwdt              ; 1 clear watchdog
                  clrwdt              ; 1 ciclo delay
                  decfsz    PDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
                  goto      PLoop2    ; 2 no, loop
                  decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
                  goto      PLoop1    ; 2 no, loop
                  clrwdt              ; 1 ciclo delay
                  return              ; 2+2 Fin.
;*********************************
;*Servicio de rutinas de interrupción
;*********************************
INTERRUPCION    MOVWF temporal1
                MOVF STATUS,W
                MOVWF temporal2
                BTFSC INTCON,INTF   ;salta si la interrupción no es interna
                GOTO INT_RBO

FIN_INTER
   MOVF     temporal2,w
        movwf STATUS
        MOVF temporal1,w
   retfie

INT_RBO
   BTFSS PORTB,0
        GOTO ENCENDER
        GOTO APAGAR



ENCENDER
   BSF PORTB,1
        GOTO FIN_INTER

APAGAR
     BCF PORTB,1
        GOTO FIN_INTER


    END




Lo que tenes que haces segun yo es crear una rutina que genere el pulso y espere 60ms, esa la vas a repetir mientras no se pulse rb0.
Por otro lado lo unico que tenes que hacer en la interrupcion es modificar una variable que se llame por ejemplo "pulsado" y si esta variable es true interrumpir el blucle infinito del programa principal.
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: ECHEARANJUEZ en 14 de Abril de 2013, 13:57:11


Para poder ayudarte deberías poner más información la primera que máquina utilizas y segundo el hardware que estas utilizando.

compañero estoy utilizando el pic16f887 y el mplab x v1.6 .
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: Chenao en 14 de Abril de 2013, 15:42:34

Porque no pones el hardware, creo que el error puede estar en la forma como estas interpretando el suceso de interrupción, ya que el terminal RB0 debe estar activo para de esta manera detectar el flanco descendente en RB0.
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: Darkman_A en 14 de Abril de 2013, 17:10:21
El programa  genera un pulso de 12us cada 60ms, lo que necesito es interrumpir ese pulso cuando halla un pulso en RB0 que se encienda un led en el puerto RB1, pero no logro que se ejecute la interrupción correctamente. agradecería cualquier ayuda.

Citar
; CONFIGURAR REGISTROS
temporal1 EQU 0X23
temporal2 EQU 0X24
PDel0   EQU 0X21
PDel1   EQU 0X22



        ORG 0X00
        GOTO INIT


        ORG 0X04
        GOTO INTERRUPCION
        ORG 0X05



INIT

;*********************************
;*CONFIGURACION DE PUERTOS y de la interrupciones
;*********************************
    
    banksel TRISB   ;Pasamos al banco 1
    MOVLW B'11111101'  ; RB0  COMO ENTRADA
    MOVWF TRISB
    BCF   OPTION_REG,6
    CLRF  TRISA      ;configura PORTA todo como salida
    CLRF  TRISE        ; PUERTO A COMO SALIDA
    CLRF  TRISC         ;PUERTO C COMO SALIDA
    CLRF  ANSELH          ;ENTRADAS DIGITALES
    banksel PORTA   ;volvemos al banco 0

;BORRAR PUERTOS
    CLRF PORTA
    CLRF PORTB
    CLRF PORTC
    CLRF PORTD

;CONFIGURACION INTERRUPCIONES

    MOVLW B'10010010'
    MOVWF INTCON
    CLRF PORTB


Inicio
   call TRIGER
   goto Inicio


;*********************************
;*CONFIGURACION DEl disparo para el ultrasonido
;*********************************
TRIGER
        BSF PORTA,0
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        BCF PORTA,0
        CALL DELAY_60MS
        GOTO TRIGER
   ;RUTINA RETARDOS

DELAY_60MS
                  movlw     .66       ; 1 set numero de repeticion  (B)
                  movwf     PDel0     ; 1 |
PLoop1            movlw     .181      ; 1 set numero de repeticion  (A)
                  movwf     PDel1     ; 1 |
PLoop2            clrwdt              ; 1 clear watchdog
                  clrwdt              ; 1 ciclo delay
                  decfsz    PDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
                  goto      PLoop2    ; 2 no, loop
                  decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
                  goto      PLoop1    ; 2 no, loop
                  clrwdt              ; 1 ciclo delay
                  return              ; 2+2 Fin.
;*********************************
;*Servicio de rutinas de interrupción
;*********************************
INTERRUPCION    MOVWF temporal1
                MOVF STATUS,W
                MOVWF temporal2
                BTFSC INTCON,INTF   ;salta si la interrupción no es interna
                GOTO INT_RBO

FIN_INTER
   MOVF     temporal2,w
        movwf STATUS
        MOVF temporal1,w
   retfie

INT_RBO
   BTFSS PORTB,0
        GOTO ENCENDER
        GOTO APAGAR



ENCENDER
   BSF PORTB,1
        GOTO FIN_INTER

APAGAR
     BCF PORTB,1
        GOTO FIN_INTER


    END





Hola.
Me parece que en tu codigo esta mal que inicialices en 1 el bit INTF ( te lo he marcado en rojo en tu codigo)

;CONFIGURACION INTERRUPCIONES
    MOVLW B'10010010'
Tendrias que inicializarlo en cero y cuando se produce la interrupcion chequeas que ha cambiado a 1 (esto ultimo ya lo estas haciendo en tu programa)
Lo sigo mirando a ver si encuentro algun error mas.
Saludos.

Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: Chenao en 14 de Abril de 2013, 17:57:35

A parte de lo que comenta el compañero Darkman_A, existe un problema mucho mayor ya que no estas aplicando la regla de oro en la interrupciones y es que se deben limpiar los bits banderas que indican que una interrupción ha ocurrido en este caso particular en la rutina de interrupción (desde FIN_INTER) debes agregar la siguiente linea de código.

Código: [Seleccionar]
FIN_INTER
     
bcf   intcon,1

Ya se han encontrado 2 errores, implementa las sugerencias haber si así anda.

 
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: ECHEARANJUEZ en 14 de Abril de 2013, 19:47:42
Si compañeros tienen toda la razón, ya realice los cambios mencionados, ademas agregue el OPTION_REG para que el RB0 detecte el flanco de subida, pero aun no me anda bien.
Ya modifique el código y agregue una imagen de la simulación 
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: Chenao en 14 de Abril de 2013, 20:25:35

Haber si estoy entendiendo, tienes configurado la interrupción para que detecte un flanco descendente en el terminal RB0, si un flanco descendente ocurre el programa principal se debe interrumpir para atender la solicitud de interrupción generada por el evento externo, pero según el hardware el terminal RB0 esta en 0 (o al menos eso es lo que observo en el esquemático) por lo tanto, para que funcione el terminal RB0 debe mantenerse inicialmente (antes de hacer la solicitud) en nivel alto, es decir, conectado a 5V.  Así se realiza la simulación?. 
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: ECHEARANJUEZ en 15 de Abril de 2013, 00:10:56
Eso es exactamente lo que quiero hacer pero con la diferencia que quiero detectar el flanco de subida. Alguna sugerencia?
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: Darkman_A en 15 de Abril de 2013, 11:15:32
Hola.
Me parece que el problema esta aca.
Estas escribiendo
INT_RBO    BTFSS PORTB,0
                 GOTO ENCENDER
                 GOTO APAGAR

Estas chequeando el puerto B0 ( por donde llega la interrupcion). Suponiendo que se produjo la interrupcion esa entrada esta a 1. Siempre se va a dar ese caso ( sin considerar el ruido de rebote del pulsador. Estamos con el Proteus).
Tenes una sentencia BTFSS que salta cuando es 1. Por lo tanto salta y va a GOTO APAGAR, y  el led nunca se prende.
Si queres que cambie el estado del led cuando presionas tendrias que chequear B1 que es donde esta el led o en su defecto un registro auxiliar donde guardes el estado del led.
Miralo, cualquier cosa volve a consultar.
Saludos.

Otra cosa.  esta limpiando el WDT (clrwdt). No necesitas limpiarlo si no lo estas usando (& _WDTE_OFF &)
Y una mas, no se que le parezca al moderados, pero me parece que si corregis el codigo original tendrias que poner algo un texto que indique que fue corregido, porque sino dentro de unos dias entra alguien y no entiende nada porque al final si seguis corrigiendo el programa va a estar bien y no va a encontrar los errores, salvo que se lea todo el post. Algun comentario que indique que corregiste tal linea.
Saludos nuevamente. 
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: ECHEARANJUEZ en 15 de Abril de 2013, 11:32:33
Tienes razón las correcciones que he realizado las he colocado en color rojo. he revisado el código una y otra vez y no le encuentro problema alguno, sinceramente ya no se que hacer
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: AngelGris en 15 de Abril de 2013, 11:41:57
  Me parece que hay un error en la configuración del registro ANSELH. Por lo que entiendo, lo estás intentando configurar estando en el banco 1 (al seleccionar dicho banco para modificar el trisB), pero el registro ANSELH se encuentra en el banco 3. Por lo tanto RB0 te queda configurada como entrada analógica.
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: Chenao en 15 de Abril de 2013, 11:43:23
Para que funciones debes agregar las siguientes lineas de código, fíjate que en tu código existe un error en estas lineas ya que estos registros se encuentran en el banco 3 y no en el banco 1 de la memoria como esta implementado en el programa guía.

Código: [Seleccionar]
bsf STATUS,6
    bsf STATUS,5 ; banco 2
    CLRF   ANSELH          ;ENTRADAS DIGITALES
    CLRF ANSEL

De esta manera funciona si problema alguno.
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: ECHEARANJUEZ en 15 de Abril de 2013, 11:57:12
Para que funciones debes agregar las siguientes lineas de código, fíjate que en tu código existe un error en estas lineas ya que estos registros se encuentran en el banco 3 y no en el banco 1 de la memoria como esta implementado en el programa guía.

Código: [Seleccionar]
bsf STATUS,6
    bsf STATUS,5 ; banco 2
    CLRF   ANSELH          ;ENTRADAS DIGITALES
    CLRF ANSEL

De esta manera funciona si problema alguno.

Ecxelente un paso mas, ahora me enciende y me apaga el led con el flanco de subida, pero no se me interrumpe el triger lo que necesito es que mietras el led este encendido no halla pulso en el triger
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: Darkman_A en 15 de Abril de 2013, 12:11:27
Para que funciones debes agregar las siguientes lineas de código, fíjate que en tu código existe un error en estas lineas ya que estos registros se encuentran en el banco 3 y no en el banco 1 de la memoria como esta implementado en el programa guía.

Código: [Seleccionar]
bsf STATUS,6
    bsf STATUS,5 ; banco 2
    CLRF   ANSELH          ;ENTRADAS DIGITALES
    CLRF ANSEL

De esta manera funciona si problema alguno.

Ecxelente un paso mas, ahora me enciende y me apaga el led con el flanco de subida, pero no se me interrumpe el triger lo que necesito es que mietras el led este encendido no halla pulso en el triger

En "inicio" chequea si el bit del led esta en 1 ( o en cero como prefieras; BTFss o BTFsc) y luego ejecutas la rutina call trigger. Si no pones una condicion lo hace siempre.
Fijate si necesitas o no deshabilitar la interrupcion mientras generas el pulso (durante la rutina del pulso),  para que no te quede un pulso cortado.
Saludos.
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: BrunoF en 15 de Abril de 2013, 12:13:44
Si bien soy partidario del uso de las interrupciones, en este caso particular me parece que estás complicando tal vez más de lo que está solucionando. Si el propósito de la interrupción no es académico no me parece un buen caso para utilizar  la interrupción.

Desactivando la interrupción y colocando:

TRIGER
        BTFSC PORTB,0
        GOTO TRIGER

        BSF PORTA,0
        ...

Alcanza y sobra para tu propósito.

Ojo que en ese caso se puede perder la separación entre pulsos de 60mS.


Por otro lado, estás guardando y restaurando de forma errónea los registros clave (W y STATUS en este caso). No podés usar movf libremente, porque movf es una instrucción que modifica el flag Z del registro STATUS, por lo que estás corrompiendo el correcto valor del registro a restaurar. Eso puede hacer que tu programa se descontrole en el momento menos pensado. Revisá la forma correcta de hacerlo, revisando el datasheet de tu uC, bajo la sección: Context Saving During Interrupts.
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: tapi8 en 15 de Abril de 2013, 13:06:37
Citar
Si bien soy partidario del uso de las interrupciones, en este caso particular me parece que estás complicando tal vez más de lo que está solucionando. Si el propósito de la interrupción no es académico no me parece un buen caso para utilizar  la interrupción.

Totalmente de acuerdo, no se porque motivo la gente, a veces, cree que las interrupciones son la solucion a todo y hay muchas veces que complican algo que seria muy simple.

Tambien pasa que hay profesores que se los mandan hacer asi, para que aprendan, pero les mandan hacer ejemplos tan "malos" que en vez de aprender "desaprenden"  :P :P
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: ECHEARANJUEZ en 15 de Abril de 2013, 13:18:48
Citar
Si bien soy partidario del uso de las interrupciones, en este caso particular me parece que estás complicando tal vez más de lo que está solucionando. Si el propósito de la interrupción no es académico no me parece un buen caso para utilizar  la interrupción.

Totalmente de acuerdo, no se porque motivo la gente, a veces, cree que las interrupciones son la solucion a todo y hay muchas veces que complican algo que seria muy simple.

Tambien pasa que hay profesores que se los mandan hacer asi, para que aprendan, pero les mandan hacer ejemplos tan "malos" que en vez de aprender "desaprenden"  :P :P


Lo que quiero implementar es un sensor de distancia ultrasonico, pero como apenas me inicio en esto de los pics y la programación, me pareció que lo primero que tenia que hacer  era aprender las interrupciones, ya que necesito contar el ancho de pulso que le llega al puerto rb0 ya que este esta en funcion de la distancia, o si alguien me recomienda otra forma mas sencilla de hacerlo se lo agradecería mucho.   
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: Chenao en 15 de Abril de 2013, 15:24:47
Citar
Lo que quiero implementar es un sensor de distancia ultrasonico, pero como apenas me inicio en esto de los pics y la programación, me pareció que lo primero que tenia que hacer  era aprender las interrupciones, ya que necesito contar el ancho de pulso que le llega al puerto rb0 ya que este esta en funcion de la distancia, o si alguien me recomienda otra forma mas sencilla de hacerlo se lo agradecería mucho. 

Si quieres medir el ancho de un pulso en el foro hay bastante info del tema, es más hay ejemplos de todas la clases y en todo los lenguajes,  sólo utiliza el buscador del foro y te saldrá bastantes hilos, te recomiendo el hilo del compañero REDPIC donde enseña algunas técnicas (creo que son las únicas) para medir el ancho de un pulso utilizando diferentes modulo de hardware de la máquina.
Título: Re: No logro que el programa entre a Interrupción por RB0 pic16f887
Publicado por: tapi8 en 15 de Abril de 2013, 15:57:46
Si, hay informacion por el foro, en esencia es darle al sensor orden de enviar eco, poner un TIMER a contar (TMR1 es el mas preciso) y cuando caiga el receptor del sensor leer ese TMR, supongo que hay mas maneras de hacerlo.

Recorde que hablamos de esto no hace mucho aqui:

http://www.todopic.com.ar/foros/index.php?topic=34630.0

Hay una documentacion bastante buena del SRF-05 en español.

A hacer interrupciones esta bien que aprendas, puede que en este caso te sean utiles, pero hay veces que no van bien...