Linguagem Assembly do microcontrolador PIC16F628A

PIC16F628A

Neste post vamos ver o uso da Linguagem Assembly com o microcontrolador PIC16F628A, com três exemplos de código, um onde o microcontrolador vai ficar ligando e desligando um GPIO em alta frequência, um onde o LED piscará a cada 500 ms, e outro onde o microcontrolador vai ligar / desligar um LED quando uma tecla for pressionada. Esses três exemplos são um ponto de partida para o aprendizado da linguagem Assembly.

O microcontrolador PIC16F628A possui um conjunto de 35 instruções, o que facilita a programação deste microcontrolador usando a Linguagem Assembly.

Vamos conhecer o Hardware que será montado para testar os nossos códigos.

Hardware para testes com PIC16F628A

Os circuitos foram montados seguindo as recomendações do datasheet do componente, que podem ser consultados no link no final do post. Abaixo é fornecido o diagrama esquemático do circuito que foi montado.

Temos um regulador de tensão (LM7805) para regular a tensão de entrada de 12 Vcc para 5 Vcc, que será utilizado para alimentar o microcontrolador PIC16F628A. Também é possível observar que foi utilizado um circuito oscilador externo com um cristal de quartzo e dois capacitores de disco cerâmico de 15 pF. E o circuito de controle de reset, composto por dois resistores, um capacitor e um diodo.

O PIC16F628A temos ligado um resistor de 1 k em série com um LED, e um circuito para leitura de um push-button, onde está ligado um resistor de pull-down de 10 k e um capacitor de 100 nF.

Primeiro exemplo – Piscar um LED em Assembly

Não serão apresentados detalhes de como criar o projeto no MPLABX, uma vez que já existem outros post no BLOG que mostram como criar o projeto no MPLABX.

Abaixo é mostrado o código que será responsável por mudar o estado o LED que está conectado ao GPIO RA1 do microcontrolador PIC16F628A.

RES_VECT  CODE    0x0000            ; processor reset vector
#include <p16F628A.inc>
;Configuração dos Fuses bits do microcontrolador
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF

;Configurações iniciais no banco de memória 1
BSF STATUS, RP0 ;muda para banco de memória 1 para configurar os PORTS e TRIS

; Configura o PORTA como saída
MOVLW 0x00
MOVWF TRISA
; Configura o PORTB como saída
MOVLW 0X00
MOVWF TRISB

BCF STATUS, RP0 ; Volta para banco de memória 0

CLRF PORTA	;Limpa o PORTA
CLRF PORTB	;Limpa o PORTB

inicio:

BSF PORTA, 1 ; Faz o set do GPIO RA1
nop          ; Fica em um ciclo de máquina sem operação
BCF PORTA, 1 ; Faz o clear do GPIO RA1
nop          ; Fica em um ciclo de máquina sem operação

GOTO inicio ; Volta para o inicio

end ; Fim do código

Na Linguagem Assembly, o ponto e virgula é utilizado para criar os comentários dos códigos. As instruções podem ser consultadas no datasheet do componente. É importante manter um padrão na hora de escrever o código, como usar letras maiúsculas para as instruções.

Outro detalhe importante é quanto ao uso das labels, como no código foi utilizado o label inicio para criar um laço infinito, ou seja, após o microcontrolador executar todas as instruções, quando chegar na instrução GOTO inicio, ele retorna para BSF PORTA, 1.

No vídeo a seguir é possível ver o circuito em funcionamento.

Como a frequência do sinal é alta temos a impressão de que o LED não está mudando de estado de ligado para desligado. Para verificar que o circuito está funcionando foi utilizado um analisador lógico. Na figura abaixo é apresentado a forma de onda obtida no terminal de saída do PIC16F628A.

Captura do sinal do PIC16F628A com um analisador lógico

Vamos para o segundo exemplo.

Segundo exemplo – Piscar um LED em Assembly com delay de 500 ms

Neste segundo exemplo vamos fazer a mesma coisa, mas vamos acrescentar um delay de 500 ms, com isso vamos conseguir ver o LED piscar.

RES_VECT  CODE    0x0000            ; processor reset vector
#include <p16F628A.inc>
;Configuração dos Fuses bits do microcontrolador
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF

