3 - Complete o código para o sistema abaixo: ( 0,7 pontos)
- Tarefa 1: o buzzer (pino RC1) deverá ser acionado 5 ms ligado e 5 ms desligado;
- Tarefa 2: a mensagem “OLA” deverá ser enviada repetidamente via comunicação serial, com baud-rate de 4800bps (cada carácter precisa pelo menos de
para ser transmitido);
- Tarefa 3: o pino RD1 deve alternar 10 ms ligado e 10 ms desligado;
Lembre-se que neste exercício é adotado o “COOPERATIVE MULTITASK” e agora só podem ser executadas no máximo 2 tarefas em cada intervalo de tempo
void main (void){
TRISCbits.TRISC1=0;
TRISDbits.TRISD1=0;
TOCON=0b10000111; //PRE=16
TXSTAbits.BRGH=1;
BAUDCONbits.BRG16=0;
SPBRG=250; //4800bps
TXSTAbits.SYNC=0;
RCSTAbits.SPEN=1;
TRISCbits.TRISC6=1;
TXSTAbits.TXEN=1;
for(;😉{
START_TIMER();//2,5ms
switch(slot){
case 0:
while (TXSTAbits.TRMT==0) {}
TXREG=‘O’;
slot=1;
break;
}
VERIFY_END_TIMER();
}
}
void main (void){
TRISDbits.TRISD1=0;
TOCON=0b10000111; //PRE=16
TXSTAbits.BRGH=1;
BAUDCONbits.BRG16=0;
SPBRG=250; //4800bps
TXSTAbits.SYNC=0;
RCSTAbits.SPEN=1;
TRISCbits.TRISC6=1;
TXSTAbits.TXEN=1;
for(;😉{
START_TIMER();//2,5ms
switch(slot){
case 0:
while (TXSTAbits.TRMT==0) {}
TXREG=‘O’;
slot=1;
break;
}
VERIFY_END_TIMER();
}
}
Passo 1
O enunciado pede um escalonador cooperativo para três tarefas com estas restrições:
- Tarefa 1 (buzzer em RC1): 5 ms ligado, 5 ms desligado → período de 10 ms.
- Tarefa 2 (envio de “OLA” via serial a 4800 bps): cada caractere leva ≈ 2,2 ms → 3 caracteres levam ≈ 6,6 ms.
- Tarefa 3 (led em RD1): alterna ligado/desligado a cada 10 ms → período de 20 ms (toggle a cada 10 ms).
O hardware já está configurado de modo que cadaSTART_TIMER(); ... VERIFY_END_TIMER();
dá exatamente 2,5 ms de “slot”. Em cada slot só podem rodar até 2 tarefas. Vamos organizar um ciclo de 4 slots (4×2,5 ms = 10 ms), pois: - Em 4 slots conseguimos encaixar os 3 envios de caractere (3 slots), os dois eventos de ligar/desligar o buzzer (slots 0 e 2) e um toggle de RD1 (slot 3).
- O toggle de RD1 a cada 10 ms se dá uma vez por ciclo de 4 slots.
Passo 2
Definimos um contador
slot
que varia de 0 a 3. Em cada iteração do for(;;)
fazemos:START_TIMER();
para abrir um slot de 2,5 ms.- Um
switch(slot)
que executa até duas ações:- slot 0: enviar ‘O’ e ligar RC1 (buzzer)
- slot 1: enviar ‘L’
- slot 2: enviar ‘A’ e desligar RC1
- slot 3: togglear RD1
- Incrementar
slot
; se chegar a 4, volta a 0. VERIFY_END_TIMER();
para aguardar o fim dos 2,5 ms.
Passo 3
Precisamos declarar e inicializar
slot
e, antes do laço, forçar estados iniciais dos pinos de saída.Passo 4
Segue o código completo em C para o PIC, respeitando as diretivas do enunciado e escalonando as tarefas conforme descrito:
#include <xc.h>
// declaração de variável de slot
static unsigned char slot = 0;
void main(void){
// configurações iniciais
TRISCbits.TRISC1 = 0; // RC1 como saída (buzzer)
TRISDbits.TRISD1 = 0; // RD1 como saída (LED)
LATCbits.LATC1 = 0; // buzzer desligado inicialmente
LATDbits.LATD1 = 0; // LED desligado inicialmente
// Timer e UART já configurados conforme enunciado
TOCON = 0b10000111; // prescaler 1:16
TXSTAbits.BRGH = 1;
BAUDCONbits.BRG16 = 0;
SPBRG = 250; // 4800 bps
TXSTAbits.SYNC = 0;
RCSTAbits.SPEN = 1;
TRISCbits.TRISC6 = 1; // RX pin como entrada (UART)
TXSTAbits.TXEN = 1; // habilita transmissão UART
for(;;){
START_TIMER(); // abre slot de 2,5 ms
switch(slot){
case 0:
// envia 'O'
while(TXSTAbits.TRMT == 0) {}
TXREG = 'O';
// liga buzzer (primeiros 5 ms)
LATCbits.LATC1 = 1;
break;
case 1:
// envia 'L'
while(TXSTAbits.TRMT == 0) {}
TXREG = 'L';
break;
case 2:
// envia 'A'
while(TXSTAbits.TRMT == 0) {}
TXREG = 'A';
// desliga buzzer (próximos 5 ms)
LATCbits.LATC1 = 0;
break;
case 3:
// toggle em RD1 a cada 10 ms
LATDbits.LATD1 = ~LATDbits.LATD1;
break;
}
// avança slot e reinicia a cada 4
slot++;
if(slot == 4) slot = 0;
VERIFY_END_TIMER(); // espera completar 2,5 ms
}
}
Resposta
#include <xc.h>
static unsigned char slot = 0;
void main(void){
TRISCbits.TRISC1 = 0;
TRISDbits.TRISD1 = 0;
LATCbits.LATC1 = 0;
LATDbits.LATD1 = 0;
TOCON = 0b10000111;
TXSTAbits.BRGH = 1;
BAUDCONbits.BRG16 = 0;
SPBRG = 250;
TXSTAbits.SYNC = 0;
RCSTAbits.SPEN = 1;
TRISCbits.TRISC6 = 1;
TXSTAbits.TXEN = 1;
for(;;){
START_TIMER();
switch(slot){
case 0:
while(TXSTAbits.TRMT == 0){}
TXREG = 'O';
LATCbits.LATC1 = 1;
break;
case 1:
while(TXSTAbits.TRMT == 0){}
TXREG = 'L';
break;
case 2:
while(TXSTAbits.TRMT == 0){}
TXREG = 'A';
LATCbits.LATC1 = 0;
break;
case 3:
LATDbits.LATD1 = ~LATDbits.LATD1;
break;
}
slot++;
if(slot == 4) slot = 0;
VERIFY_END_TIMER();
}
}