Programación Específica > Microcontroladores

 Uso De Interrupciones Con Pic 16f877

<< < (3/4) > >>

karen81:
Las interrupciones son un conjunto de excepciones asincrónicas que permite el microprocesador para alterar la ejecución secuencial normal de instrucciones; estas se manejan a través de vectores que contienen la dirección física de la memoria donde se encuentra la rutina de servicio a la excepción solicitada.

es decir hacemos un programa que acepta interrupciones por lo que cada vez que se da una interrupcion el programa se interrumpe el micro guarda la direccion donde se interrumpio el programa y otras cosas en la pila (depende de que microcontrolador estemos usando) luego se va al vector de interrupcion donde esta la direccion de la rutina de servicio (que es la rutina que queremos que haga cuando se da la interrupcion) luego de realizarla saca lo que guardo en la pila y retorna a la direccion donde se dio la interrupcion y continua.
La diferencia entre las interrupciones enmascarables y las noenmascarables es que las enmascarables se pueden evitar, es decir si no queremos que se den las enmascaramos poniendo a uno o a cero una bandera (depende del micro) y aunque se de la condicion no se da la interrupcion. En cambio las noenmascarables no se puede evitar que se den ejemplo los RESET no se pueden evitar.
En cuanto a la interrupcion NMI e IRQ tendrias que especificar a que micro te refieres.

Espero que esto te ayude, si algo no te queda claro avisame ya que es un tema que recien acabo de pasar por lo que lo recuerdo muy bien

adios :comp:

SinChip:
Hola , yo también soy nuevo en el foro. He leído y releído vuestras respuestas ya que las necesito para solucionar un problema, pero aún no lo he conseguido. Se trata de hacer saltar al pic 16f877 a cualquier interrupción (estoy mosca porque esto se supone que es algo básico  :whistling: ).

Es la primera vez que trabajo con estos pics, y me parecen bastante potentes y sencillos de manejar, pero aquí hay algo que se me escapa.

Estoy usando las directivas de código relocalizable (CODE, IDATA, UDATA), aunque he usado las mismas estructuras de programa Imarte o Javierv para el uso de interrupciones viendo que no hay ninguna diferencia entre poner un ORG o un CODE  0x... cuando quieres que un bloque empiece desde una direccion concreta. Es decir, estas directivas no creo que me estén planteando problemas, ya que estoy depurando con ICD2 otros programas que he hecho (sin interrupciones) y van bien.

La interrupción que quiero activar es la de RB0 (es decir, INTE dentro de INTCON). Por cierto Imarte, ¿Qué quieres decir con?:


--- Citar --- Ahhh... se me olvidaba, OJO con INTCON.
--- Fin de la cita ---

precisamente a mí me está dando problemas, ya que intento poner a 0 el bit INTF para que vuelva a interrumpir, pero siempre está a 1, y en el 877 no hace falta seleccionar el banco de memoria que contiene a INTCON ya que está reflejado en los 4 bancos.

Os dejo el codiguito que me trae de cabeza, ya estoy empezando a desconfiar en la placa que he hecho, incluso en el icd2 :blink:



--- Código: Text ---;***** DEFINICIÓN DE VARIABLES **************************************** variables  UDATA 0x110w_temp    RES 1&#59; Variables para la salvaguarda del contextopclath_temp  RES 1status_temp  RES 1reg_temp    RES  1  ;******** VECTORES DE INTERRUPCIÓN ************************************* RESET_VECT  CODE    0x000   &#59; Vector de reset del procesador           nop            &#59; &#34;nop&#34;                                      pagesel     inicio  &#59;      goto      inicio  &#59; Salto al inicio del programa ;******************************************************************* INT_VECTOR  CODE       0x004  &#59; Zona del vector de interrupción    goto  ServInt  &#59; ISR    CODE  0x005ServInt:    banksel   w_temp                  movwf     w_temp       movf  STATUS,w     movwf  status_temp     &#59;hasta aquí guarda de registros     btfsc  INTCON,INTF  &#59;¿ocurrió flanco en rb0?    goto  noint                                 movlw  b'00110100'   &#59; indicar interrupción    banksel   PORTB    movwf  PORTB    bcf   INTCON,INTF                       &#59; Limpia las interrupciones pendientes      noint      banksel   status_temp    &#59; recupera lo guardado    movf      status_temp,w    movwf  STATUS    swapf     w_temp,f    swapf     w_temp,w            retfie                   &#59;   ;***** PROGRAMA PRINCIPAL ********************************************* MAIN    CODE               &#59; Zona de Programa inicio:     bcf  INTCON,GIE  &#59;Deshabilito por si acaso     movlw  b'00001001'   &#59;    banksel   TRISB        &#59; configurando el puerto B    movwf   TRISB    movlw  b'00000000'   &#59;     banksel   PORTB    movwf  PORTB     bsf  INTCON,INTE  &#59;    banksel   OPTION_REG  &#59;    bsf  OPTION_REG,INTEDG&#59;    bsf   INTCON,GIE  &#59;     bcf  INTCON,1&#59; Limpia las interrupciones pendientes     goto  &#036;             &#59; espera interrupcionesfin    END 
Bueno, espero que os sirva de algo el codigo, y si hay errores me lo decís. Ojalá sepais que me puede pasar, no estoy muy ducho con los PIC.

