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.
; 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.
4 comentários:
Boa noite.
Você tem o código desse projeto em linguagem C para PIC??
Atenciosamente,
Jutai C.S
jutaics@hotmail.com
ola Daniel,
Parabens pela iniciativa...e gostaria de pedir um exemplo de como fazer um led piscar 4 vezes e para apagado em um interfalo de 3 segundo..... detse ja agradeço pela atençao!! Raul Leles
Olá amigo
Você pode voltar a disponibilizar o código fonte completo
Obrigado
Tiago,
Está lá nos arquivos do blog no skydrive (icone e link no canto superior direito da página). Algum dia eu saio acertando os links post a post...
Daniel
Postar um comentário