Programación Específica > Microcontroladores
Uso De Interrupciones Con Pic 16f877
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; Variables para la salvaguarda del contextopclath_temp RES 1status_temp RES 1reg_temp RES 1 ;******** VECTORES DE INTERRUPCIÓN ************************************* RESET_VECT CODE 0x000 ; Vector de reset del procesador nop ; "nop" pagesel inicio ; goto inicio ; Salto al inicio del programa ;******************************************************************* INT_VECTOR CODE 0x004 ; Zona del vector de interrupción goto ServInt ; ISR CODE 0x005ServInt: banksel w_temp movwf w_temp movf STATUS,w movwf status_temp ;hasta aquí guarda de registros btfsc INTCON,INTF ;¿ocurrió flanco en rb0? goto noint movlw b'00110100' ; indicar interrupción banksel PORTB movwf PORTB bcf INTCON,INTF ; Limpia las interrupciones pendientes noint banksel status_temp ; recupera lo guardado movf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ; ;***** PROGRAMA PRINCIPAL ********************************************* MAIN CODE ; Zona de Programa inicio: bcf INTCON,GIE ;Deshabilito por si acaso movlw b'00001001' ; banksel TRISB ; configurando el puerto B movwf TRISB movlw b'00000000' ; banksel PORTB movwf PORTB bsf INTCON,INTE ; banksel OPTION_REG ; bsf OPTION_REG,INTEDG; bsf INTCON,GIE ; bcf INTCON,1; Limpia las interrupciones pendientes goto $ ; 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 ;paranoia movwf irq_w swapf irq_w,F movfw STATUS movwf irq_status ;cambio de contexto btfss INTCON, (mi interrupcion);[PIR1,(mi interrupcion)]probar aqui ;el tipo de interrupcion goto ATENDER ATENDER ;el codigo necesario END_ISR movfw irq_status ;vuelve al contexto anterior movwf STATUS swapf irq_w,W retfie ;esta instruccion coloca el GIE en ON INICIO ;mi codigoEND
Saludos
Oldkami
oldkami:
erratas:
--- Código: Text --- btfsc INTCON, (mi interrupcion);[PIR1,(mi interrupcion)]probar aqui ;el tipo de interrupcion goto ATENDER ;si el bit esta en set atiende goto END_ISR ;si es clear sale de la rutina (aunque si es asi ;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
[#] Página Siguiente
[*] Página Anterior
Ir a la versión completa