Gracias por adelantado.

oldkami:
1- Desde que yo programo pics (hace ya casi unos 4 años) es la primera vez que escucho que el GIE en INTCON se desactiva con solo ejecutarse una interrupción. Esto definitivamente !no es verdad¡ es necesario desactivar el INTCON,GIE si se quiere atender la interrupción, de lo contrario se corre el riesgo que el programa se interrumpa continuamente,  y esto puede causar multiples consecuencias, desde desbordar el stack del micro y ocasionar reset del mismo, hasta alterar los datos en las variables de contexto y volver de la interrupcion con datos totalmente erroneos (W,STATUS,OPTION, PCLATH, etc). solo cuando se realiza algo complejo como interrupciones priorizadas se tendria en cuenta no apagar el GIE. lo que si es cierto es que al ejecutar RETFIE el bit GIE es activado automaticamente para permitir atender la siguiente interrupcion.

2- En el codigo de sinchip existen dos errores, uno fatal y el otro no muy obvio.

a-  ¿btfsc    INTCON,INTF?  ; yo creo que es mejor btfss        :)
       goto    noint               ; de lo contrario siempre va a noint

b- cuando se seleccionan las variables para hacer el cambio de contexto, lo mejor es definirlas en la seccion UDATA_SHR, con el fin de no cambiar el registro STATUS con la operacion "banksel"  ya que si se regresa de la interrupcion se puede llegar al programa principal con un banco no deseado. ademas, repito hace falta apagar el GIE en el servicio de interrupciones.  algo asi como:


--- Código: Text ---    UDATA_SHRirq_w        res d'1'irq_status  res d'1' RESET_VEC  CODE  0x0000       pagesel  INICIO       goto       INICIO  INT_VEC   code 0x0004       pagesel  ISR       goto       ISR  ISR:      bcf         INTCON,GIE      btfsc      INTCON,GIE  &#59;paranoia       movwf    irq_w      swapf      irq_w,F      movfw    STATUS      movwf    irq_status    &#59;cambio de contexto       btfss      INTCON, (mi interrupcion);[PIR1,(mi interrupcion)]probar aqui                                                       &#59;el tipo de interrupcion      goto       ATENDER  ATENDER    &#59;el codigo necesario  END_ISR     movfw    irq_status    &#59;vuelve al contexto anterior     movwf    STATUS     swapf     irq_w,W     retfie                         &#59;esta instruccion coloca el GIE en ON  INICIO                                 &#59;mi codigoEND   



Saludos

Oldkami

oldkami:
erratas:

--- Código: Text ---   btfsc      INTCON, (mi interrupcion);[PIR1,(mi interrupcion)]probar aqui                                                    &#59;el tipo de interrupcion  goto       ATENDER                       &#59;si el bit esta en set atiende  goto       END_ISR                        &#59;si es clear sale de la rutina (aunque si es asi                                                    &#59;alguna interrupcion no prevista se ejecuto)   
Creo que asi es mas claro :)

Saludos

Oldkami

oldkami:
Errata 2:

uicchhh..

ISR:
     bcf         INTCON,GIE
     btfsc      INTCON,GIE  ;paranoia
     goto       ISR


tal vez ya esta muy tarde.. que duerman  -_-


Saludos

Oldkami

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa