Autor Tema: Interrupcion por RB0. Ayuda urgente.  (Leído 3833 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado n-utz

  • PIC10
  • *
  • Mensajes: 5
Interrupcion por RB0. Ayuda urgente.
« en: 06 de Noviembre de 2016, 21:19:14 »
Tengo que entregar un trabajo ma;ana, simulando un ascensor. Tengo todo el codigo, pero estoy teniendo inconvenientes con una interrupcion por rb0.

Al presionar el pulsador del rb0, en la maqueta se abriran las puertas del ascensor y se detendra el movimiento del motor, hasta que se cierre y reanude todo el programa comunmente.

El programa cuenta con 3 pulsador, 1 por cada piso a utilizar, contando planta baja. Y otro pulsador que es el de la interrupcion en rb0, para la puerta como explique.

Les dejo el codigo de la interrupcion para ver si pueden ver en que esta fallando, y mas abajo el codigo completo, por si necesitan mas detalles del programa. Muchas gracias.


Código: [Seleccionar]
;ESPACIO EN MEMORIA
org 0x00
          goto Inicio
          org  0x04
          goto Interrupciones

;CONFIGURACION DE INTERRUPCIONES     
Interrupciones  bcf INTCON,GIE ;DESACTIVO INTERRUPCIONES GLOBALES
                bcf INTCON,INTF ;DESACTIVO INTERRUPCIONES POR RB0
                bsf PORTB,1 ;DETIENE EL MOTOR
Detener         btfss PORTB,0 ;VERIFICA PUERTA
                goto Fin_inter ;SI NO ESTA ABIERTA FIN DE INTERRUPCION
                goto Detener ;SI ESTA ABIERTA DETIENE EL MOTOR
Fin_inter       bsf     INTCON,GIE ;ACTIVA INTERRUPCIONES GLOBALES
                retfie ;RETORNO



CODIGO COMPLETO


Código: [Seleccionar]
#include <P16F628A.INC>

list  p=16f628a
__config 3f10

Contador1     equ 0x22 ;VARIABLES PARA RETARDO
Contador2     equ 0x23

;ESPACIO EN MEMORIA
org 0x00
          goto Inicio
          org  0x04
          goto Interrupciones

;CONFIGURACION DE INTERRUPCIONES     
Interrupciones  bcf INTCON,GIE ;DESACTIVO INTERRUPCIONES GLOBALES
                bcf INTCON,INTF ;DESACTIVO INTERRUPCIONES POR RB0
                bsf PORTB,1 ;DETIENE EL MOTOR
Detener         btfss PORTB,0 ;VERIFICA PUERTA
                goto Fin_inter ;SI NO ESTA ABIERTA FIN DE INTERRUPCION
                goto Detener ;SI ESTA ABIERTA DETIENE EL MOTOR
Fin_inter       bsf     INTCON,GIE ;ACTIVA INTERRUPCIONES GLOBALES
                retfie ;RETORNO

;INICIO DE PROGRAMA
Inicio      bcf STATUS,5 ;CAMBIO A BANCO 0
                bsf INTCON,GIE ;ACTIVA INTERRUPCIONES GLOBALES
                bsf INTCON,INTF ;ACTIVA INTERRUPCION POR RB0
                movlw 0x07 ;ELIMINA COMPARADORES
                movwf CMCON
                bsf STATUS,5 ;CAMBIO A BANCO 1
                bcf OPTION_REG,7 ;ACTIVO PULL-UPS INTERNOS
                bsf OPTION_REG,6 ;SE ACTIVA DE SUBIDA
                movlw B'11110001'
                movwf TRISB ;RB1, RB2 Y RB3 COMO SALIDA. DEMAS COMO ENTRADA
                movlw B'11111111'
                movwf TRISA ;PORTA COMO ENTRADA
                bcf STATUS,5 ;CAMBIO A BANCO 0
                ;clrf PORTA
                ;clrf PORTB
                bcf PORTB,1 ;ACTIVO MOTOR
                bsf    PORTB,2 ;BAJA HASTA QUE ESTE EN PLANTA BAJA
        btfss PORTA,0 ;PREGUNTA SI ESTA EN PLANTA BAJA
                goto    $-.1 ;LOOP HASTA QUE ESTE EN PLANTA BAJA
Verificacion    clrf    PORTB
                bsf    PORTB,1 ;PARO EL MOTOR
                btfss  PORTB,6 ;VERIFICA SI SE PULSA EL BOTON DEL SEGUNDO PISO
                goto    Verificacion2 ;SINO, SIGUIENTE VERIFICACION
                call    delay ;SI ESTA PULSADO, LLAMA A RETARDO
                btfsc  PORTB,6 ;VERIFICA NUEVAMENTE SI EL BOTON AL SEGUNDO PISO ESTA PULSADO
                call  ir_a_piso2 ;SI ESTA PULSADO, A SUBRUTINA PISO2
Verificacion2   btfss  PORTB,5 ;VERIFICA SI ESTA PULSADO EL BOTON DEL PRIMER PISO
                goto    Verificacion3 ;SINO, SIGUIENTE VERIFICACION
                call    delay ;SI ESTA PULSADO, LLAMA A RETARDO
                btfsc  PORTB,5 ;VERIFICA NUEVAMENTE SI EL BOTON AL PRIMER PISO ESTA PULSADO
                call    ir_a_piso1 ;SI ESTA PULSADO, A SUBRUTINA PISO1
Verificacion3   btfss  PORTB,4 ;VERIFICA SI SE PULSA EL BOTON DE PLANTA BAJA
                goto Verificacion ;SINO, VUELVE RETORNA AL INICIO DEL BUCLE
                call    delay ;SI ESTA PULSADO, LLAMA A RETARDO
                btfsc  PORTB,4 ;VERIFICA NUEVAMENTE SI EL BOTON A PLANTA BAJA ESTA PULSADO
                call    ir_a_pb ;SI ESTA PULSADO, A SUBRUTINA PB
                goto    Verificacion ;VUELVE AL LOOP

;SUBRUTINA A PISO2
ir_a_piso2      btfsc  PORTA,2 ;VERIFICA SI SE ENCUENTRA EN EL SEGUNDO PISO
                goto    Fin ;SI ESTA EN ESE PISO, TERMINA EL PROCESO
                btfss  PORTA,0 ;VERIFICA SI ESTA EN PLANTA BAJA
                btfsc  PORTA,1 ;VERIFICA SI ESTA EN EL PRIMER PISO
                call    Subir ;LLAMA A SUBRUTINA SUBIR
        btfss  PORTA,2 ;VERIFICA SI ESTA EN EL SEGUNDO PISO
                goto    ir_a_piso2 ;SI NO LLEGO AL SEGUNDO PISO SIGUE SUBIENDO
Fin             return ;VUELVE CUANDO ESTE EN PLANTA BAJA

;SUBRUTINA A PISO1
ir_a_piso1      btfsc PORTA,1 ;VERIFICA SI ESTA EN EL PRIMER PISO
                goto    Fin2 ;SI ESTA EN ESE PISO, TERMINA EL PROCESO
                btfss  PORTA,0 ;VERIFICA SI ESTA EN PLANTA BAJA
                goto    Condi ;SI NO ESTA VA A LA OTRA CONDICION
            call Subir ;SI ESTA, LLAMA A SUBRUTINA PARA SUBIR
                goto    Fin2
Condi         btfsc  PORTA,2 ;VERIFICA SI ESTA EN EL SEGUNDO PISO
                call    Bajar ;SI ESTA, LLAMA A SUBRUTINA PARA BAJAR
Fin2            btfss  PORTA,1 ;VERIFICA SI ESTA EN EL PRIMER PISO
                goto    ir_a_piso1 ;SINO ESTA EN EL PRIMER PISO, LOOP
                return ;SI ESTA EN PRIMER PISO, VUELVE

;SUBRUTINA A PB
ir_a_pb         btfsc PORTA,0 ;VERIFICA SI ESTA EN PLANTA BAJA
                goto    Fin3 ;SI ESTA EN ESE PISO, TERMINA EL PROCESO
                btfss  PORTA,2 ;VERIFICA SI ESTA EN EL SEGUNDO PISO
                btfsc  PORTA,1 ;SINO, VERIFICA SI ESTA EN EL PRIMER PISO
                call    Bajar ;SI ESTA EN ALGUNO DE ESOS PISO, LLAMA A SUBRUTINA PARA BAJAR
            btfss  PORTA,0 ;VERIFICA SI ESTA EN PLANTA BAJA
                goto    ir_a_pb ;SI NO ESTA EN PB, LOOP
Fin3            return ;SI ESTA EN PB, RETORNA

;SUBRUTINA PARA SUBIR
Subir           bcf    PORTB,1 ;ENCIENDE EL MOTOR
                bcf    PORTB,2 ;MOTOR PARA SUBIR
                return

;SUBRUTINA PARA BAJAR
Bajar           bcf    PORTB,1 ;ENCIENDE EL MOTOR
                bsf    PORTB,2 ;MOTOR PARA BAJAR
                return

;SUBRUTINA DE RETARDO
delay        movlw   .100
                movwf   Contador1
loop        movlw   .110
                movwf   Contador2
loop2      nop
                nop
                nop
                nop
                nop
                nop
                decfsz  Contador2,f
                goto    loop2
                decfsz  Contador1,f
                goto    loop
                return

;TERMINA EL PROGRAMA
                end



Desconectado Chaly29

  • Moderador Global
  • DsPIC33
  • *****
  • Mensajes: 4315
Re:Interrupcion por RB0. Ayuda urgente.
« Respuesta #1 en: 06 de Noviembre de 2016, 22:03:13 »
Hola n-utz, solo un par de cosas:

1) Cuando entras en una interrupción (o sea el programa salta a la dirección ORG .4), no hace falta que desactives las mismas, ya que el micro por si solo lo hace.

