He realizado unas pocas mejoras al codigo, para que trabaje mas eficientemente, he reducido un poco el tamaño del codigo de interrupcion y tambien he kitado la espera activa de interrupcion, para que en vez de esperar, empiece a ejecutar el primer proceso inmediatamente despues de cargar todos en la cola de procesos. Y por ultimo he cambiado las variable "x" y "proceso" a variables locales del main(), y en el caso de la variable "proceso", ahora es de tipo BOOLEAN, para que el codigo sea mas claro y gaste algo menos de memoria.
Aki esta el codigo:
#include <18f452.h>
#fuses NOWDT,NOPROTECT,XT
#use delay (clock=4000000)
#include <LCD.C>
#byte TOSU = 0xFFF
#byte TOSH = 0xFFE
#byte TOSL = 0xFFD
#byte STATUS = 0xFD8
#byte BSR = 0xFE0
#byte STKPTR = 0xFFC
int cola_proc[5][3]; //Concurrencia para 5 procesos
int W_temp[5];
int BSR_temp[5];
int STATUS_temp[5];
int save_W;
int save_STATUS;
int save_BSR;
int i=0;
// ----------------Rutina de interrupcion para cambio de proceso----------------
#INT_RTCC FAST //FAST - para controlar nosotros mismos SAVE,RESTORE(BSR,W,etc.)
void cambio_proceso ()
{
//Almacenamos estado actual del procesador
#asm
MOVWF save_W
MOVFF STATUS, save_STATUS
MOVFF BSR, save_BSR
#endasm
W_temp=save_W;
STATUS_temp=save_STATUS;
BSR_temp=save_BSR;
cola_proc[0]=TOSU; //Salvamos la direccion de la ultima sentencia
cola_proc[1]=TOSH; //ejecutada del proceso i
cola_proc[2]=TOSL;
lcd_putc("f");
i+=1;
IF (i>4) i=0; //Cuando hemos ejecutado todos los procesos, volvemos al primero
TOSU=cola_proc[0]; //Cargamos en la cima de la pila, la direccion de la
TOSH=cola_proc[1]; //siguiente instruccion a ejecutar del proceso i
TOSL=cola_proc[2];
//Restauramos estado del procesador para el proceso i
save_W=W_temp;
save_STATUS=STATUS_temp;
save_BSR=BSR_temp;
#asm
MOVF save_W, W
MOVFF save_STATUS, STATUS
MOVFF save_BSR, BSR
#endasm
}
// -----------------------------------------------------------------------------
main()
{
BOOLEAN proceso=FALSE; //Deshabilitamos entrada a procesos
int x;
lcd_init();
setup_counters(rtcc_internal,rtcc_div_1);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
set_rtcc(0);
// --------------------PROCESO 0--------------------
#asm
push
#endasm
cola_proc[0][0]=TOSU; //Salvamos la 1ª sentencia del proceso 0
cola_proc[0][1]=TOSH;
cola_proc[0][2]=TOSL;
WHILE (proceso)
{
printf(lcd_putc,"0");
}
// -----------------------------
// --------------------PROCESO 1--------------------
#asm
push
#endasm
cola_proc[1][0]=TOSU; //Salvamos la 1ª sentencia del proceso 1
cola_proc[1][1]=TOSH;
cola_proc[1][2]=TOSL;
WHILE (proceso)
{
printf(lcd_putc,"1");
}
// -----------------------------
// --------------------PROCESO 2--------------------
#asm
push
#endasm
cola_proc[2][0]=TOSU; //Salvamos la 1ª sentencia del proceso 2
cola_proc[2][1]=TOSH;
cola_proc[2][2]=TOSL;
WHILE (proceso)
{
printf(lcd_putc,"2");
}
// -----------------------------
// --------------------PROCESO 3--------------------
#asm
push
#endasm
cola_proc[3][0]=TOSU; //Salvamos la 1ª sentencia del proceso 3
cola_proc[3][1]=TOSH;
cola_proc[3][2]=TOSL;
WHILE (proceso)
{
printf(lcd_putc,"3");
}
// -----------------------------
// --------------------PROCESO 4--------------------
#asm
push
#endasm
cola_proc[4][0]=TOSU; //Salvamos la 1ª sentencia del proceso 4
cola_proc[4][1]=TOSH;
cola_proc[4][2]=TOSL;
WHILE (proceso)
{
printf(lcd_putc,"4");
}
// -----------------------------
proceso=TRUE; //Habilitamos entrada a procesos
FOR (x=1;x<5;x++) //Cargamos la direccion del primer proceso y limpiamos pila
{
#asm
pop
#endasm
}
goto_address(*STKPTR); //Ejecutamos proceso 0,que se encuentra en cima de pila
}