Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Este tutorial foi feito para as pessoas que têm a eletrônica como diversão e
desejam aprender a utilizar microcontroladores em seus projetos.
Também sou um entusiasta da eletrônica e gosto de entender como as coisas
funcionam. Por isso, escrevo os programas para os microcontroladores em linguagem Assembly.
Se você é como eu, creio que gostará deste tutorial.
Boa leitura!
Mulder_Fox
Membro do fórum de Eletrônica do Clube do Hardware
http://forum.clubedohardware.com.br/eletronica/f39
Parte 1
Pisca LED
Nesta primeira parte, vamos montar um circuito para fazer um LED piscar
numa frequência de aproximadamente 1 Hz.
Vamos utilizar o microcontrolador PIC16F628A, um dos modelos mais
usados hoje em dia.
Figura 1
Figura 2
Configuração
dos registradores
Inicialização das
variáveis
Passou 0,5
segundo? não
sim
Indica o início
.
Agora podemos começar a escrever o programa utilizando o software
MPLAB IDE da Microchip.
Faça o download do MPLAB IDE do site da Microchip e instale em seu
computador. A última versão disponível na data que foi escrito este tutorial é a 8.63.00.00.
A tela inicial do MPLAB IDE, pode ser vista na figura 3.
No menu “File”, clique em “New”.
Novamente, no menu “File”, clique em “Save As...” e escolha um nome para
o arquivo, com a extensão .asm. Por exemplo: Pisca LED.asm.
Figura 3
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /2011
;***********************************************************************************************
Tudo o que for digitado na linha após ponto e vírgula será ignorado pelo
MPLAB na hora da montagem do código, portanto, todas as anotações e comentários tem que vir
precedidos de ponto e vírgula.
Repare no ponto e vírgula no início de cada linha que faz com que o
MPLAB ignore o que está escrito após.
Em seguida vamos incluir no nosso programa o arquivo padrão de
definições do PIC16F628A, usando a diretiva #INCLUDE:
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /2011
;***********************************************************************************************
#INCLUDE <P16F628A.INC> ;ARQUIVO PADRAO MICROCHIP PARA O PIC16F628A
;***********************************************************************************************
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /2011
;***********************************************************************************************
#INCLUDE <P16F628A.INC> ;ARQUIVO PADRAO MICROCHIP PARA O PIC16F628A
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************;
VARIAVEIS
;**********************************************************************************************
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /2011
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************;
VARIAVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /2011
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************;
VARIAVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /2011
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************
;**********************************************************************************************
VARIAVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
; VETOR DE RESET
;***********************************************************************************************
; ROTINA DE INTERRUPÇÃO
;***********************************************************************************************
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /2011
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************;
VARIAVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
; VETOR DE RESET
;***********************************************************************************************
; ROTINA DE INTERRUPÇÃO
;***********************************************************************************************
;***********************************************************************************************
; CONFIGURACAO DOS REGISTRADORES DE USO ESPECÍFICO
INICIO
MOVLW B'00000111'
MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O
;***********************************************************************************************
Repare que aqui está a label INICIO, ou seja, aqui começa o programa.
Nesta parte do programa devemos configurar todos os Registradores de Uso
Específico que estejam envolvidos com os recursos do microcontrolador que iremos utilizar.
Por exemplo, se formos utilizar o TIMER 0, teremos que configurar o
registrador relacionado a ele. Se formos utilizar o módulo de PWM, devemos configurar o
registrador a ele relacionado e assim por diante, por isto, devemos ler o datasheet do
microcontrolador para sabermos quais registradores deveremos configurar.
No nosso circuito estamos utilizando o pino RA0 do PORTA e por isto,
devemos configurar o registrador TRISA responsável por definir cada pino do PORTA como
entrada ou saída.
Aqui também há uma relação direta entre o bit e o pino.
O bit 0 do TRISA configura o pino RA0, o bit 1 o pino RA1 e assim por
diante.
Se for atribuído o valor 0 para o bit, o pino é configurado como saída e se
for atribuído o valor 1, o pino é configurado como entrada. Memorize esta regra.
Veja a figura 4. Observe que o registrador TRISA está no banco 1.
Para termos acesso a este registrador precisamos selecionar o banco 1
escrevendo BANCO_1 (label que definimos para isto).
Os demais pinos não serão utilizados e não precisamos configurá-los, mas
aqui vai uma dica:
Configure como entrada os pinos que não estiverem sendo utilizados, pois,
se estiverem configurados como saída e se, por engano, um destes pinos for ligado diretamente ao
VSS ou ao VDD, poderá provocar a queima do microcontrolador. Estando configurados como
entrada, eles assumem alta impedância e não tem problema se forem ligados diretamente no VDD e
VSS.
O pino RA0 será configurado como saída e os demais pinos do PORTA
como entrada, então, precisamos escrever o número binário 11111110 no registrador TRISA (os bits
em um registrador estão na seguinte ordem: bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0).
Não existe uma instrução para escrever diretamente um número num
registrador do PIC16F628A.
No microcontrolador existe um registrador chamado de W (work).
Quando queremos escrever um número num registrador, primeiramente
devemos escrever este número no registrador W.
Fazemos isto com a instrução MOVLW, desta forma:
MOVLW B'11111110'
Com isto, escreve-se no registrador W o número binário 11111110.
O nome das instruções foram criados de forma a lembrar a sua função.
No caso da instrução MOVLW, MOV vem de mover. L vem de literal. A
instrução MOVLW, move um número para o registrador W. Reparou na correspondência? (move L
para W).
Com o número já escrito no registrador W, podemos escrever este número
no registrador TRISA, usando a instrução MOVWF, assim:
MOVWF TRISA
A instrução MOVWF move o que estiver no registrador W para o
registrador escrito após a instrução, no caso o TRISA.
Melhor dizendo, o conteúdo do registrador W é copiado para o TRISA, pois,
depois de executada a instrução, o registrador W continua com o mesmo valor que estava antes.
Pronto, configuramos o pino RA0 para funcionar como saída e os demais
pinos do PORTA para funcionarem como entrada.
Agora vamos configurar todos os pinos do PORTB como entrada, pelo
mesmo motivo que configuramos os outros pinos do PORTA.
O registrador TRISB é onde configuramos os pinos do PORTB como
entrada e saída:
MOVLW B'11111111'
MOVWF TRISB
MOVLW B'00000111'
MOVWF CMCON
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************;
VARIAVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
; VETOR DE RESET
;***********************************************************************************************
; ROTINA DE INTERRUPÇÃO
;***********************************************************************************************
; ROTINA DE INTERRUPÇÃO
INICIO
MOVLW B'00000111'
MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O
;***********************************************************************************************
; INICIALIZACAO DAS VARIAVEIS
Nosso programa aguarda que passe 0,5 segundo e testa o LED para ver se
está aceso ou apagado. Se estiver aceso, apaga e se estiver apagado, acende, voltando a aguardar 0,5
segundo para testar o LED novamente.
Há mais de uma forma de contar este tempo de 0,5 segundo. Neste
programa vamos fazer isto decrementando os valores de variáveis. No próximo programa iremos
fazer de outra forma mais eficiente.
Nossa rotina irá decrementar a variável DELAY_0 até que ela chegue ao
valor 0.
Quando DELAY_0 chega ao valor 0, ela é reiniciada e a variável DELAY_1
é decrementada.
Quando DELAY_1 chega a 0, ela é reiniciada e a variável DELAY_2 é
decrementada.
Quando DELAY_2 chegar a 0 terá passado aproximadamente 0,5 segundo.
MOVLW INI_DELAY_0
MOVWF DELAY_0
Se o seu valor não for igual a 0, o programa deverá voltar para decrementar
DELAY_0 e por isto, usamos a mesma instrução de antes:
GOTO PRINCIPAL
MOVLW INI_DELAY_1
MOVWF DELAY_1
DECFSZ DELAY_2,F
GOTO PRINCIPAL
MOVLW INI_DELAY_2
MOVWF DELAY_2
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /2011
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************;
VARIAVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
; SAÍDA
;***********************************************************************************************
; VETOR DE RESET
;***********************************************************************************************
; ROTINA DE INTERRUPÇÃO
;***********************************************************************************************
; CONFIGURACAO DOS REGISTRADORES DE USO ESPECÍFICO
INICIO
MOVLW B'00000111'
MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O
;***********************************************************************************************
; INICIALIZACAO DAS VARIAVEIS
;
************************************************************************************************
Agora que passou o tempo de 0,5 segundo, devemos testar o LED para ver
se ele está aceso ou apagado.
O LED estará aceso se o pino RA0 estiver em nível alto e apagado se estiver
em nível baixo.
Para testar o estado deste pino, devemos verificar qual o valor do bit 0 do
registrador PORTA.
Para verificar o valor de um bit, existem 2 instruções: BTFSS E BTFSC.
BTFSS testa o bit e pula a próxima linha se o valor for 1. (BTFSS = testa o
bit do registrador F e pula se estiver setado).
BTFSC testa o bit e pula a próxima linha se o valor for 0. (BTFSC = testa o
bit do registrador F e pula se estiver limpo (clean)).
A escolha entre uma ou outra depende das particularidades do trecho do
programa onde serão usadas.
Neste nosso programa não faz diferença e, portanto, vamos escolher
BTFSS:
BTFSS LED
Você se lembra de que nós definimos a label LED para o bit 0 do registrador
PORTA. Portanto, quando escrevemos esta instrução, é aquele bit que será testado.
Vamos supor que o valor do bit seja igual a 1 e, neste caso, a próxima linha
do programa será pulada.
Se o valor do bit 0 do PORTA é igual a 1, significa que o LED está aceso e,
então, devemos apagá-lo e para isso devemos fazer o valor do bit 0 do PORTA igual a 0.
Lembre-se de que para fazer o valor de um bit igual a 0, usamos a instrução
BCF.
BCF LED
Desta forma, quando o valor do bit for igual a 0, ele desviará para onde está
escrito ACENDE_LED, executando a instrução BSF LED.
Repare que depois de acender ou de apagar o LED ele desvia para o começo
da rotina principal, onde, começará novamente a decrementar as rotinas.
Com isto chegamos ao fim do nosso programa.
Devemos indicar o fim do programa ao MPLAB através da diretiva END.
Lembre-se de que nós ativamos o WDT nos bits de configuração.
O WDT é um circuito que reinicia o microcontrolador caso o programa
trave.
Ele é um contador que é incrementado continuamente e quando atinge o
valor máximo, provoca o reset do microcontrolador.
Em algum ponto do nosso programa deveremos escrever a instrução
CLRWDT, que reinicia o contador do WDT toda vez que é executada.
Caso o programa trave, esta instrução não será executada, provocando o
reset do microcontrolador.
É assim que o WDT funciona.
Vamos escrevê-la no começo da rotina principal:
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /
;***********************************************************************************************
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************;
VARIAVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
; SAÍDA
;***********************************************************************************************
; VETOR DE RESET
;***********************************************************************************************
; ROTINA DE INTERRUPÇÃO
;***********************************************************************************************
; CONFIGURACAO DOS REGISTRADORES DE USO ESPECÍFICO
INICIO
MOVLW B'00000111'
MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O
;***********************************************************************************************
; INICIALIZACAO DAS VARIAVEIS
;
************************************************************************************************
;**********************************************************************************************
Figura 6
Na próxima janela (“Step Two”), clique em “Avançar”:
Figura 7
Figura 8
Na janela que se abre, escolha um local e dê um nome para o projeto, por
exemplo Pisca LED e clique em “Salvar”.
Figura 9
Figura 10
Na janela seguinte (“Step Four”), selecione o arquivo .asm, clique em
“Add” e em seguida clique em “Avançar”:
Figura 11
Figura 12
No menu “Project”, clique em “Build All”. Na janela que se abre, selecione
“Absolute”:
Figura 13
Figura 14
A mensagem “BUILD SUCCEEDED”, confirma que não ocorreu nenhum
erro na compilação.
Com isto, nós já temos disponível o arquivo Pisca LED.hex para ser gravado
no microcontrolador, criado na mesma pasta onde está o arquivo Pisca LED.asm., mas, antes vamos
simular a execução do programa.
A mensagem “Message[302] E:\PISCA LED.ASM 56 : Register in operand
not in bank 0. Ensure that bank bits are correct” é um aviso de que o registrador objeto da
instrução presente naquela linha do programa (linha 56), não está no banco 0, afim de que nos
certifiquemos de ter setado corretamente o banco. É uma mensagem que aparece mesmo que o
banco tenha sido selecionado corretamente.
Abra o arquivo Pisca LED.asm, clicando no menu “File” em “Open”.
Clique no menu “Edit”, depois em “Properties” e depois na aba “ASM File
Types” e selecione “Line Numbers”.
Aparecerão os números das linhas à esquerda.
Vá na linha 56 e veja que o registrador em questão é o TRISA, que está no
banco 1. Repare que nós selecionamos este banco antes e, por isto, não precisamos nos preocupar.
O mesmo ocorre para a mensagem da linha 58.
Figura 15
Depois, clique onde está indicado na figura abaixo e selecione DELAY_0 e
clique em “Add Symbol”.
Faça o mesmo para DELAY_1 e DELAY_2.
Figura 16
Figura 17
Na imagem abaixo, a seta está apontando para a barra de botões do
simulador.
Aponte o mouse para cada botão para ver seus nomes. São eles: “Run”,
“Halt”, “Animate”, “Step Into”, “Step Over”, “Reset” e “Breakpoints”.
Figura 18
Figura 19
Esta seta indica qual instrução está para ser executada.
Clique no botão “Step Into”.
Este botão executa uma instrução a cada vez que é pressionado.
A instrução GOTO INICIO foi executada e, portanto, o programa foi
desviado para a linha após a label INICIO.
Clique novamente em “Step Into”.
Agora, a instrução representada pela label BANCO_1, ou seja, BSF
STATUS, RP0 foi executada e o banco 1 foi selecionado.
Repare na parte de baixo da janela, que o banco selecionado é o 1:
Figura 20
Figura 21
Você acaba de inserir um Breakpoint. O programa será interrompido toda
vez que encontrar um Breakpoint ativo.
Clique no botão “Reset” da barra de ferramentas do simulador e depois vá
clicando em “Step Into” até chegar na linha onde está a instrução CLRWDT.
No menu “Debugger”, clique em “StopWatch”.
Eis a janela do “StopWatch”:
Figura 22
Figura 26
Vamos experimentar diminuir o valor da variável DELAY_0 para 254.
Agora, o tempo é de praticamente 500 milissegundos.
Figura 27
Até hoje apenas utilizei este programa no Windows XP, e por isso, não
posso garantir que o mesmo funcione em versões posteriores do Windows.
Descompacte os arquivos do programa e do driver numa mesma pasta.
Na primeira vez que o IC-prog é executado ele apresenta a janela mostrada
na figura a seguir. Clique em OK.
Figura 29
Na próxima janela também clique em OK, deixando como está, pois, este
gravador é baseado no JDM.
Figura 30
Figura 31
Figura 33
Na janela que se abre, perguntando se deseja instalar o driver, clique em
“Yes”.
Figura 34
Figura 35
Figura 36
Pisca LED II
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************;
Para não ter de escrever tudo de novo, no MPLAB, abra o arquivo Pisca
LED.asm e, no menu “File”, clique em “Save As...” e mude o nome do arquivo para Pisca LED
II.asm e vá fazendo as alterações.
O próximo passo do programa é definirmos as variáveis.
Iremos utilizar apenas uma variável, que será usada para contar os estouros
do TMR0.
Vamos nomeá-la de CONT_EST_TMR0:
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************
; VARIÁVEIS
;**********************************************************************************************
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
#DEFINE BANCO_0 BCF STATUS,RP0 ;SETA BANCO 0 DE MEMORIA
#DEFINE BANCO_1 BSF STATUS,RP0 ;SETA BANCO 1 DE MEMORIA
;**********************************************************************************************
; VARIÁVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
; SAÍDA
;***********************************************************************************************
; VETOR DE RESET
;***********************************************************************************************
; ROTINA DE INTERRUPÇÃO
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************
; VARIÁVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
; SAÍDA
;***********************************************************************************************
; VETOR DE RESET
;***********************************************************************************************
; ROTINA DE INTERRUPÇÃO
INICIO
MOVLW B'00000111'
MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O
;***********************************************************************************************
; INICIALIZACAO DA VARIAVEL
;***********************************************************************************************
A seguir, iremos reiniciar o TMR0 com o valor 131, usando a constante que
criamos:
MOVLW INI_TMR0 ;W = INI_TMR0
MOVWF TMR0 ;REINICIA TMR0
Em seguida, decrementamos o valor da variável e ao mesmo tempo
verificamos se o seu valor chegou a 0:
Se o seu valor não for igual a 0, a próxima linha será executada e, neste
caso, desviaremos o programa para o começo da rotina principal:
;***********************************************************************************************
; PROGRAMA: PISCA LED
; VERSÃO 1.0
; DESENVOLVIDO POR: MULDER_FOX
; DATA DE CONCLUSÃO: / /
;***********************************************************************************************
;***********************************************************************************************
; BITS DE CONFIGURAÇÃO
;**********************************************************************************************
; PAGINACAO DE MEMORIA
;**********************************************************************************************
; VARIÁVEIS
;**********************************************************************************************
; CONSTANTES
;***********************************************************************************************
; SAÍDA
;***********************************************************************************************
; ROTINA DE INTERRUPÇÃO
;***********************************************************************************************
; CONFIGURACAO DOS REGISTRADORES DE USO ESPECÍFICO
INICIO
MOVLW B'00000111'
MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O
;***********************************************************************************************
; INICIALIZACAO DA VARIAVEL
;***********************************************************************************************
PRINCIPAL ;ROTINA PRINCIPAL DO PROGRAMA
;**********************************************************************************************
Salve o arquivo.
A seguir iremos simular a execução do programa com o MPLAB SIM.
No menu “Project”, clique em “Open”. Localize o projeto de nome Pisca
LED, selecione-o e clique em “Abrir”.
No menu “Project”, clique em “Add Files to Project...”, localize o arquivo
Pisca LED II.asm, selecione-o e clique em “Abrir”.
No menu “Project”, em “Remove Files to Project”, clique no arquivo Pisca
LED.asm (o da parte I) para removê-lo.
No menu “Project”, clique em “Buid All”.
Verifique se a montagem foi feita com sucesso, selecionando a janela
“Output” no menu “Window”:
Figura 1
Figura 3
O erro de 5 milissegundos é devido ao tempo gasto com as instruções que
reiniciam o TMR0 com o valor 131 toda vez que ele estoura.
Experimente mudar este valor para 132 (na constante), monte novamente o
projeto e volte a fazer a simulação e medir o tempo.
Você verá que o tempo agora é de 497 milissegundos:
Figura 4