Ed. Técnica, perguntado por rafaelbrdf, 11 meses atrás

Apesar de não ser em todos os casos, em muito deles os sistemas embarcados devem controlar saídas em tempo real. Esse tipo de aplicação abrange um outro conceito e padrões para se criar algoritmos, não utilizados/necessários para outros tipos de projetos, como programar o perfil de uma página da internet, por exemplo. Os temporizadores são periféricos internos aos microcontroladores ideais para prover referência precisa de tempo, no entanto estes podem ser associadas a técnicas clássicas de sincronismo de tarefas, como o uso de contadores. Muitos programadores já utilizaram contadores para sincronizar seus sistemas embarcados, e, apesar de aparentemente simples, essa técnica antiga se mostra poderosa e eficiente.

Considere o seguinte problema para sistemas embarcados: Deseja-se construir um projeto eletrônico com um botão e dois leds, onde o led1 deve permanecer piscando em 2 Hz e o led2 que fica apagado, deve acender durante 2 segundos, somente se o botão for pressionado. Como o algoritmo pode ser construído para controlar o sistema de forma efetiva, considerando apenas o uso de rotinas de delay, sem temporizadores, e que o acionamento do botão dura no mínimo 30 ms?

Escolha uma:
a. Deve ser usado uma máquina de estados binária, através de uma variável booleana. Quando o programa atua no primeiro estado, o led1 é acionado/invertido entre intervalos de 250 ms, sempre checando o botão. Quando este é acionado, o sistema entra no segundo estado acionando o led2 com um delay de 2 segundos.
b. Deve ser usado um loop infinito com um único comando de delay, de 50 ms, um valor logo acima dos 30 ms do acionamento do botão, para garantir que o botão não seja interpretado duplamente. Os tratamentos dos leds podem ser feitos através de um contador, usado para contar para o led1 quando o botão não for pressionado, e depois para contar o tempo do led2 quando o botão for acionado.
c. O loop infinito pode ter apenas um único comando de delay, de menos de 30 ms, como 25 ms, para não haver a chance de um pressionamento não ser percebido. Os leds devem ser controlados a partir então de contadores, um para cada led. O contador CNT1 pode ser decrementado a cada loop, enquanto não atinge o zero. Quando ocorre, o programa deve inverter o led1 e carregar o CNT1 com o valor 10, mantendo-se assim. Paralelamente, o botão deve ser verificado a cada iteração, caso o CNT2 esteja nulo. Caso o botão seja acionado, o led2 é ligado e o CNT2 deve ser carregado com 80, e decrementado a cada próxima iteração. Quando o CNT2 zerar, o led2 deve ser desligado, e está pronto para um novo acionamento.
d. Pode-se afirmar que não há nenhuma forma de se criar um sincronismo que cumpra, mesmo que de uma forma aproximada, as exigências impostas pelo problema, usando apenas rotinas de delay. Para sincronismo múltiplo, como é o caso, deve-se usar temporizadores, exclusivamente.
e. Usa-se uma função auxiliar para acionar o led2 por 2 segundos (_delay_ms(2000);) quando o botão for acionado, e a função principal deve manter o led1 piscando em 2Hz (_delay_ms(250);)

Soluções para a tarefa

Respondido por henrymordenti20
62
c. O loop infinito pode ter apenas um único comando de delay, de menos de 30 ms, como 25 ms, para não haver a chance de um pressionamento não ser percebido. Os leds devem ser controlados a partir então de contadores, um para cada led. O contador CNT1 pode ser decrementado a cada loop, enquanto não atinge o zero. Quando ocorre, o programa deve inverter o led1 e carregar o CNT1 com o valor 10, mantendo-se assim. Paralelamente, o botão deve ser verificado a cada iteração, caso o CNT2 esteja nulo. Caso o botão seja acionado, o led2 é ligado e o CNT2 deve ser carregado com 80, e decrementado a cada próxima iteração. Quando o CNT2 zerar, o led2 deve ser desligado, e está pronto para um novo acionamento.

graitonneves: correto
Perguntas interessantes