|
multitasking.h |
Descripción:
Facilita
la programación de tareas que deben ser ejecutadas
periodicamente,
aunque en un sentido más amplio permite la programación
apoyada en bases de tiempo.
Se usa el Timer0 para generar una interrupción con un periodo
definido por base_time
, para cada tarea se incrementa un contador hasta que el tiempo
predefinido es alcanzado, entonces se pone a 1 la bandera para que esa
tarea pueda ser ejecutada.
Esta librería está incluida en el instalador GcBasic-PL,
pero se puede descargar directamente:
multitasking.h
|
Uso:
Actualmente
un máximo de 16 Tasks y 8 LTasks son posibles.
El
tiempo base debe ser definido:
#define base_time valor
Donde
valor es el periodo deseado en us, por ejemplo:
#define
base_time 100
' for 100 us
Máximo
valor de base_time con reloj de 20 MHz es 13107.
Máximo
valor de base_time con reloj de
4 MHz es 65535.
Máximo
valor de base_time con otras velocidades de reloj:
65535/ChipMhz/4.
La
subrutina conteniendo la tarea debe ser definida:
#define Task1 Sub_nombre1
#define Task2 Sub_nombre2
#define
LTask1 Sub_nombre3
El
periodo para cada Task debe ser definido, por ejemplo:
#define Task1_us 500
'
Periodo para Task1es 500 us
#define Task2_ms 10
'
Periodo para
Task2 es 10 ms
#define LTask1_s 1
'
Periodo
para
LTask1 es 1 s
En
este ejemplo, Sub_nombre1 se ejecutará cada 500 us, Sub_nombre2
cada 10 ms y Sub_nombre3 cada 1 seg.
El
valor máximo para el periodo de Task es: base_time*255
Por
ejemplo, con 100 us base_time, el valor máximo es:
100*255
= 25500 us => 25 ms
LTask
es para tasks de periodo largo, un periodo es largo o nó
dependiendo de base_time:
Cuando
el periodo > base_time*255 entonces necesitas un LTask.
El
valor máximo para el periodo de LTask es: base_time*65535
Por
ejemplo, con 100 us base_time, el valor máximo para el periodo
de LTasks es:
100*65535
= 6553500 us => 6553 ms => 6 s
Cada
tarea se ejecutará con el comando: Do_Taskx,
Por ejemplo en el bucle principal:
do
Do_Task2
Do_LTask1
loop
O
de cualquier otra manera, por ejemplo:
do
Do_Task2
if PORTB.0 on then Do_LTask1
loop
Es
posible ejecutar un Task directamente en la subrutina de interrupciones:
#define Run_Task1
'Ejecutar
tarea en la subrutina de interrupciones
Hay
una variable contador para cada task: cont_Taskx
Una
variable de
periodo:
time_Taskx
Y
una bandera:
flag_Taskx
Estas
variables se pueden usar en el programa, leyéndolas o
escribiéndolas para conseguir diversos comportamientos; ver el
siguiente ejemplo, donde la variable time_task3 se usa para
obtener un Task de periodo variable.
|
|
Ejemplo:
|
'________________________________________________________________________________
'
'
Example for multitasking.h
'
'
'
One led atached to PORTB.0 toggles at 1 s rate
'
One led atached to PORTB.1 toggles at
300 ms s rate
'
One led atached to PORTB.3 toggles at
a variable rate, defined by ReadAD
'
'________________________________________________________________________________
'
#chip 16F876A, 20 'MHz
#config HS_OSC, WDT_OFF,
LVP_OFF, PWRTE_ON
'________________________________________________________________________________
#include
<multitasking.h>
#define base_time 500
'Base time in us
#define Task1 read_input
'Task1 subroutine
#define Task1_us 500
'This task will run every 500 us
#define Task2 led2
'Task2 subroutine
#define Task2_ms 300
'This task will run every 300 ms
#define Task3 led3
'Task3 subroutine
'We will have the period for this
task from ReadAD
#define LTask1 led1
'LTask1 subroutine
#define LTask1_s 1
'This task will run every 1 s
#define Run_LTask1
'Run Task inside interrupt subroutine
'________________________________________________________________________________
DIR PORTA.0 IN
DIR PORTB OUT
do
'Main Loop
Do_Task1
Do_Task3
Do_Task2
loop
'________________________________________________________________________________
Sub read_input
time_Task3
= ReadAD(An0)
'Read ADC
at PORTA.0
End Sub
Sub led1
PORTB
= PORTB xor
1 'Toggle led at PORTB.0
End Sub
Sub led2
PORTB
= PORTB xor 2
'Toggle led at PORTB.1
End Sub
Sub led3
PORTB
= PORTB xor 4
'Toggle led at PORTB.2
End Sub
|
|
|