Fork me on GitHub

Microcontrolandos

O Blog está passando por uma fase de mudanças. Todos os posts estão sendo atualizados, códigos, links e imagens estão sendo arrumados. Conteúdos novos ainda estão por vir.

WatchDog Timer

Share:

WatchDog Timer

O Watchdog Timer( cão de guarda) é um  oscilador RC, que não necessita de quaisquer componentes externos. Isso significa que o WDT irá executar, mesmo se o clock do dispositivo tiver sido parado, por exemplo, pela execução de uma instrução SLEEP. Durante a operação normal, o WDT gera um reset do dispositivo (Watchdog Timer Reset). Se o dispositivo está no modo SLEEP, faz com que o dispositivo acorde e continua com a operação normal (Watchdog Timer Wake-Up).


O WDT tem um função muito importante não apenas contra bugs de software, mas também em situações ambientais agressivas. O WDT oferece a possibilidade de restabelecer o controle da aplicação pelo microcontrolador através da reinicialização do sistema (um simples RESET) mesmo que a falha esteja na próprio oscilador do microcontrolador. Esse insucesso do microcontrolador de manter o fluxo do programa adequadamente pode ter várias causas como condições ambientais ( temperaturas extremas ), instabilidade da alimentação, falha do oscilador ou bugs no código (loop infinito, por exemplo).

O tempo do WDT é de 18ms e pode ser incrementado para até alguns segundos através do prescaler. Este divisor de frequência é um recurso compartilhado entre o WDT e o TIMER0. Para evitar que o sistema reinicie, deve-se adicionar a instrução clrwdt a algum loop do programa para que ela seja executada periodicamente e em um período menor do que o tempo de estouro do de WDT.

A detecção do time-out é feita pela verificação do bit TO do registro STATUS (pic16f) ou RCON (pic18f). Então quando houver um estouro no timer do WDT, TO será igual a 0.

Você  deve ativar o WDT, configurando os fusíveis.

EXEMPLO:
char k = 1;
void main()
{
OPTION_REG = 0x0E; //configura o WDT(ativa o prescaler setando o bit 3, e define para 1:64(bits 2-0)
TRISB = 0;
asm CLRWDT; //limpa o tempo do watchdog timer

while(1)
{
 asm CLRWDT; //limpa o tempo do watchdog timer
 
 while(k++)
 {
 PORTB = k--;//ops!!, bug no codigo, entao depois de um certo tempo(18ms x 64 = 1,1s), irá ocorrer o reset
 Delay_ms(200);
 }
 PORTB = 0;
 ...
 
}
}

6 comentários:

  1. Ola caro amigo, meus parabéns pelo site muito bom

    vc saberia me informa se no pic 18f4550 eu perco o uso do Timer 0 para poder ativar o Watchdog ou tem maneira de usar os dois juntos, pelo que foi possível ver no datasheet la não menciona o timer0 nesse modelo nos 16f sim. estou usando ja o timer 0 1 2 e queira usar Watchdog tb.
    Pode me auxiliar

    ResponderExcluir
    Respostas
    1. Olá, muito obrigado!

      A unica coisa que voce perde é o prescaler do timer0, que no caso será destinado ao watchdog timer. A fonte de clock do watchdog timer vem do INTRC ( clock interno RC ), veja na pag. 303 do datasheet.

      Abraços,
      Tiago.

      Excluir
    2. Gostaria de agradecer a ajuda deu tudo certo.

      aproveitando não achei nada sobre bloquear a leitura do hex que esta no microcontrolador para ninguém roubar o programa que foi feito, vc teria algum tópico com isso ou alguma referencia.
      muito obrigado mais uma vez

      Excluir
  2. Muito boa suas explicações, parabéns. Como posso introduzir este watchdog timer, em um programa ASENBER, estou aprendendo a linguagem basica e não tenho o conhecimento de como introduzir este cão de guarda em minha programação sem que ele reinicie o programa, as vezes o programa entra em um loop infinito e se perde, so consigo retornar acionando o reset manual. Assim li sua explicação e percebi que este timer pode resolver o problema.
    Mas como usar em ASENBER?

    exmplo:
    MAIN
    TESTE_PLACA
    CALL BT1_1
    CALL BT2_1
    CALL BT3_1
    GOTO main


    BT1_1
    BTFSS BT1
    RETURN
    BSF LED_VERDE
    BSF LED_VERMELHO
    GOTO BT1_1

    BT2_1
    BTFSS BT2
    RETURN
    BSF LED_VERDE
    BSF LED_VERMELHO
    GOTO BT2_1

    BT3_1
    BTFSS BT2
    RETURN
    BCF LED_VERDE
    BCF LED_VERMELHO
    GOTO BT3_1

    GOTO MAIN

    END ; FIM

    Se for possível ajudar eu agradeço.

    ResponderExcluir
    Respostas
    1. Faça a programação em C usando alguma ferramenta como MPLAB X, compile, gere o assembly e copie para seu programa. ;-)

      Excluir
  3. Aos desavisados, o WDT só irá funcionar se habilitar o fuse dele. No XC8 eu faço assim:


    /* Enable WDT. */
    #pragma config WDTE = ON

    ...
    /* Configure WDT. */
    OPTION_REGbits.PSA = 1;
    OPTION_REGbits.PS = 0x07;


    E voilà, tudo funciona lindamente!

    ResponderExcluir