;Definições das variáveis para utilização
;no delay da saída
CBLOCK 0x20
    Delay1
    Delay2
    Delay3
ENDC

;Configurações iniciais no banco de memória 1
BSF STATUS, RP0 ;muda para banco de memória 1 para configurar os PORTS e TRIS

; Configura o PORTA como saída
MOVLW 0x00
MOVWF TRISA
; Configura o PORTB como saída
MOVLW 0X00
MOVWF TRISB

BCF STATUS, RP0 ; Volta para banco de memória 0

CLRF PORTA	;Limpa o PORTA
CLRF PORTB	;Limpa o PORTB

LigaLED:
BSF PORTA, 1
MOVLW .250
MOVWF Delay1
MOVLW .250
MOVWF Delay2
MOVLW .2
MOVWF Delay3

DelayLEDLigado:
nop
DECFSZ Delay1, 1
GOTO DelayLEDLigado
DECFSZ Delay2, 1
GOTO DelayLEDLigado
DECFSZ Delay3, 1
GOTO DelayLEDLigado
GOTO DesligaLED

DesligaLED:
BCF PORTA, 1
MOVLW .250
MOVWF Delay1
MOVLW .250
MOVWF Delay2
MOVLW .2
MOVWF Delay3

DelayLEDDesligado:
nop
DECFSZ Delay1, 1
GOTO DelayLEDDesligado
DECFSZ Delay2, 1
GOTO DelayLEDDesligado
DECFSZ Delay3, 1
GOTO DelayLEDDesligado
GOTO LigaLED

end ; Fim do código

No exemplo acima foram feitas várias chamadas a uma mesma função, e foram criadas três variáveis diferentes para obter um delay maior. Abaixo é mostrado o resultado do LED piscando a cada 500 ms aproximadamente.

Terceiro exemplo – Leitura de uma tecla em Assembly

No código abaixo é mostrado um exemplo que faz a leitura de uma tecla. Quando a tecla for pressionada o LED acende, caso contrário o LED permanece apagado.

RES_VECT  CODE    0x0000            ; processor reset vector
#include <p16F628A.inc>
;Configuração dos Fuses bits do microcontrolador
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF

;Configurações iniciais no banco de memória 1
BSF STATUS, RP0 ;muda para banco de memória 1 para configurar os PORTS e TRIS
  
; Configura o PORTA como saída, apenas RA0 como entrada
MOVLW 0x01
MOVWF TRISA
; Configura o PORTB como saída
MOVLW 0X00
MOVWF TRISB

BCF STATUS, RP0 ; Volta para banco de memória 0

MOVLW 0x07
MOVWF CMCON

CLRF PORTA	;Limpa o PORTA
CLRF PORTB	;Limpa o PORTB

desliga:
MOVLW B'00000000'
MOVWF PORTA
nop
BTFSS PORTA, 0 ; Se entrada RA0 == 1, liga LED, senão desliga LED
GOTO desliga
GOTO liga

liga:
MOVLW B'00000010'
MOVWF PORTA
nop
BTFSS PORTA, 0 ; Se entrada RA0 continuar pressionada, mantém o LED ligado
GOTO desliga
GOTO liga

end ; Fim do código

No vídeo abaixo é possível conferir o microcontrolador já gravado com código.

Conclusão

Foram mostrados alguns exemplos simples de como se programar o microcontrolador PIC16F628A usando a Linguagem Assembly, com a prática é possível criar códigos mais elaborados e que executam uma quantidade maior de instruções.

A vantagem em se utilizar a Linguagem Assembly está no fato de que o código vai executar de forma mais eficiente, e se tem um controle maior sobre quantidade de ciclos de máquina que são gastos durante a operação do microcontrolador, como foi possível verificar no primeiro exemplo. Entretanto, dependendo da complexidade do projeto pode ser inviável a utilização da Linguagem Assembly, sendo melhor se optar pela Linguagem C.

https://ww1.microchip.com/downloads/en/DeviceDoc/40044G.pdf

https://ww1.microchip.com/downloads/en/DeviceDoc/51795B.pdf