HOME PROJETOS PROGRAMAÇÃO |
O Watchdog Timer, abreviadamente WDT, é um dispositivo de tempo que provoca um reset no MCU quando o tempo programado expira.
O WTD serve para reiniciar o programa de tempos em tempos, seja pelo fato dele poder travar durante a execução ou entrar em loop infinito ou qualquer outra razão que se tenha para manter o programa sempre ativo.
O WDT é ativado e desativado pelos bits de configuração e, em alguns MCU, isso pode ser feito no software.
Algumas das características do WDT são:
|
O WDT funciona como um contador que é incrementado a cada pulso de seu clock que é independente
do clock do MCU.
Quando esse contador estoura, o WTD faz com que o PC (Program Counter) seja carregado com o valor 0x0000
causando um desvio para a primeira instrução do programa (reset).
O período de tempo do WDT varia de MCU para MCU. Por exemplo, no PIC16F628A o WDT pode ser programado de 18ms a 4,6s e no PIC18F4520 pode ser programado de 4ms a 131s (2,1 minutos).
O período do WDT é programado através de um prescaler ou um postscaler, dependendo do MCU usado. Por exemplo, no PIC18F4520 , podemos programar o WDT da seguinte forma:
Primeiro habilitamos o WDT nos bits de configuração usando CONFIG WDT=ON. De acordo com o data sheet do PIC18F4520, para estabelecermos o período de tempo do WDT, devemos usar postscalers de 1:1, 1:2, 1:4 até 1:32768 (intervalos de potências de 2) que podem proporcionar períodos de tempos que vão de 4ms a 131s. Vamos assumir que desejamos programar um período de tempo de 5 segundos. Observando que, para o postscaler 1:1 o período é 4ms (0,004s), então, para obtermos 5 segundos devemos calcular o postscaler com a expressão PS=5/0,004 de onde obtemos PS=1250. Como o número 1250 não é uma potência de 2 exata, devemos aproximar o postscaler para a próxima potência de 2 escolhendo o número 1024 que multiplicado por 0,004 resulta 4,096 segundos. Isso não é o que desejavamos mas... é assim que funciona. O período também é especificado na configuração com CONFIG WDTPS=1024. |
Uma vez programado, o WDT vai estourar sempre que o período de tempo for atingido.
O programa pode limpar o WDT a fim de não deixá-lo estourar, assim permanecendo em execução normal até que aconteça um imprevisto que trave o programa. Para limpar o WDT usa-se a instrução assembler CLRWDT que vai zerar o WDT para que ele reinicie a contagem do tempo.
A instrução CLRWDT deve ser codificada num ponto estratégico do programa, onde se tem certeza que ela sempre será executada.
Assim, se o programa travar ou entrar num loop infinito, e a instrução CLRWDT não for executada, o WDT vai estourar
e provocar o reset esperado.
O WDT pode, também, operar durante o modo SLEEP a fim de acordar o MCU. Para saber como isso funciona, leia o tópico Acordando com o WatchDog Timer.
Para exemplificar o que foi dito, baixe o Programa Exemplo codificado para um MCU PIC18F4520 cujo código fonte está reproduzido na integra na listagem abaixo.
Note que o programa faz include de 2 arquivos interessantes que fornecem serviços para se trabalhar com
LCDs (#include"delay_services.inc")
e retardos de tempo (#include"delay_services.inc" ).
Se quiser, copie esses arquivos para sua pasta de subrotinas e veja a explicação sobre eles
na sessão Serviços.
O programa abaixo exibe uma mensagem intermitente no LCD, pedindo que o botão seja pressiodado.
Ao pressionar o botão, o programa entrará num loop infinito e será resetado pelo WDT em 5 segundo aproximadamente, voltando a apresentar a mensagem intermitente.
O programa usa um LCD de 2 linhas por 16 colunas, controlado por shift register, já visto em Interface de 2 fios para LCDs compatíveis com o HD44780.
O programa espera que o MCU use um Cristal Oscilador de 20MHZ.
O pino RA1 do MCU enviará dados serialmente para o LCD.
O pino RA2 do MCU enviará o sinal de clock ao LCD.
O pino RB1 do MCU deverá ter uma chave táctil conectada ao Ground e um resistor pull-up de 10K ao +5v.
list p=18F4520 #include <p18F4520.inc> errorlevel -302 ; -------------------------------------------------------------------------- ; CONFIGURATION BITS ou FUSES ; --------------------------------------------------------------------------- CONFIG WDT = ON ; Habilita o Watch Dog Timer CONFIG WDTPS = 1024 ; Postscaler para 5 segundos CONFIG MCLRE = ON CONFIG debug = OFF CONFIG LVP = OFF CONFIG OSC = HS CONFIG CP0 = OFF CONFIG CP1 = OFF CONFIG CP2 = OFF CONFIG CP3 = OFF CONFIG CPB = OFF CONFIG CPD = OFF CONFIG WRT0 = OFF CONFIG WRT1 = OFF CONFIG WRT2 = OFF CONFIG WRT3 = OFF CONFIG WRTC = OFF CONFIG WRTB = OFF CONFIG WRTD = OFF ;-------------------------------------------------------------------- ; #include "familias.inc" ; UDATA 0x80 delay_temp res 1 CLOCK equ 20000000 ; SR_1 RES 1 ; registrador auxiliar 1 SR_2 RES 1 ; registrador auxiliar 2 SR_3 RES 1 ; registrador auxiliar 3 SR_4 RES 1 ; registrador auxiliar 4 SR_5 RES 1 ; registrador auxiliar 5 LCD_COMMAND RES 1 ; buffer de comando e dados SR_TIPO RES 1 ; tipo de LCD SR_CLK equ 2 ; em TRISx este bit deve ser saida SR_DAT equ 1 ; em TRISx este bit deve ser saida SR_CHARS equ 0 ; 0 - caracteres 5x7 1 - caracteres 5x10 #define SR_TRIS TRISA ; I/O #define SR_DATA LATA,SR_DAT ; DATA #define SR_CLOCK LATA,SR_CLK ; CLOCK ; #include "gpr.inc" ; --------------------------------------------------------------- RESET_VECTOR CODE 0x0000 goto inicio ; INT_VEC1 CODE 0x0008 retfie ; --------------------------------------------------------------- MAIN CODE #include "delay_services.inc" #include "lcd_services.inc" LCD_LINES 0216 ; --------------------------------------------------------------- inicio movlw 0x0F ; mascara movwf ADCON1 ; todas as portas sao digitais clrf LATA ; PORTA = 0x00 clrf LATB ; PORTB = 0x00 clrf LATC ; PORTC = 0x00 clrf LATD ; PORTD = 0x00 clrf LATE ; PORTE = 0x00 ; movlw 0xFF ; mascara de I/O movwf TRISA ; PORTA - entrada movwf TRISB ; PORTB - entrada movwf TRISC ; PORTC - entrada movwf TRISD ; PORTD - entrada movwf TRISE ; PORTE - entrada ; movlw b'11111001' ; PORTA<2,1> saida do LCD movwf TRISA ; especifica I/O PORTA<2,1> call SR_4BITS ; configura o LCD call SR_LCDCLEAR ; limpa o LCD SET_CURSOR .1,.1,"i" ; posiciona o cursor do LCD LCD_WRITE "WATCH DOG ARMADO" ; mensagem na linha 1 ; read movf PORTB, w ; le o PORTB movwf R12 ; salva em R12 movlw .60 ; 60ms call delay_ms ; debounce do botao btfss R12, 1 ; botao pressionado??? goto get_loop ; SIM --> entra em loop SET_CURSOR .2,.1,"i" ; ANO--> posiciona o cursor do LCD LCD_WRITE " APERTE O BOTAO " ; mensagem na linha 2 movlw .250 ; 250ms call delay_ms ; tempo de visualizacao da mensagem clrwdt ; certifica que WDT nao vai estourar aqui SET_CURSOR .2,.1,"i" ; posiciona o cursor do LCD LCD_WRITE " " ; limpa a linha 2 do LCD movlw .250 ; 250ms call delay_ms ; tempo com a linha 2 limpa goto read ; espera alguem pressionar o botao get_loop SET_CURSOR .1,.1,"i" ; posiciona o cursor do LCD LCD_WRITE "PROGRAMA EM LOOP" ; avisa que o programa esta em loop SET_CURSOR .2,.1,"i" ; posiciona o cursor do LCD LCD_WRITE "Aguarde o reset " ; avisa que vai dar reset no PIC loop goto loop ; entra em loop infinito END
H P S P I N Desde 04 de Março de 2010 Atualização: 08 de Oct de 2024 |