HOME      PROJETOS      PROGRAMAÇÃO     
  1. INTRODUÇÃO
  2. RECURSOS
  3. ARQUITETURA
  4. ENDEREÇAMENTO
  5. INTERRUPÇÕES
  6. NÍVEIS DE INTERRUPÇÕES NA FAMÍLIA 18F
  7. RESETS DO MICROCONTROLADOR
  8. MODO SLEEP
  9. WATCHDOG TIMER
  10. O STACK
  11. A LINGUAGEM ASSEMBLER
  12. MPLAB - Criando Projetos
  13. LIBRARIES - Usando Bibliotecas de Funções


WATCHDOG TIMER


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:

       
  • Possui um oscilador independente do oscilador do MCU.
  • Período de Time-Out configurável de milisegundos a segundos.
  • Pode ficar ativo durante o modo Sleep.



Funcionamento do WDT

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.




Evitando o Estouro do WDT

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.




Programa Exemplo

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.




Requisitos para o programa

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





  1. INTRODUÇÃO
  2. RECURSOS
  3. ARQUITETURA
  4. ENDEREÇAMENTO
  5. INTERRUPÇÕES
  6. NÍVEIS DE INTERRUPÇÕES NA FAMÍLIA 18F
  7. RESETS DO MICROCONTROLADOR
  8. MODO SLEEP
  9. WATCHDOG TIMER
  10. O STACK
  11. A LINGUAGEM ASSEMBLER
  12. MPLAB - Criando Projetos
  13. LIBRARIES - Usando Bibliotecas de Funções

H P S P I N

Desde 04 de Março de 2010

Atualização: 08 de Oct de 2024