Complete o código baseado no sistema cooperative multitasking abaixo de forma que os níveis lógicos nos pinos de I/O RD1, RD2, RD3, RD4 e RD5 sejam alternados a cada
e 150 ms respectivamente. (0,70 pontos)
Obs1: em cada tarefa só pode ser relacionado um pino de I/O.
Obs2: em cada intervalo de tempo (loop) só podem ser executadas no máximo 3 tarefas.
unsigned char slot=0; unsigned char cont
;
void START_TIMER(void){
TMROH=0xFC;
TMROL
;
INTCONbits.TMROIF=0;
}
void VERIFY_END_TIMER(void){
while(INTCONbits.TMROIF==0) {}
}
void TAREFA1(void){
cont++;
if (cont==4){
PORTDbits.RD1=!PORTDbits.RD1; cont=0;
}
}
void TAREFA2(void){
switch(slot){
case 0:
slot=1;
break;
}
void TAREFA3(void){
}
void TAREFA4(void){
}
VERIFY_END_TIMER();
}}
}
Obs1: em cada tarefa só pode ser relacionado um pino de I/O.
Obs2: em cada intervalo de tempo (loop) só podem ser executadas no máximo 3 tarefas.
unsigned char slot=0; unsigned char cont
|
|
|||||||||||||||
|
||||||||||||||||
|
|
|||||||||||||||
|
||||||||||||||||
|
} | |||||||||||||||
Passo 1
O enunciado pede que a gente complete um sistema simples de cooperative multitasking em C para um PIC, de forma que cinco pinos de PORTD sejam alternados (toggle) a cada 200 ms, 600 ms, 300 ms, 300 ms e 150 ms (respectivamente RD1, RD2, RD3, RD4 e RD5). O temporizador está ajustado para gerar um tick de 50 ms a cada estouro de TMR0 (com
TMR0H=0xFC; TMR0L=0x2F
). Em cada tarefa podemos usar apenas um pino e, em cada loop (cada intervalo de 50 ms) não podemos chamar mais de 3 tarefas. Vamos usar um slot
que alterna entre dois estados, chamando 3 tarefas num slot=0
e 2 tarefas em slot=1
. Cada tarefa terá o seu próprio contador (contX
) e um limiar igual ao período desejado dividido por 50 ms.Passo 2
Calcular quantos ticks de 50 ms são necessários para cada período:
- 200 ms → 200/50 = 4 ticks
- 600 ms → 600/50 = 12 ticks
- 300 ms → 300/50 = 6 ticks
- 300 ms → 300/50 = 6 ticks
- 150 ms → 150/50 = 3 ticks
Passo 3
Declarar cinco contadores globais e implementar cada tarefa para incrementar o seu contador e, quando atingir o limiar, alternar o pino correspondente e zerar o contador.
unsigned char slot = 0;
unsigned char cont1 = 0, cont2 = 0, cont3 = 0, cont4 = 0, cont5 = 0;
void START_TIMER(void) {
TMR0H = 0xFC;
TMR0L = 0x2F;
INTCONbits.TMR0IF = 0;
}
void VERIFY_END_TIMER(void) {
while (INTCONbits.TMR0IF == 0) { }
}
void TAREFA1(void) {
cont1++;
if (cont1 == 4) {
PORTDbits.RD1 = !PORTDbits.RD1;
cont1 = 0;
}
}
void TAREFA2(void) {
cont2++;
if (cont2 == 12) {
PORTDbits.RD2 = !PORTDbits.RD2;
cont2 = 0;
}
}
void TAREFA3(void) {
cont3++;
if (cont3 == 6) {
PORTDbits.RD3 = !PORTDbits.RD3;
cont3 = 0;
}
}
void TAREFA4(void) {
cont4++;
if (cont4 == 6) {
PORTDbits.RD4 = !PORTDbits.RD4;
cont4 = 0;
}
}
void TAREFA5(void) {
cont5++;
if (cont5 == 3) {
PORTDbits.RD5 = !PORTDbits.RD5;
cont5 = 0;
}
}
Passo 4
No
main
ou na rotina principal de loop fazemos:START_TIMER()
para reiniciar TMR0;- pelo
switch(slot)
chamamos até 3 tarefas; - atualizamos
slot
para a próxima posição; - esperamos
VERIFY_END_TIMER()
antes de repetir o ciclo.
void main(void) {
// Configuração de PORTD como saída, configuração de TMR0 etc.
TRISD = 0x00;
// ... outras iniciais ...
while (1) {
START_TIMER();
switch (slot) {
case 0:
TAREFA1();
TAREFA2();
TAREFA3();
slot = 1;
break;
case 1:
TAREFA4();
TAREFA5();
slot = 0;
break;
}
VERIFY_END_TIMER();
}
}
Resposta
O código completo acima implementa as cinco tarefas com contadores independentes, alternando somente até 3 tarefas por intervalo de 50 ms e garantindo os períodos de 200 ms, 600 ms, 300 ms, 300 ms e 150 ms em RD1, RD2, RD3, RD4 e RD5, respectivamente.