Oido cocina, mañana que es domingo, no puedo, pero el lunes le pongo una chincheta.
La idea que yo tengo es poner aquí en este tema un determinado "bug" de CCS (de cualquier cosa), discutirlo entre todos y si se llega a la conclusión que efectivamente es un "bug" hacer una buena explicación y copiarlo en limpio en el tema con chincheta. El título del Tema con chincheta podría ser "Posibles bugs del compilador de CCS" si os parece bien.
Antes de seguir con esta cruzada he de decir que para mí el compilador de C que más me gusta es el de CCS, no porque sea el mejor, que quizá no lo sea, sino por la gran cantidad de personas que lo usan y que en un momento dado te pueden ayudar a resolver una duda.
Esta tarde se vé que tengo ganas de fastidiar al compilador y creo que he descubierto otra cosa que no funciona bien. Ojala me equivoque, por eso lo pongo aquí para discutirlo.
Se trata de la prioridad de las interrupciones en los PIC18.
Si un PIC18 tengo 2 interrupciones y una de ellas la declaro como de alta prioridad, pués si cuando se está ejecutando la instrucción de baja prioridad, llega la de alta prioridad pués se debe de abandonar inmediatamente la primera rutina e ir a atender a la rutina de alta prioridad.
Cuando finalice la rutina de alta prioridad retornará al punto donde se había quedado en la rutina de baja prioridad. Bueno, el caso es que creo que esto no funciona.
Os pongo un programa de ejemplo y os digo como reacciona.
#include <18F452.h>
#DEVICE HIGH_INTS=true
#use delay(clock=4000000)
#use fast_io(B)
#byte port_a = 0xF80
#byte port_b = 0xF81
//#PRIORITY int_ext,int_rb
//#PRIORITY int_rb,int_ext
#INT_TIMER0 // Interrupción externa en RB0
interrupcion_TIMER0() // Función de atención a la interrupción
{
delay_ms(3000);
output_toggle(PIN_B1);
disable_interrupts(INT_TIMER0);
}
#INT_EXT // Interrupción externa en RB0
interrupcion_RB0() // Función de atención a la interrupción
{
delay_ms(3000);
output_toggle(PIN_A0);
}
//#INT_RB // Interrupción externa en RB4-RB7
#INT_RB HIGH
//#INT_RB FAST
interrupcion_RB4_RB7() // Función de atención a la interrupción
{
delay_ms(3000);
#asm movf port_b,0 #endasm //Hace falta leer el portb, si no va mal
output_toggle(PIN_B3);
}
main()
{
set_tris_b(0xF5); // RB4 salida, RB4-RB7,RB0 entradas.
set_tris_a(0x00);
bit_clear(port_a,0);
bit_clear(port_b,1);
bit_clear(port_b,3);
//output_low(PIN_B3);
setup_counters(RTCC_8_BIT,RTCC_DIV_128);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RB);
enable_interrupts(INT_EXT);
while(1)
{
if(input(pin_b2))
enable_interrupts(INT_TIMER0);
}
}
La interrupción de RB0 es de baja prioridad y la de RB4..RB7 de alta.
Si activamos la interrupción RB0 y a continuación activamos la de RB4..RB7 tendría que ejecutar primero la interrupción RB4..RB7 y activar la salida RB3 para luego regresar a la interrupción RB0 y activar la salida RA0. Pués no, hace justamente lo contrario, primero activa la salida RA0 y luego la salida RB3.
Aquí os lo dejo, pensarlo.