TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: migsantiago en 05 de Noviembre de 2005, 13:58:00
-
Recordarán que en ensamblador cuando estaba corriendo un programa y de repente llega una interrupción, era necesario respaldar los datos almacenados en el registro de trabajo W y STATUS, para que al regresar de la interrupción la ejecución del programa no se viera afectada.
¿En lenguaje C se tiene que hacer eso? Uso el compilador PCWH versión IDE 3.43.
Y otra duda en C, cuando se regresa de la interrupción, ¿el código resetea las flags de interrupción automáticamente?
Gracias
-
Una de las ventajas de programar en lenguaje de alto nivel como es el c es que te puedes olvidar completamente de como funciona el micro internamente. De modificar los flags y dar valores a los distintos registros se encarga el compilador, tu no tienes que hacer nada.
Salu2
-
Qué bien Piriots
Entonces si el PIC está escribiendo en una LCD y de repente llega la interrupción, cuando salga de ella, ¿seguirá escribiendo en la LCD como si nada?
-
Hasta donde llego yo creo que asi es. Pero no sabria decirtelo seguro. A ver si se pasa por aqui alguien que controle mas que yo y nos saca de la duda.
-
hola compis, claro que C te guarda toda la informacion del programa que se esta corriendo cuando llega una interrupcion, en C no te tienes que preocupar de guardar esa informacion ya que lo hace automaticamente el compilador por ti. Osea, segun el ejemplo que ponia migsantiago, si se esta ejecutando la rutina de atencion a el LCD en escritura y por medio llega una interrupcion, a no ser que la interupcion modifique algo de la rutina del LCD, cuando volvamos de interrupcion, no tiene porque no seguirse escribiendo el LCD, es como si se hiciera una pausa y despues se continuara. Un saludo.
-
Gracias xerex, nos sacaste de una gran duda.
-
Hola a todos, algo que no me quedo claro es que si en C la interrupcion se hace en el mismo instante que llega o si se hace terminado el ultimo comando ejecutado... es decir si estoy haciendo una pausa de 5ms y en medio de esta pausa llega una interrupcion, el C lo atiende de inmediato o espera a terminar la pausa para atenderlo.
Pregunto esto, pues al hacer una interrupcion en Basic, se espera a que termine el comando para atender la interrupcion, mientras que va guardando lo que llega en memoria... La solucion para esto es hacer la interrupcion en Asembler... Por ello mi pregunta ¿Como lo hace en C?
Nos vemos
-
Me declaro con la misma duda... el lenguaje C no ha de ser mágico...
Por definición, la interrupción debería ser instantánea, sin importar si el PIC va a salvar el mundo, éste debe interrumpirse y hacer otra cosa, ¿pero en C qué pasa?
-
Hola, yo he trabajado con interrupciones en ccs y si estas haciendo una pausa (delay) y se activa una interrupción, el pic atiende esa interrupción y luego vuelve a la pausa por donde se ha quedado. Pero como el ccs genera código ensamblador, no sabría decir si internamente hace lo mismo. Quiero decir que una instrucción en ccs está compuesta por varias instrucciones en ensamblador, y si hay una interrupción no se si atenderá la interrupción inmediatamente o esperará a que acabe la instrucción en ensamblador por la que vaya...

