Atividade 1 (obrigatória):


Implementando um " cronômetro/relógio de parede" através de interrupções


Atualizado em 01/10/2010
  1. Deseja-se interromper a CPU de um ATmega88 de 1 Mhz (default de uma CPU sem relógio externo e sem programação de fusível) uma vez por segundo utilizando interrupções do Timer/Counter 0 a fim de atualizar um "cronômetro" conforme especificação a seguir. Verifique através do datasheet (p. 103) que mesmo com o valor máximo do pre-scaler (1024) isto não é possível. Para resolver este problema, escreva uma rotina de interrupção count1sec acionada pelo Timer/Counter 0 e que através de um contador global invoca uma subrotina clock para atualizar o cronômetro uma vez por segundo. Para testar o seu programa, a subrotina clock deve simplesmente incrementar um contador binário de segundos e retornar. Teste o seu programa com o simulador disparando o seu programa via F5 e interrompendo-o n segundos depois (n =~ 20 pois o simulador é pelo menos 20 vezes mais lento que um sistema real). Este teste é importante, mas você não precisa submeter a sua solução pois ele será utilizado no item a seguir.
  2. Escreva  um programa que simula um cronômetro/relógio de parede, disparado e congelado por uma entrada digital em um pino da Porta B simulando um botão do tipo toggle, ou seja, ao ser acionada a entrada digital o cronômetro será disparado se estiver inativo, caso contrário a contagem de tempo deverá ser interrompida. Ao ser disparado pela entrada digital o "cronômetro" deve inicializar o timer0 para interromper a CPU a cada tick do relógio em vez de a cada segundo conforme colocado no item anterior. Razão: Você vai usar o simulador no teste e o tempo da simulação não tem correlação com o tempo real das interrupções. Escreva uma rotina de interrupção que essencialmente implementa o "cronômetro/relógio de parede" abaixo especificado. Você deve vizualizar a atualização do "cronômetro" usando o recurso de "Auto Step" do simulador.
    Sugestão: a fim de testar o seu programa na situação de contorno dada pela passagem de 23h59m59s para 00h00m00s coloque o valor inicial do cronômetro na memória RAM e altere-o manualmente para, digamos, 23h 59min 00 segs (em hexadecimal teriamos 3233 3539 3030). Você deverá ver o relógio passar para 23h 59min 59s, depois para 24h 00min 00 seg e imediatamente para 00h 00min 00 segs.
  3. Usando as rotinas descritas acima e o HAPSIM para disparar as diversas funções do cronômetro através de "botões" ligado á entrada digital e exibir o valor do tempo no simulador de display LCD escreva um programa que implementa um cronômetro que possua no mínimo as seguintes funções: a) inicializa o cronômetro com um valor HHMMSS (em ASCII) a ser fornecido por uma porta de entrada; b) dispara o cronômetro: se o valor armazenado no contador do cronômetro for zero - conta de forma crescente, se o valor for maior que zero conta de forma decrescente e para a contagem quando esta atingir o valor zero; c) Lap: quando  ativado o Lap a contagem de tempo é congelada no LCD porém o  cronômetro continua a contagem voltando a mostra-la quando o Lap é desativado.  Ajuste a temporização do seu cronômetro para que, embora executando no simulador, possua o menor erro possível.

Especificação do cronômetro/relógio de parede

Escreva uma subrotina clock que toma como entrada um apontador no par X para uma área de memória com 6 bytes onde é mantido um contador de tempo em ASCII no formato hhmmss ( horas minutos segundos), onde os bytes do contador conterão os seguintes valores máximos (em ASCII): 23hs, 59 mins, 59 segs. O contador deve ser inicializado com os valores ASCII 00, 00, 00 (em hexadecimal: 3030, 3030, 3030). Cada chamada à subrotina deve somar 1 segundo ao contador e os seus dígitos devem ser atualizados de forma apropriada. Depure a sua subrotina com o recurso de "Auto Step" do simulador.
Sugestão: utilize o recurso de endereçamento com predecrementação de X para varrer e atualizar os dígitos do contador da "direita para a esquerda", ou seja, a partir do dígito menos significativo de segundos; se escrita com cuidado sua subrotina conterá apenas 15 instruções. Ela será utilizada neste laboratório para atualizar um "cronômetro/relógio de parede" acionado a cada segundo por uma rotina de interrupção.
A subrotina clock deverá também zerar o contador quando o mesmo atingir o valor 24:00:00 hs. Sugestão: para este fim escreva outra subrotina simples, chk24h e chame-a imediatamente antes de retornar da subrotina clock. Alternativamente você pode colocar o código de chk24h diretamente no final da subrotina clock.