Fazendo Watchdog Timer com Circuito NRF24LE1
Até agora, na série NRF24LE1, cobrimos muitos recursos interessantes e especiais que diferenciam o NRF dos outros. Hoje vamos discutir uma funcionalidade importante dos microcontroladores que os ajuda a se recuperar de falhas. Suponha que eu lhe dê uma tarefa para resolver em um tempo predefinido e você não consiga fazê-la no tempo previsto, então você terá que iniciá-la desde o início. A palavra 'Timeout' pode ser usada aqui para esclarecer o conceito.
Fig. 1: Protótipo de Watchdog Timer baseado em NRF24LE1
Mas você sabia que o microcontrolador também pode controlar o tempo e, se não conseguir realizar a tarefa no tempo previsto, pode reiniciar sozinho. Isso é feito para evitar mau funcionamento e travamentos. Ou podemos dizer que em caso de falha do sistema ele reinicia automaticamente. Isso também elimina a necessidade de reinicialização manual manual. É uma parte essencial no projeto de sistemas remotos e automatizados. O cronômetro usado para controlar o tempo é conhecido como Watchdog Timer. O nome é claro. O Mars Rover também usa essa funcionalidade para se recuperar de falhas e mau funcionamento do sistema.
Alguns recursos do Watchdog Timer no NRF24LE1 são:
• Intervalo mínimo de tempo limite do Watchdog: 7,8125ms
• Intervalo máximo de tempo limite do Watchdog: 512 s
• Usa clock de frequência de 32,768 KHz
• Temporizador de registro de 16 bits
Para controlar o Watchdog temos registro WDSV. Ele contém um valor de contador de 16 bits e é dividido em dois bytes – MSByte e LSByte. Para escrever o valor do contador neste registrador, primeiro temos que escrever LSByte e depois MSByte. O mesmo vale para a leitura do registro. Os dois bytes devem ser lidos ou gravados continuamente. Não podemos ler nenhum byte enquanto escrevemos e vice-versa. A leitura do registro WDSV sempre fornecerá o valor inicial do contador ou o valor inicial. Não podemos obter o valor atual do temporizador watchdog lendo WDSLV.
O temporizador watchdog é ativado quando dois bytes são gravados. Ele faz a contagem regressiva de WDSLV*256 até 0. Quando o valor do contador chega a 0, o microcontrolador se reinicia. Esta reinicialização é igual à reinicialização do hardware. Para evitar a reinicialização, podemos registrar o WDSV com um valor novo ou igual.
O contador será reiniciado se WDSV for gravado. Isso é feito quando nosso sistema está funcionando corretamente e não queremos reiniciar.
O watchdog é desabilitado quando o sistema é reiniciado ou quando usamos NRF nos modos de retenção de registro ou retenção de memória. Ele usa clock de baixa frequência de 32,768 KHz. Antes de usar o temporizador temos que ativar o relógio. Esta frequência pode ser fornecida externamente ou derivada de um oscilador de cristal de 16 MHz. A fonte de 32.768 KHZ pode ser controlada pelo registro CLKLFCTRL (Clock Low Frequency Control). O conteúdo deste registro é –:
• Bit 7 – Ler CLKLF(fase)
• Bit 6 – CLKLF pronto para ser usado
• Bit 5:4 – Reservado
• Bit 3 – Ler fonte de clock de 16 MHz. 1: Oscilador de Cristal, 0: Oscilador RC
• Bit 2:0 – Fonte para CLKLF.
000: Cristal 32K
001: RC 32K
001: Sintetizado a partir de Cristal de 16 MHz
011: Do pino IO usado como XC1 a XOSC32K (sinal de baixa amplitude)
100: Do pino IO (sinal digital rail-to-rail)
101: Reservado
110: Reservado
111: Nenhum selecionado
• Primeiro temos que habilitar o clock de 32.768 KHz. Para isso usamos o registro CLKLFCTRL. Para simplificar, usaremos relógio sintetizado. Podemos fazer isso escrevendo 001 em Bit2:1.
• Depois temos que verificar se o relógio começou ou não. Podemos fazer isso verificando o Bit 6.
• Depois disso podemos escrever LSByte e depois MSByte de WDSV.
#include"hal_delay.h" // arquivo de cabeçalho contendo funções de atraso
#include "hal_wdog.h" // biblioteca de funções watchdog
// função principal
vazio principal
{
CLKLFCTRL = 0x02; // iniciando o relógio 32.768
enquanto(!( CLKLFCTRL & 0x40)); //esperando o relógio começar
P0DIR = 0; // porta0 como saída
P0 = 0xff; //porta0 alta
atraso_ms(200); //espera 200ms
P0 = 0x00; //porta0 baixa
hal_wdog_init(0x0200); // Tempo limite de 4 segundos
enquanto(1); // Loop infinito
}