2) Cuando sales de la rutina de interrupción, tampoco hace falta que las actives, ya que la instrucción RETFIE aparte de producir el retorno, las activa.

3) En ningún momento antes del RETFIE veo que borres el flag de la interrupción activa. Por lo tanto recuerda de borrar los flag involucrados.

Un saludo.

Atte. CARLOS.

La teoría es cuando se sabe todo y nada funciona. La práctica es cuando todo funciona y nadie sabe por qué.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion por RB0. Ayuda urgente.
« Respuesta #2 en: 06 de Noviembre de 2016, 22:32:53 »
***** Lo escribi antes que Chaly asi que algunos temas pueden estar repetidos, nomas que tuve que salir, recien completo y envio ******

Como que estas un poco jugado con el tiempo. Deberias haber preguntado con anterioridad.

- Cuando entra a la interrupcion solo se pone a 0 el bit GIE deshabilitando las interrupciones. Cuando se ejecuta el RETFIE es como si se ejecutaran 2 instrucciones un RETURN y un BSF INTCONT, GIE. Es decir el RETFIE estaria poniendo a 1 el bit ese, habilitarlo antes podria llevar a un stack overflow.

- Depende como tengas tus sensores de deteccion de en que planta esta el ascensor puede que tengas algunos problemas. Pero arreglar esto significa que te vas a tardar mas que una sola noche.

