Autor Tema: Interrupciones en PIC 16F628A  (Leído 4426 veces)

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

Desconectado Santoryu

  • PIC10
  • *
  • Mensajes: 2
Interrupciones en PIC 16F628A
« en: 01 de Noviembre de 2015, 05:05:34 »



org 3

   goto inicio
   goto pepito

inicio   configuro puertos y demas

interrupciones   bcf INTCON, 0
      bsf INTCON, 7
      bsf INTCON, 3
      goto interrupciones

pepito   permite mediante puerto b prender un led


El pic es 16F628a. Si configuro el puerto b y demas (trisb y bla bla). Y tengo una interrupcion global o del bit 3 del intcon.
¿A donde va esa interrupcion?. Ejecuta el goto pepito? Desde ya gracias .

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupciones en PIC 16F628A
« Respuesta #1 en: 01 de Noviembre de 2015, 09:09:31 »
Por si no queres leer demasiado al final doy la respuesta a tu pregunta, sino aca tenes la explicacion:

Tenes que entender que los vectores de esa familia son

Vector de reset 0x00
Vector de interrupcion 0x04

Asi que normalmente su suele hacer:

Código: ASM
  1. ORG 0x00
  2.     GOTO INICIO
  3. ORG 0x04
  4.     GOTO PEPITO

Cuando ocurra una interrupcion va a ir a la direccion 0x04 y ejecutar esa instruccion.

Respecto a tu programa tenes:

Código: ASM
  1. org 3
  2.  
  3.    goto inicio
  4.    goto pepito

Para ubicarte mejor voy a poner las posiciones de memoria de 0x00 a 0x04

0x00 = ADDLW 0xFF
0x01 = ADDLW 0xFF
0x02 = ADDLW 0xFF
0x03 = GOTO INICIO
0x04 = GOTO  PEPITO

Los ADDLW es por que cuando se borra la flash quedan todos en 1 sus bits, eso significa en opcode esa instruccion.
Como ves en tu programa, si ocurre el reset se ejecuta 3 veces el ADDLW y luego el GOTO INICIO,
Si ocurre una interrupcion solo se ejecutaria el GOTO PEPITO.

Resumen: Cuando entra a una interrupcion ejecutaria el GOTO PEPITO
Creo que eso es lo que preguntabas..
« Última modificación: 01 de Noviembre de 2015, 09:46:14 por KILLERJC »

Desconectado Santoryu

  • PIC10
  • *
  • Mensajes: 2
Re:Interrupciones en PIC 16F628A
« Respuesta #2 en: 01 de Noviembre de 2015, 16:10:35 »
Gracias por la respuesta, hice este programa para probar este tema justamente y me resulta en que al agregar la interrupcion no enciende el led, y quitandosela esto si pasa. tenes idea donde puede estar el inconveniente. Desde ya gracias y perdon por las molestias :3 adjunto prints de pantalla.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Interrupciones en PIC 16F628A
« Respuesta #3 en: 01 de Noviembre de 2015, 17:10:58 »
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 :P


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:

Código: ASM
  1. 0x41 = SUBLW 0x10
  2. 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.

Código: ASM
  1. interrupcion:
  2.         MOVWF   W_TEMP
  3.         SWAPF   STATUS, W
  4.         BCF     STATUS, RP0
  5.         MOVWF   STATUS_TEMP
  6.  
  7.         ; Aca codigo de la interrupcion
  8.  
  9.         SWAPF   STATUS_TEMP, W
  10.         MOVWF   STATUS
  11.         SWAPF   W_TEMP, F
  12.         SWAPF   W_TEMP, W
  13.         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

Código: ASM
  1. #include <P16F628A.inc>
  2.  
  3. __config 0x3F10
  4.  
  5.  
  6. CBLOCK 0x70
  7. STATUS_TEMP
  8. W_TEMP
  9. ENDC
  10.  
  11.  
  12.  
  13.         org 0x00
  14.         GOTO    start
  15.         org 0x04
  16.         GOTO    interrupcion
  17. start:
  18.         BANKSEL TRISA           ; Selecciono banco donde esta TRISA
  19.         CLRF    TRISA           ; Pongo todo el puerto A como salida
  20.         BANKSEL PORTA           ; Vuelvo al banco 0, donde esta CMCON y los PORTx
  21.         CLRF    PORTA           ; Pongo a 0 el PORTA
  22.         MOVLW   0x07
  23.         MOVWF   CMCON           ; Puerto A todo como digital
  24.  
  25.         MOVF    PORTB, W        ; Leo el puertoB asi me permite borrar el flag
  26.         BCF     INTCON, RBIF    ; Borro el flag
  27.         BSF     INTCON, RBIE    ; Activo interrupciones
  28.         BSF     INTCON, GIE
  29.  
  30. principal:                      ; Loop principal, aca podrias encender otro led con una demora
  31.         GOTO    principal
  32.        
  33. interrupcion:
  34.         MOVWF   W_TEMP
  35.         SWAPF   STATUS, W
  36.         BCF     STATUS, RP0
  37.         MOVWF   STATUS_TEMP
  38.  
  39.         BTFSC   INTCON, RBIF    ; Esto lo pongo para que veas como es cuando existen varias interrupciones juntas
  40.         CALL    int_RB          ; En caso de estar en 1 haga este codigo, sino sale
  41.  
  42.         SWAPF   STATUS_TEMP, W
  43.         MOVWF   STATUS
  44.         SWAPF   W_TEMP, F
  45.         SWAPF   W_TEMP, W
  46.         RETFIE
  47.  
  48. int_RB
  49.         MOVF    PORTB, W        ; Aca podria comprobar cual de los RB4 a 7 fue el que cambio
  50.         BCF     INTCON, RBIF    ; y de paso leo asi puedo borrar el flag
  51.         BTFSS   PORTB, 4        ; Pregunto si esta en 1, recorda que entra tanto cuando esta en 0 como en 1
  52.         RETURN                  ; En caso de ser 0 salgo
  53.         MOVF    PORTA, W
  54.         XORLW   0x01            ; Hago una XOR del bit0, si estaba en 0 pasa a 1, si estaba en 1 pasa a 0
  55.         MOVWF   PORTA           ; Actualizo el puerto y salgo
  56.         RETURN
  57.  
  58.         END


 

anything