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 2,2 \mathrm{~ms} 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();
    }
}

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 cada START_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:
  1. START_TIMER(); para abrir um slot de 2,5 ms.
  2. 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
  3. Incrementar slot; se chegar a 4, volta a 0.
  4. 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();
    }
}

Exercícios relacionados