La forma simple de arreglarlo es:

Código: ASM
  1. Interrupciones  
  2.                 bsf             PORTB,1                 ;DETIENE EL MOTOR
  3.  
  4.                 BCF             PORTB, X                ; Abro la puerta
  5.                 btfsc   PORTB,0                         ; Espera que abra la puerta por completo
  6.                 goto    $-1
  7.                
  8.                 BSF             PORTB, X                ; Cierro la puerta
  9.                 BTFSC   PORTB,0                         ; Espero que cierre por completo
  10.                                                
  11.  
  12.                 bcf             INTCON,INTF             ;DESACTIVO INTERRUPCIONES POR RB0
  13.                 retfie

Existen MUCHOS problemas que pueden ocurrir con este codigo.

- Le falta el guardado y reposicion de STATUS y W
- No hay nada que asegure que esto no ocurra entre medio de los pisos!
- Y seguro que alguno me estoy olvidando

Este codigo presupone que la puerta se abre por un momento y luego se cierra. Poner un delay dentro implica que vas a tener que SI o SI poner el codigo para salvar W y STATUS.
No entiendo tampoco por que deberia abrirse la puerta con una interrupcion y que directamente solo ocurra cuando llega al piso presionado.

Desconectado n-utz

  • PIC10
  • *
  • Mensajes: 5
Re:Interrupcion por RB0. Ayuda urgente.
« Respuesta #3 en: 07 de Noviembre de 2016, 00:45:26 »
Muy bien, agregué ese código, espero que vaya bien, contaré como me fue.

