Ahi va un ejemplo sencillo de multitarea en CCS:
1. Se usa la interrupción por desbordamiento de TMR0 cada milisegundo.
2. En la función de interrupción (que se ejecuta cada milisegundo), se incrementa los valores de CONTA1, 2 y 3 y cuando se igualan con los valores predefinidos de TIEMPO1, 2 y 3, se ejecuta la función correspondiente Funcion1(), 2 y 3.
//--------------------------------------------------------------//
// MULTITAREA.c
// Ciclo de encendido (0,5 s) y apagado (0,5 s) de LED en RB1.
// Ciclo de encendido (250 ms) y apagado (250 ms) de LED en RB2.
// El Display de Cátodo común, cambia de estado cada 1000 ms
// Se usa interrupción de TMR0 para retardo de 1 ms.
// Se controla que transcurra los tiempos TIEMPO1, 2 y 3 para
// que se ejecute la función correspondiente
//--------------------------------------------------------------//
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT,NOCPD,NOWRT
#use delay (clock=4000000)
int8 FLAG1=0, FLAG2=0, FLAG3=0, num=0; // Las banderas en cero
int16 TIEMPO1=500, TIEMPO2=250, TIEMPO3=1000; // 500 ms, 250 ms y 1000 ms
int16 CONTA1=0, CONTA2=0, CONTA3=0; // Contadores en cero
int8 LED[10]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 10 elementos de 0 a 9
void Funcion1()
{
FLAG1 = 0;
output_toggle(PIN_B1);
}
void Funcion2()
{
FLAG2 = 0;
output_toggle(PIN_B2);
}
void Funcion3()
{
FLAG3 = 0;
num=num+1;
output_c (LED[num]);
if (num==9)
num=-1;
}
//--------------------timer0 interrupt----------------------------
// Se ejecuta esta función cada milisegundo y se compara los valores
// de CONTAx y TIEMPOx
#int_timer0
void isr()
{
set_timer0(6); // Valor inicial de TMR0=6
CONTA1++; // Se incrementa CONTA1 cada ms
if (CONTA1 > TIEMPO1) // Transcurrió 500 ms?
{
CONTA1 = 0; // SI: borra CONTA1 y FLAG1=1
FLAG1 = 1;
}
CONTA2++; // Se incrementa CONTA2 cada ms
if (CONTA2 > TIEMPO2) // Transcurrió 250 ms?
{
CONTA2 = 0; // SI: borra CONTA2 y FLAG2=1
FLAG2 = 1;
}
CONTA3++; // Se incrementa CONTA3 cada ms
if (CONTA3 > TIEMPO3) // Transcurrió 1000 ms?
{
CONTA3 = 0; // SI: borra CONTA3 y FLAG3=1
FLAG3 = 1;
}
}
void main()
{
// Se configura interrupción por desbordamiento de TMR0, cada 1 ms (aproximadamente)
setup_timer_0(rtcc_internal|rtcc_div_4); // Prescaler = 4
enable_interrupts(int_timer0); // habilita interrupción timer0
enable_interrupts(global); // habilita interrupción global
output_high(PIN_B1);
output_high(PIN_B2);
while(TRUE)
{
if (FLAG1==1) // Si transcurrieron 500 ms se ejecuta Funcion1()
Funcion1();
if (FLAG2==1) // Si transcurrieron 250 ms se ejecuta Funcion2()
Funcion2();
if (FLAG3==1) // Si transcurrieron 1000 ms se ejecuta Funcion3()
Funcion3();
}
}