Y respecto al primer post, yo tuve problemas con las interrupciones, y buscando por la ayuda del ccs encontré esto:
CLEAR_INTERRUPT( )
Syntax: clear_interrupt(level)
Parameters: level - a constant defined in the devices.h file
Returns: undefined
Function: Clears the interrupt flag for the given level. This function is designed for use with a specific interrupt, thus eliminating the GLOBAL level as a possible parameter.
Availability: All devices
Requires: Nothing
Examples: clear_interrupt(int_timer1);
Example Files: None
Also See: enable_interrupts(), #INT
La interrupción en la que tuve el problema fué en la interrupción externa.
Creo recordar que lo que pasaba esque la interrupción debería de activarse varias veces, pero sólo reaccionaba el pic en la primera.
Con la instrucción anterior solucioné mi problema.
Un saludo
-
Por definicion una interrupcion se ejecuta nada mas producirse. A nivel de ASM se termina la instruccion que se este ejecutando y se produce la interrupcion, si estamos en "C" y estamos en medio de varias instrucciones de ASM que forman la intruccion de "C" saltara al terminar la intruccion de ASM y aunque no haya terminado la instrucción en "C". Por otra parte el compilador CCS salva las variables al entrar en la subrutina de interrupcion, desabilita las interrupciones y al terminar recupera los registros, borra el flags de la interrupcion, habilita las interrupciones y retorna de la interrupcion. Esto lo hace de forma automatica, sin tener que añadir código. Esto posibilita el siguiente código:
#EXT_INT
ext_isr{
nValor++;
}
Incrementamos una variable dentro de la interrupcion y no hace falta borrar el flags, ni hacer retornos de interrupcion ni nada.
Solo es necesario hacer una operacion mas en la interrupcion del puerto B por nivel y es ¡¡¡¡¡antes de terminar la subrutina de interrupcion hay que leer o escribir en el puerto B!!!.
-
Escrito originalmente por jfh900
Solo es necesario hacer una operacion mas en la interrupcion del puerto B por nivel y es ¡¡¡¡¡antes de terminar la subrutina de interrupcion hay que leer o escribir en el puerto B!!!.
Comor??
-
Escrito originalmente por radon
Escrito originalmente por jfh900
Solo es necesario hacer una operacion mas en la interrupcion del puerto B por nivel y es ¡¡¡¡¡antes de terminar la subrutina de interrupcion hay que leer o escribir en el puerto B!!!.
Comor??
En el hilo siguiente esta la explicación de lo que pasa con la interrupción del puerto B por nivel:
http://miarroba.com/foros/ver.php?foroid=46840&temaid=4428090
-
Escrito originalmente por radon
Escrito originalmente por jfh900
Solo es necesario hacer una operacion mas en la interrupcion del puerto B por nivel y es ¡¡¡¡¡antes de terminar la subrutina de interrupcion hay que leer o escribir en el puerto B!!!.
Comor??
En el hilo siguiente esta la explicación de lo que pasa con la interrupción del puerto B por nivel:
http://miarroba.com/foros/ver.php?foroid=46840&temaid=4428090
-
Entendido jfh

El coach, ¿de qué versión sacaste esa instrucción? Yo tengo la ccs 3.43 y no existe.
-
Mi versión del ccs es la 3.221.
He mirado la última versión existente del ccs en su página y es la 3.239 , revisa la versión de tu compilador porque no me cuadra que sea la 3.43 
Gracias por la aclaración JFH, un saludo a tod@s
-
Yo tengo la versión: 3.222. Y respecto a la intrucción: clear_interrupt aparece en Built-In Functions, también aparece en busqueda, pero no aparece en Índice (en la ayuda se entiende).
-
Tienen razón, me equivoqué, el instalador dice que es la versión CCS PCWH 3.190.
Pues no está en built-in functions ni en búsqueda...
Lo que se le acerca es disable_interrupts
DISABLE_INTERRUPTS( )
Syntax:
disable_interrupts (level)
Parameters:
level - a constant defined in the devices .h file
Returns:
undefined
Function:
Disables the interrupt at the given level. The GLOBAL level will not disable any of the specific interrupts but will prevent any of the specific interrupts, previously enabled to be active. Valid specific levels are the same as are used in #INT_xxx and are listed in the devices .h file. GLOBAL will also disable the peripheral interrupts on devices that have it. Note that it is not necessary to disable interrupts inside an interrupt service routine since interrupts are automatically disabled.
Availability:
Device with interrupts (PCM and PCH)
Requires
Should have a #int_xxxx, Constants are defined in the devices .h file.
Examples:
disable_interrupts(GLOBAL); // all interrupts OFF
disable_interrupts(INT_RDA); // RS232 OFF
enable_interrupts(ADC_DONE);
enable_interrupts(RB_CHANGE);
// these enable the interrupts
// but since the GLOBAL is disabled they are not
// activated until the following statement:
enable_interrupts(GLOBAL);
Example Files:
ex_sisr.c, ex_stwt.c
Also See:
enable_interrupts(), #int_xxxx
-
De todas formas es una función que no es necesaria a no ser que queramos construir por nostros mismos la subrutina de interrupción. La ayuda pone lo siguiente:
Syntax:
clear_interrupt(level)
Parameters:
level - a constant defined in the devices.h file
Returns:
undefined
Function:
Clears the interrupt flag for the given level. This function is designed for use with a specific interrupt, thus eliminating the GLOBAL level as a possible parameter.
Availability:
All devices
Requires
Nothing
Examples:
clear_interrupt(int_timer1);
Example Files:
None
Also See:
enable_interrupts(), #INT
Si se quiere utilizar será preciso actualizar la versión o construir la función.