El profesor va a contar con un pulsador que lo único que hace es abrir las puertas del ascensor, y cuando eso suceda tiene que frenar el motor y demás. Supongo que lo a;adió como para complicarnos.

El "back up" de w y status, la linea logica sería:   entro a interrupcion - almaceno w y status en auxiliares - trabajo en la interrupcion - cargo los registros originales con los aux - retfie?

Agregandole eso, estaría solucionando posibles problemas?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion por RB0. Ayuda urgente.
« Respuesta #4 en: 07 de Noviembre de 2016, 01:32:44 »
Citar
El "back up" de w y status, la linea logica sería:   entro a interrupcion - almaceno w y status en auxiliares - trabajo en la interrupcion - cargo los registros originales con los aux - retfie?

Si haces mas cosas en la interrupcion, me refiero a ejecutar instrucciones que cambien el contenido de W y/o alguna bandera de STATUS, entonces si o si tenes que agregar ese codigo.
El codigo esta en el datasheet del micro, solo busca W_TEMP y lo vas a encontrar.

Los demas problemas no se van a solucionar por eso.

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Interrupcion por RB0. Ayuda urgente.
« Respuesta #5 en: 07 de Noviembre de 2016, 10:19:04 »
Hola n-utz.no he mirado tu codigo.pero ten en cuenta que para borrar la interrupción por cambio de estado en portb.antes de su borrado hay que leer el puerto.

Por ejemplo:

MovF portb,w
bcf intcon,rbif
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupcion por RB0. Ayuda urgente.
« Respuesta #6 en: 07 de Noviembre de 2016, 10:40:45 »
Hola n-utz.no he mirado tu codigo.pero ten en cuenta que para borrar la interrupción por cambio de estado en portb.antes de su borrado hay que leer el puerto.

Por ejemplo:

MovF portb,w
bcf intcon,rbif

No tengo el datasheet paraverificarlo, pero tengo entendido que eso es para la interrupcion de cambio de nivel, la interrupcion por flanco ( o interrupcion externa ) que es la del RB0 es distinta y no lo requiere.
Como decia no tengo el datasheet a mano aca en el trabajo.
Igual ya hoy debe estar entregando el trabajo, por eso le dije que habia sido un poco tarde.

Desconectado Chaly29

  • Moderador Global
  • DsPIC33
  • *****
  • Mensajes: 4315
Re:Interrupcion por RB0. Ayuda urgente.
« Respuesta #7 en: 07 de Noviembre de 2016, 11:12:03 »
Hola n-utz, la linea lógica a seguir sería:

Entro a interrupción
Almaceno W y STATUS en auxiliares
Trabajo en la interrupción
Restauro los registros STATUS  y W (partiendo de los resguardo)
Borro el flag de la interrupción que disparó el evento
RETFIE

Así como este código a continuación:

Código: [Seleccionar]
INTERRUPCION
bcf INTCON,GIE
movwf WWW ; Guardo el estado de los registros
swapf STATUS,W
movwf ESTADO

(AQUÍ TU RUTINA DE INTERRUPCIÓN)

swapf ESTADO,W ; Restauro el estado de los registros
movwf STATUS
swapf WWW,F
swapf WWW,W
bcf INTCON,RBIF ; Borro el flag de la interrupción
retfie

Fíjate que para guardar los reguistros STATUS y W no se puede hacer de manera directa, y se usa la sentencia SWAPF, tal como lo indico en el código.



Hola groundman, no es necesario leer el puerto antes del borrado del flag de interrupción, este borrado se puede hacer en cualquier momento. Pero si es recomendable leerlo (una ves entrada a la interrupción) lo más rápido posible para no "perder" el pin que creó el evento, ya que puede ser cualquier se los 4 involucrados.

Un saludo.

Atte. CARLOS.

La teoría es cuando se sabe todo y nada funciona. La práctica es cuando todo funciona y nadie sabe por qué.

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:Interrupcion por RB0. Ayuda urgente.
« Respuesta #8 en: 07 de Noviembre de 2016, 16:58:30 »
crei que estaba usando la interrupcion del PORTB.por lo vist es INT0.y no tiene nada que ver una con la otra.claro que cada pic usa sus propios nos.
Montando mi primera impresora 3D (Raprep Prusa i3)