Teste Teste Teste Teste Teste

Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste Teste

Controlando um LED com um PIC - Parte II

sexta-feira, 11 de março de 20160 comentários

Nesta parte vamos ver o software do nosso projeto.

Uma vez que o software é bastante simples, vamos desenvolvê-lo em linguagem assembler e usar o ambiente de desenvolvimento MPLab, disponibilizado gratuitamente pela Microchip.

Definido o algorítmo é só pegar o manual de referência do PIC e enfrentar as esquisitices do conjunto de instruções. Alguns pontos a destacar:
  • a execução começa sempre no endereço 0, a interrupção desvia sempre para o endereço 4. No endereço 0 foi colocado um GOTO para desviar para o corpo do programa, que fica após o tratamenteo da interrupção.
  • é preciso tomar cuidado com o fato dos registradores de controle (SFR) estarem armazenados em dois bancos (BANK0 e BANK1). Antes de acessar um registrador de controle é preciso garantir que o banco correto está selecionado.
  • no início da rotina de interrupção é preciso salvar os registradores W e STATUS. Ao final da interrupção estes registradores precisam ser restaurados.
  • o PIC não possui instruções de desvio condicional convencionais. As instruções condicionais são sempre na forma de Skip If, na qual a instrução seguinte é pulada se uma determinada condição for verdadeira.
No inicio do programa deve-se definir a configuração do PIC, que será gravada em uma área especial da Flash:
; Configuração do PIC;
- habilita BrownOut Detect;
- desabilita pino MCLR;
- desabilita Watchdog;
- usa o oscilador interno
__CONFIG _BODEN_ON & _MCLRE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT

Uma variável (MODO_LED) é usada armazenar o modo atual de atuação do LED (APAGADO, ACESO ou PISCANDO). Quando for detectado o pressionamento do botão o modo será avançado para o modo seguinte (circularmente).
; Estados do LED
#define APAGADO 0
#define ACESO 1
#define PISCANDO 2

; Loop principal
PRINC
BTFSS MODO_BOTAO, BOTAO_APERT
GOTO PRINC ; aguarda apertar o botão
BCF MODO_BOTAO, BOTAO_APERT ; limpa indicação
MOVF MODO_LED,W
XORLW APAGADO
BTFSC STATUS,Z
GOTO ACENDER
MOVF MODO_LED,W
XORLW ACESO
BTFSC STATUS,Z
GOTO PISCAR

; Estava piscando, vamos apagar
MOVLW APAGADO
MOVWF MODO_LED
BCF LED
GOTO PRINC

; Estava apagado, vamos acender
ACENDER
MOVLW ACESO
MOVWF MODO_LED
BSF LED
GOTO PRINC

; Estava aceso, vamos piscar
PISCAR
MOVLW PISCANDO
MOVWF MODO_LED
GOTO PRINC

O tratamento do botão possui uma pequena dificuldade: quando o botão é apertado ou solto, por alguns instantes o contato abre e fecha rapidamente. Isto é chamado de 'bounce' (algo como 'quicar'). Para evitar que cada uma destas aberturas/fechamentos seja tratada como um aperta/solta do botão, é preciso aguardar que o sinal do botão fique estável por um certo tempo.

Para fazer o LED piscar e executar o 'debounce' do botão, vamos configurar o Timer 0 do PIC para gerar interrupções periodicamente. O valor que adotei foi aproximadamente 50 milisegundos, o que permite um piscar nítido e fazer o debounce simplesmente exigindo duas leituras iguais em interrupções consecutivas.
; Inicia o timer
BANK0
BCF INTCON,T0IF ; limpa a interrupção do timer
MOVLW .256-CNT_TIMER
MOVWF TMR0 ; programa o timer
BSF INTCON,T0IE
BSF INTCON,GIE ; permite interrupções

O piscar do LED fica bastante simples: na interrupção testamos se o modo atual é piscar; se sim invertemos o sinal no pino do LED.
MOVF  MODO_LED,W
XORLW PISCANDO
BTFSS STATUS,Z
GOTO TRATA_BOTAO
MOVLW 0x01
XORWF GPIO,F ; pisca o LED
TRATA_BOTAO

A lógica do botão é um pouco mais complicada. São usados três valores lógicos, armazenados em três bits de uma variável (MODO_BOTAO):
  • o estado do botão na interrupção anterior, que é atualizado ao final de toda interrupção
  • o estado do botão após o debounce, que é atualizado somente quando o estado atual do botão é igual ao estado anterior
  • uma indicação de que o botão foi apertado, que é ligado na interrupção quando o estado após o debounce passa de solto para apertado. Esta indicação é limpa no laço principal do programa, após tratar o acionamento da tecla.

; Controles do estado do botão
#define BOTAO_ANT 0x01 ; este bit indica o estado anterior
#define BOTAO_DEB 0x02 ; este bit tem o valor c/ "debounce"
#define BOTAO_APERT 0x04 ; este botão indica que foi detectado
; um pressionmento do botão

TRATA_BOTAO
BTFSC BOTAO ; testa o botão
GOTO SOLTO

; botao apertado
BTFSC MODO_BOTAO,BOTAO_ANT ; testa leitura anterior
GOTO APERT_10
BSF MODO_BOTAO,BOTAO_ANT ; mudou
GOTO FIM_INT
APERT_10 ; igual a vez anterior
BTFSC MODO_BOTAO,BOTAO_DEB
GOTO FIM_INT ; ja estava apertado
BSF MODO_BOTAO,BOTAO_APERT ; apertou agora
BSF MODO_BOTAO,BOTAO_DEB
GOTO FIM_INT

SOLTO ; botao solto
BTFSS MODO_BOTAO,BOTAO_ANT
GOTO SOLTO_10
BCF MODO_BOTAO,BOTAO_ANT ; mudou
GOTO FIM_INT
SOLTO_10 ; igual a vez anterior
BCF MODO_BOTAO,BOTAO_DEB

O fonte completo está aqui

Na próxima parte vamos encerrar esta série, vendo como montar o circuito e as referências para maiores detalhes.
Share this article :

Postar um comentário

 
Support : Creating Website | Johny Template | Mas Template
Copyright © 2011. mlknaweb - All Rights Reserved
Template Created by Creating Website Published by Mas Template
Proudly powered by Blogger