Você está na página 1de 8

EA871 Experimento 11 TIMERS (I): SYSTICK E WATCHDOG

Rose Landeira de Macedo RA 137550




Introduo e objetivos
Neste experimento foi utilizado o software CodeWarrior 10.4 para executar dois programas
determinados pelo professor. O objetivo do primeiro programa exibir um relgio no visor de LCD que indica
as horas, os minutos e os segundos (a partir de uma entrada de horrio inicial). J o segundo programa visa
piscar duas cores de LEDs enquanto o programa segue na sua execuo normal, e um LED vermelho quando
um tempo limite de processamento esgotado (ou seja, ocorre algum travamento na execuo do programa).
O objetivo real do experimento familiarizar os alunos com um recurso muito importante nos
sistemas digitais: os timers. So introduzidos dois tipos de timers: o timer do sistema (SysTick) e o watchdog.
Alm de compreender os conceitos, os alunos tambm conseguiro ver exemplos de como esses recursos
podem ser aplicados de maneira til.

Descrio do experimento e resultados obtidos
Antes do incio do experimento, o Captulo 3.4.10 do manual KL25 Sub-Family Reference Manual e a
Seo B3.3 do manual ARM v6-M Architecture Reference Manual foram lidos. Eles explicam os detalhes de
funcionamento dos timers existentes no programa: o tick do sistema (SysTick) e o watchdog.
Inicialmente foi criado um projeto bsico em C no software CodeWarrior 10.4. O seu arquivo main.c
foi editado de acordo com as instrues e o cdigo fornecidos pelo professor (anexo 1). As funes InitGPIO(),
del3ms(), pulso(), enviaLCD(), RS(), InitLCD(), ConvNpraDec(), mandaString() e limpaLCD(), presentes
no programa, j so conhecidas e foram utilizadas e exploradas em experimentos anteriores. Entretanto, duas
novas funes foram introduzidas neste experimento.
A primeira delas a InitSysTick():

Essa funo responsvel por inicializar o timer tick do sistema (SysTick). Esse timer recebe um valor
determinado pelo programador, inicia uma contagem decrescente com ele de acordo com a frequncia de
clock desejada e, quando a contagem se encerra, uma interrupo chamada. Aps o cumprimento do evento,
a contagem reiniciada a partir de um determinado valor de reload. Dessa maneira, conclui-se que ele opera
gerando uma interrupo periodicamente, permitindo que o sistema mantenha um contador de tempo
atualizado. Para que ele seja corretamente configurado, quatro registradores recebem valores que
determinam como esse recurso dever operar.
A primeira linha, SYST_RVR = 20480, determina que o valor de reload do SysTick vale 20480. Ou seja,
quando o contador atingir o nmero 0, a contagem se reiniciar a partir do valor determinado como reload,
20480.
J a segunda linha, SYST_CVR = 0, responsvel por setar o valor do contador em 0. Dessa maneira, a
instruo anterior automaticamente torna-se vlida e, em seguida, o valor 20480 atribudo ao contador do
sistema.
Por fim, a terceira linha, SYST_CSR = 0x00000007, responsvel por determinar algumas flags que
atribuem caractersticas ao SysTick:

A COUNTFLAG uma flag que determina se o contador possui valor igual ou diferente de 0.
Nessa instruo, ela recebe o nmero 0, indicando que o contador possui um valor diferente de
0.
A CLKSOURCE uma flag responsvel por determinar se o clock utilizado para realizar a
contagem ser o do processador ou algum outro referencial externo. Como ela possui valor
lgico 1, o clock que ser utilizado pelo SysTick neste caso o clock do processador.
A TICKINT uma flag responsvel por determinar se as interrupes esto ativadas ou no.
Como ela tambm possui valor lgico 1, as interrupes esto ativadas e ocorrero quando o
contador atingir o fim da contagem
A ENABLE uma flag que determina se a contagem do contador est ativa ou no. Como
Recebendo o valor 1, permitido que o contador inicie sua contagem.
Considerando as observaes realizadas acima respeito das trs linhas da funo isoladamente,
possvel sintetizar a sua finalidade. A funo InitSysTick() determina que o clock do programa (de
20.48MHz) ser utilizado para a contagem, que inicia no valor 20480. Desse modo, o contador inicia com o
valor 20480 e, a cada 1/20.48 ms, o seu valor decresce em uma unidade. Realizando os clculos, conclui-se
que o contador ir chegar ao valor 0 cada 1ms. Sabendo que, quando o valor 0 atingido, o SysTick inicia
uma interrupo, a cada 1ms a funo SysTick_Handler() responsvel por executar a interrupo ser
chamada.
A funo SysTick_Handler() foi ento analisada:

Primeiramente ela contm a declarao de uma varivel do tipo static unsigned int com nome ms. O
tipo de declarao static indica que o valor da varivel mantido aps a execuo da rotina; ou seja, o valor
que ms conter ser sempre o mesmo que ela possua na ltima execuo da funo SysTick_Handler().
Posteriormente, ocorre um incremento da varivel ms. Caso ela atinja o valor 1000, um comando condicional
tambm executado. Nele, a varivel ms recebe o valor 0 e atribudo o nmero 1 uma varivel global fl.
Interpretando as instrues acima, foi possvel concluir o real objetivo da interrupo. Como a cada
1ms a funo SysTick_Handler() chamada, a varivel ms ser incrementada 1000 vezes antes do comando
condicional ser iniciado. Ou seja, se passaro 1000*1 ms a partir da sua primeira execuo o que resulta em
1s. Quando as instrues internas ao if forem executadas, a varivel ms receber o valor 0 (assim, a contagem
de 0 1000 ser reiniciada por mais 1 segundo) e a varivel fl, o valor 1. Portanto, essa interrupo realiza a
contagem de 1s e, quando esse completado, atribui o valor 1 varivel fl, utilizada na funo main.

Na funo main, primeiramente so declaradas as variveis s, m e h e atribudo o valor 16 h, 30 m
e 0 s. A varivel fl tambm recebe o valor 0. Posteriormente, so realizadas as inicializaes das GPIOs, do
visor LCD e do SysTick.
criado um loop for, que enlaa todo o restante da funo. Internamente ele, checado se a varivel
fl a mesma que foi analisada a funo SysTick_Handler() - possui valor 1. Caso positivo (ou seja, foi
completado o tempo de 1 segundo), fl recebe o valor 0 e, como ela uma varivel global, ela tambm
possuir esse valor na funo de interrupo, auxiliando o reincio da contagem e a varivel s
incrementada. Um novo comando condicional, interno ao primeiro, aplicado: caso a varivel s atinja o valor
60 (ou seja, passaram-se 60 segundos), ela recebe o valor 0 e a varivel m incrementada. Internamente
esse if, mais uma condio deve ser analisada: caso a varivel m obtenha o valor 60, ela zerada e a varivel h
sofre um incremento. Por fim, mais uma condio realizada internamente essa: caso h seja superior 23,
ela recebe o valor 0.
Ainda dentro do loop for, mas externamente aos comandos condicionais, os valores de h, m e s so
enviados para o visor LCD, separados por dois pontos (:).
Analisando a essa funo, foi possvel concluir como todo o programa opera e que ele desempenha a
funo de exibir um relgio no visor LCD. Primeiramente, atravs do valor da frequncia do clock do
processador, possvel determinar um certo valor para que o SysTick realize sua contagem a cada 1ms. Assim,
a cada 1ms uma interrupo atendida. Aps o atendimento de 1000 interrupes ou seja, o tempo de 1s ,
uma varivel flag muda de valor, informando funo main que se passou 1 segundo. O valor dos segundos
atualizado e, caso ele seja maior que 59, os minutos so atualizados e o valor dos segundos passa a ser 0,
como em qualquer relgio. De maneira anloga, o programa tambm checa se o valor dos minutos maior que
59 atualizando o valor das horas e zerando o valor dos minutos e se o valor das horas maior que 23
reiniciando assim a contagem das horas. Por fim, os valores so enviados ao visor LCD (que, assim,
atualizado a cada segundo).
Como o valor de h foi inicializado em 16, o de m, em 30, e o de s, em 0, o visor exibiu, em um primeiro
momento, o valor de 16h30 (16:30:00). Logo aps a contagem foi iniciada e o relgio desempenhou sua
funo corretamente.

Aps a anlise completa do programa acima, foi criado um novo projeto bsico em C no software
CodeWarrior 10.4. O seu arquivo main.c foi editado de acordo com as instrues e o cdigo fornecidos pelo
professor (anexo 2):



Em seguida, o arquivo kinetis_sysinit.c foi aberto e a constante KINETIS_WDOG_DISABLED_CTRL foi
trocada pelo valor 0x0000000C:

Assim, o watchdog foi ativado e recebeu o valor 0x0C.
O watchdog um timer do sistema que realiza uma contagem crescente at um valor determinado pelo
programador. Caso esse valor mximo seja atingido, ocorre um overflow: o valor do watchdog retorna 0 e o
programa reiniciado. Esse timer tem como principal finalidade evitar que o programa continue sendo
executado por grandes perodos de tempo durante um travamento. Forando um reset do sistema, ele impede
que tempo e processamento sejam desperdiados.
Aps consultar o manual KL25 Sub-Family Reference Manual, foi possvel obter mais detalhes sobre o
que essa mudana altera na execuo do programa e o seu watchdog:

Atravs dela, o watchdog habilitado em seu modo normal (COPW recebe o bit 0), configurado para
utilizar o clock interno do sistema (COPCLKS recebe o bit 0) como referncia e ter como quantidade limite 2
10

ciclos de clock (COPT recebe o valor 11).
Assim, o watchdog realizar a contagem de 0 at 1024. Caso ela seja atingida, o sistema reiniciar.
Sabendo que o clock interno opera em uma frequncia de 1kHz, possvel estimar que o watchdog aguarda o
tempo limite de, aproximadamente, 1 segundo de espera antes de reiniciar o sistema.
Aps a realizao dessa anlise, o projeto foi compilado e debugado. O programa foi ento executado
fora do modo debug com o auxlio do boto Disconnect.
Inicialmente, a primeira observao foi que o LED da placa KL25Z piscava alternadamente nas cores
verde e azul. Para explorar o funcionamento do programa, um dos botes da placa auxiliar foi pressionado.
Quando o mesmo foi apertado por um tempo menor que 1 segundo, a cor do LED automaticamente foi
alterada e a sequncia prosseguiu. Entretanto, quando a botoeira ficou pressionada por mais que 1 segundo, o
LED tornou-se da cor vermelha. Para compreender melhor tais observaes, o cdigo do programa foi
cuidadosamente analisado.
Primeiramente, dois valores so atribudos a duas variveis, atravs do comando define. So eles
define DELINIC 1500000 e define DELPISCA 650000. Depois, a funo InitGPIO() inicializa e configura as
GPIOs que sero utilizadas.
A funo ClrCOP() foi ento definida. Basicamente, ela atribui os valores 0x55 e, depois, 0xAA ao
registrador SIM_SRVCOP. Consultando o manual KL25 Sub-Family Reference Manual, percebe-se que,
quando esses dois valores so atribudos a esse registrador, em sequncia, o watchdog reinicia sua contagem.
Posteriormente, a funo pisca() determinada. Ela executa duas aes: inverte o nvel lgico do pino
19 da porta B, correspondente ao LED verde, e o do pino 1 da porta D, correspondente ao LED azul. Dessa
maneira, ela alterna a cor do LED que est sendo exibido: o que estava aceso, apaga, e o que estava apagado,
acende.
Em seguida, a funo delayPisca() apresentada. Primeiramente declarada uma varivel inteira
sem sinal tempo. Depois, construdo um loop for que possui como parmetros a varivel tempo iniciando com
o valor definido para DELPISCA (nesse caso, 650000) e sendo decrementada at atingir o valor zero. A cada
execuo do loop, realizado um comando condicional if, que testa se algum dos pinos 4, 5 ou 12 da porta A
possuem valor lgico diferente de 1. Caso afirmativo (ou seja, algum dos pinos possui valor 0), a varivel
tempo recebe o valor 1000. A finalidade real desse comando if testar se algum dos botes est pressionado.
Em caso afirmativo, a varivel tempo recebe um novo valor e, assim, o loop continua e a execuo do programa
fica presa ali at que todos os botes estejam soltos.
Por fim, a funo delayInic() definida. Novamente, uma varivel inteira sem sinal tempo declarada
e um loop for construdo. Os parmetros do loop so a varivel tempo iniciando com o valor definido para
DELINIC (nesse caso, 1500000) e sendo decrementada at atingir o valor zero. A cada execuo do loop, a
funo ClrCOP() chamada. Dessa maneira, a funo garante que, mesmo que um tempo de delay seja
executado nela, o watchdog continue sendo alimentado e no d um reset no sistema.
Assim, torna-se mais fcil compreender, por ltimo, o que a funo main desempenha. Aps inicializar
os GPIOs e configurar corretamente os LEDs, implementado um loop for que contm - nessa ordem - as
chamadas de funo para ClrCOP(), pisca() e delayPisca(). Dessa maneira, o watchdog reinicializado cada
entrada no loop; em seguida, os LEDs verde e azul se alternam- o que estiver aceso, apaga, e o que estiver
apagado, acende - e a funo delayPisca() checa se algum boto ainda est pressionado. Em caso negativo, a
execuo prossegue normalmente e, aps um intervalo de tempo (definido por DELPISCA), os LEDs verde e
azul se alternam novamente. Caso algum boto ainda esteja pressionado, a execuo do programa fica presa
no loop interno funo delayPisca(), fazendo com que o watchdog reinicie o sistema quando esse tempo de
execuo ultrapasse 1s e, assim, o LED torna-se vermelho (incio da funo main).
Para explorar o programa e as utilizaes do watchdog, o valor de DELPISCA no define foi alterado
para um valor maior: O programa foi ento compilado e executado.
O resultado obtido foi que o LED verde passou a piscar juntamente com o LED vermelho. Alm disso,
tambm foi observado que o tempo que cada uma das cores do LED permanece acesa era maior do que no
programa anterior.
Considerando as observaes realizadas e analisando a modificao realizada no programa, possvel
concluir que o tempo de delay determinado foi grande demais. Assim, antes mesmo da alternncia entre o LED
verde e o LED azul e uma execuo completa do programa, o watchdog atinge o seu valor mximo e reinicia o
sistema, exibindo o LED vermelho. Portanto, possvel inferir que, para intervalos de delay muito grandes,
necessrio zerar o valor do watchdog (atravs de uma chamada de funo ClrCOP() com periodicidade menor
que 1 segundo), evitando assim um reset do sistema em um momento indesejado.
O valor de DELPISCA foi ento retornado para o original ( ). Com o auxlio
de //, a instruo tempo = 10000 foi desativada e a SIM_SRVCOP = 0x00, ativada:


Aps compilar e executar o programa, foi observado que os LEDs verde e azul piscam normalmente.
Entretanto, quando qualquer boto pressionado, o programa reinicia ou seja, retorna para o LED verde.
Tal observao pode ser explicada pelo fato de que, segundo o manual KL25 Sub-Family Reference
Manual, quando qualquer valor diferente de 0x55 e 0xAA atribudo ao registrador SIM_SRVCOP, o sistema
automaticamente sofre um reset. Portanto, independentemente do valor que for determinado a esse
registrador que exceto os dois supracitados -, o programa reiniciar da mesma maneira.
Por fim, foi realizada uma ltima alterao no programa: aps ser retornado para o cdigo original, a
instruo ClrCOP() que estava determinada na forma de comentrio na funo delayPisca() foi ativada. O
programa foi novamente compilado e executado.
O resultado observado foi que os LEDs verde e azul piscam, novamente, de maneira normal. Alm
disso, independentemente de qual boto fosse pressionado, os LEDs continuavam se alternando com a mesma
frequncia, sem nenhuma mudana.
Tal modificao no programa s possvel j que, atravs da chamada da funo ClrCOP() dentro da
funo delayPisca(), o watchdog constantemente limpo e, assim, no atinge seu valor limite. Dessa maneira,
o programa fica incapaz de sofrer um reset. Assim, fica claro que reiniciar o watchdog internamente um loop
faz com que o sistema nunca seja reiniciado: essa observao pode ser muito til em casos de programas mais
complexos, que possuem um grande nmero de interaes e no qual um reset poderia ser algo indesejado.

Concluso
Atravs desse experimento, foi possvel compreender melhor o que um timer, seus recursos e como
ele opera. Por meio de dois programas, dois diferentes tipos de timers foram introduzidos: o SysTick e o
watchdog.
O primeiro programa - que realiza uma contagem decrescente e, ao seu fim, realiza uma interrupo
foi aplicado na construo de um relgio. A partir de um horrio inicial configurado no programa, o visor LCD
exibia horas, minutos e segundos e, claramente, era atualizado a cada segundo. Isso foi possvel graas ao
SysTick, que criava uma interrupo cada 1ms com uso do clock do processador e era capaz de marcar o
tempo transcorrido.
J o segundo programa consistia em piscar duas cores de LEDs (verde e azul) enquanto o programa
estivesse sendo executado corretamente. Quando, por algum motivo, a execuo do programa falhava e o
watchdog precisava ser acionado, o LED tornava-se vermelho. Esse erro ocorria devido alteraes
realizadas no programa inicial, como intervalos muito grandes de delay nas funes internas ao programa.
Dessa maneira, foi possvel compreender como os timers funcionam, como so interpretados e os
recursos existem para oper-los de modo que realizem um determinado objetivo. Tambm foram analisados
os erros que podem ocorrer quando um timer no corretamente programado, alm dos cuidados necessrios
ao utilizar esse recurso.

Você também pode gostar