Buscar

Tutorial de Programação Assembly para Microcontroladores PIC Partes 1 a 8

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 204 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 204 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 204 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
1 
Introdução 
 
 
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 um Hz. 
Vamos utilizar o microcontrolador PIC16F628A, um dos modelos mais 
usados hoje em dia. 
 
Figura 1 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
2 
Os microcontroladores precisam de um sinal de clock para funcionar, mas 
muitos modelos possuem a alternativa de usar um circuito oscilador interno para gerar esse sinal. 
Este é o caso do PIC16F628A, onde podemos escolher a frequência de 48 KHz ou a de 4 MHz. 
A configuração do oscilador interno como fonte do sinal de clock e a sua 
frequência são feitos no programa que é gravado no PIC. 
Antes de escrevermos o programa para o microcontrolador, vamos desenhar 
o esquema do circuito. 
Segundo consta no datasheet do PIC16F628A, a sua tensão de alimentação 
pode ser de 3 v até 5,5V, sendo que com 3 v, a frequência máxima do sinal de clock é de 10 MHz 
enquanto que a partir de 4,5V é de 20Mhz. 
Vamos utilizar um regulador de tensão LM7805 para fornecer uma tensão de 
5 v a partir de 9 v. 
Além do LM7805 e do PIC16F628A iremos utilizar um LED e um resistor 
para limitar sua corrente, que serão ligados diretamente no pino do PIC, já que ele tem a capacidade 
de fornecer a corrente necessária para o LED. 
Mas, em qual pino do PIC iremos ligar o LED? 
O PIC16F628A possui 15 pinos que podem ser usados como entrada ou 
saída: RA0, RA1, RA2, RA3, RA4, RA6, RA7, RB0, RB1, RB2, RB3, RB4, RB5, RB6 e RB7 e 1 
pino que só pode ser usado como entrada: RA5. 
O pino RA4 é o único que, quando configurado como saída, é do tipo open 
drain, ou seja, a carga conectada a este pino deve estar ligada ao positivo da alimentação. 
É possível fazer com que resistores de pull-up integrados no PIC sejam 
conectados nos pinos RB0, RB1, RB2, RB3, RB4, RB5, RB6 e RB7, individualmente, para o caso 
de um ou mais destes pinos estarem sendo usados como entrada, economizando, desta forma, o uso 
de resistores externos. Veremos como fazer isto em outra parte deste tutorial. 
Antes de definirmos qual pino iremos utilizar, precisamos saber se as 
características do pino atendem às nossas necessidades. 
No nosso circuito precisaremos de um pino que possa ser usado como saída 
e, portando, temos 15 à nossa disposição. Podemos escolher qualquer um deles, por exemplo, o 
RA0. 
Portanto, o esquema do circuito ficou assim: 
 
 
Figura 2 
 
 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
3 
Definido o esquema do circuito, vamos elaborar o fluxograma do programa 
que iremos gravar no PIC. 
O fluxograma é uma representação gráfica de como o programa se comporta 
conforme as possíveis situações. 
Com o fluxograma, fica mais fácil escrever o programa. 
Eis o fluxograma do nosso programa: 
 
 Início 
 
 
 
 
 Configuração 
 dos registradores 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Indica o início 
 
 
 Indica uma subrotina 
 
 
 
 
 
 Inicialização das 
 variáveis 
 
 Passou 0,5 
segundo? não 
sim 
 Acende LED LED está aceso? Apaga LED 
sim não 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
4 
 
 
 Indica uma decisão 
 
 
 
 Indica acesso a um dispositivo de I/O 
 
 
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 
 
 
Primeiramente vamos criar um cabeçalho onde irá constar o nome do 
programa, sua versão, o nome do autor e a data de conclusão, ficando assim: 
 
 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
5 
 
;*********************************************************************************************** 
; 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 têm de virem 
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: 
 
;*********************************************************************************************** 
 #INCLUDE <P16F628A.INC> ;ARQUIVO PADRAO MICROCHIP PARA O PIC16F628A 
;*********************************************************************************************** 
Repare que antes de #INCLUDE <P16F628A.INC> não há ponto e vírgula 
e portanto o MPLAB irá executar esse comando. 
Observe que foi deixado um espaço a partir da margem esquerda. Isso 
porque se o MPLAB encontra uma diretiva na margem esquerda, ele envia uma mensagem de alerta 
na hora de criar o arquivo a ser gravado no microcontrolador. 
Observe que na mesma linha, antes do comentário “ARQUIVO PADRAO 
MICROCHIP PARA O PIC16F628A” há ponto e vírgula, pois, não queremos que o MPLAB leve 
em consideração o que está escrito, pois se trata de um comentário (não faz parte do programa). 
Repare que após digitar #INCLUDE a cor da letra ficou azul, O MPLAB faz 
isso sempre que reconhece o termo como uma diretiva. Isso ajuda a perceber quando escrevemos a 
diretiva de forma errada, pois, aí ela não ficará azul. 
No arquivo P16F628A.INC é onde constam, além do modelo do 
microcontrolador, as correspondências entre os nomes dos registradores e as respectivas posições 
que eles ocupam na memória de dados, bem como, entre os nomes de cada bit e sua posição no 
registrador, entre outras informações, como tamanho e endereços válidos da memória e bits de 
configuração. 
O que ocorre é que, para facilitar a vida do programador, as localidades damemória de dados, ou seja, os registradores, recebem nomes. 
Quando o MPLAB vai traduzir o programa para a linguagem de máquina ele 
usa essas correspondências. 
Se você quiser ver o arquivo P16F628A.INC, localize-o na pasta MPASM 
Suite que é uma subpasta da pasta Microchip, criada no diretório onde foi instalado o MPLAB IDE. 
O próximo passo é ajustar os Bits de Configuração, também conhecidos por 
“fusíveis” ou “fuses”. Isso é feito com a diretiva __CONFIG. 
;*********************************************************************************************** 
; BITS DE CONFIGURAÇÃO 
 
 __CONFIG _INTOSC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BOREN_OFF 
& _LVP_OFF & _CP_OFF & DATA_CP_OFF 
 
;********************************************************************************************** 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
6 
 
São 2 “underlines” antes do CONFIG, seguido de espaço e, após, as 
expressões antecedidas de 1 “underline” separadas pelo símbolo “&” entre espaços. 
Nos Bits de Configuração selecionamos o tipo de oscilador que será usado e 
se os seguintes recursos serão ativados: WDT (Watch Dog Timer), PWRTE (Power-up Timer), 
MCLRE (Master Clear Enable), BOREN (Brown-out Reset), LVP (Low Voltage Program), 
DATA_CP (proteção da memória de dados), CP (proteção da memória de programa). 
As opções para seleção do oscilador são: 
 
_LP_OSC : Cristal de frequência até cerca de 1MHz ligado entre os pinos 
OSI e OSO. 
 _XT_OSC : Cristal de frequência de cerca de 1MHz a 4 MHz ligado entre 
os pinos OSI e OSO. 
_HS_OSC : Cristal de frequência superior a 4 MHz ligado entre os pinos 
OSI e OSO. 
_EXTCLK_OSC : Sinal de clock externo aplicado no pino CLKIN. 
 
_INTOSC_OSC_NOCLKOUT : Oscilador interno. 
 
_INTOSC_OSC_CLKOUT : O mesmo que o anterior, porém com saída do 
sinal de clock no pino CLKOUT (¼ da frequência) para fins de sincronização de hardware externo. 
 
_RC_OSC_NOCLKOUT : Oscilador a base de resistor e capacitor ligados 
no pino CLKIN. 
_RC_OSC_CLKOUT : O mesmo que o anterior, porém com saída do sinal 
de clock no pino CLKOUT (¼ da frequência) para fins de sincronização de hardware externo. 
 
No nosso caso, escolhemos a opção _INTOSC_OSC_NOCLKOUT, ou seja, 
oscilador interno sem saída do sinal. 
O WDT (Watch Dog Timer) é um recurso que reinicia o microcontrolador, 
caso o programa travar. 
Vamos habilitar esse recuso escrevendo _WDT_ON. 
Se não quiséssemos ativar o recurso escreveríamos _WDT_OFF. 
O PWRTE (Power-up Timer) é um circuito que mantém o microcontrolador 
em reset por 72 ms após a alimentação ser ligada para que dê tempo do oscilador estabilizar. 
Vamos habilitar também este recurso escrevendo _PWRTE_ON. 
O MCLRE (Master Clear Enable), se estiver ativado, reserva o pino MCLR 
para a função de reset do microcontrolador. 
Este recurso não nos interessa e, por isso, o deixamos desligado, escrevendo 
_MCLRE_OFF. 
O BOREN (Brown-out reset) é um recurso que monitora a tensão de 
alimentação e quando ela cai abaixo de 4,5V provoca o reset. 
Este recurso também não nos interessa e, por isso, escrevemos 
_BOREN_OFF. 
O LVP (Low Voltage Program) é um recurso que permite que o 
microcontrolador seja gravado sem a necessidade de aplicar uma tensão de cerca de 13V no pino 
VPP (veremos sobre gravação do PIC no momento oportuno). 
Esta função não nos interessa e, por isso, escrevemos _LVP_OFF. 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
7 
DATA_CP é um recurso para proteger a memória de dados contra cópia. 
CP é um recurso para proteger a memória de programa contra cópias. 
Estes recursos interessam a quem fabrica aparelhos eletrônicos e quer evitar 
engenharia reversa. 
Estes recursos não nos interessam, e, por isso, escrevemos _CP_OFF & 
DATA_CP_OFF. 
O próximo passo é definir as “labels” para a comutação dos bancos de 
memória de dados. 
Fazemos isto utilizando a diretiva #DEFINE desta forma: 
 
;********************************************************************************************** 
; 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 
 
;********************************************************************************************** 
A memória de dados está dividida em quatro bancos (figura 4). 
Para ter acesso a qualquer registrador a fim de ler ou alterar o seu valor, 
precisamos ajustar os valores dos bits RP0 e RP1 do registrador STATUS, para selecionar o banco 
onde se encontra o registrador. 
Banco 0: RP0 = 0, RP1 = 0 
Banco 1: RP0 = 1, RP1 = 0 
Banco 2: RP0 = 0, RP1 = 1 
Banco 3: RP0 = 1, RP1 = 1 
Neste programa que estamos fazendo, não necessitaremos de acessar os 
bancos 3 e 4, pois, os Registradores de Uso Específico que neles se encontram também estão nos 
bancos 0 ou 1 e não iremos precisar das posições destinadas a Registradores de Uso Geral que lá se 
encontram, pois, nos bastarão os disponíveis no banco 0. 
Como o bit RP1 inicializa com o valor 0, basta que alteremos o bit RP0, 
para alternar entre os bancos 0 e 1. 
Usamos a diretiva #DEFINE para que onde houver a palavra BANCO_0 o 
microcontrolador execute a instrução BCF STATUS,RP0. 
BANCO_0 é o que chamamos de “label” e poderia ser outra palavra de sua 
preferência. 
A instrução BCF serve para fazer o valor de um determinado bit igual a 0. 
Em BCF STATUS,RP0 STATUS é o nome do registrador e RP0 o 
nome do bit deste registrador cujo valor ficará igual a 0. 
Nós também usamos a diretiva #DEFINE para que onde houver a palavra 
BANCO_1 o microcontrolador execute a instrução BSF STATUS,RP0. 
A instrução BSF serve para fazer o valor de um determinado bit igual a 1. 
Desta forma, fica mais fácil fazer a comutação entre os bancos de memória, 
pois basta escrever a palavra BANCO_0 para que o banco 0 da memória de dados seja selecionado 
e a palavra BANCO_1 para o banco 1. 
Repare que após digitar BCF e BSF, a cor da letra ficou azul e em negrito. O 
MPLAB faz isto com qualquer termo reconhecido como uma instrução. Isto nos ajuda a perceber se 
escrevermos uma instrução de forma errada. 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
8 
 
 
Figura 4 
 
O próximo passo é definir as variáveis que iremos utilizar em nosso 
programa. 
Uma variável é um Registrador de Uso Geral, ou seja, é uma das posições da 
memória de dados que podemos usar para armazenar os valores dos dados que vamos manipular no 
nosso programa. 
À medida que vamos escrevendo o programa, vamos precisando criar 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
9 
variáveis. Por esse motivo, minha forma preferida para defini-las é com o uso da diretiva CBLOCK: 
;********************************************************************************************** 
; VARIAVEIS 
 
 CBLOCK 0X20 ;ENDERECO INICIAL DA MEMORIA DO USUARIO 
 
 DELAY_0 ;USADO PARA GERAR O TEMPO DE 0,5 SEGUNDO 
 DELAY_1 ;USADO PARA GERAR O TEMPO DE 0,5 SEGUNDO 
 DELAY_2 ;USADO PARA GERAR O TEMPO DE 0,5 SEGUNDO 
 ENDC ;FIM DO BLOCO DE MEMORIA 
 
;********************************************************************************************** 
 
A expressão 0X20 após a diretiva CBLOCK indica o endereço na memória 
de dados que assumirá a primeira variável definida (DELAY_0). 
Esse endereço está em formato hexadecimal. Veja na figura 4 queele (lá 
representado por 20h) é o primeiro, no banco 0, que podemos usar como Registrador de Uso Geral. 
Repare que o último é o 7Fh, totalizando 96 localidades de memória nesse 
banco. 
Os do endereço 70 até 7F são espelhados nos outros bancos, permitindo que 
possam ser acessados sem necessidade de selecionar o banco. 
No banco 1 temos outras 80 posições e no banco 2 mais 48. 
Portanto, no PIC16F628A temos um total de 224 posições de memória 
(registradores) que podemos usar para armazenar valores. Ou seja, podemos criar até 224 variáveis. 
Voltando a falar da diretiva CBLOCK, após relacionar os nomes das nossas 
variáveis, encerramos a diretiva com ENDC. 
Desta forma, definimos o endereço 0X20 para DELAY_0, 0X21 para 
DELAY_1 e 0X22 para DELAY_2. 
Se posteriormente quisermos adicionar outras variáveis, podemos intercalá-
las sem problemas. 
Há outras formas de definir variáveis, através das diretivas #DEFINE e 
EQU, mas creio que a mais prática seja através da diretiva CBLOCK. 
 
O próximo passo é definir as constantes. 
Constantes são valores numéricos que utilizamos durante o programa. 
Por exemplo, uma determinada variável pode precisar ser reiniciada sempre 
com o mesmo valor. Este valor é uma constante. 
No nosso programa, as variáveis DELAY_0, DELAY_1 c DELAY_2 serão 
reiniciadas, cada qual, com valores que serão sempre os mesmos. 
Esses valores serão ajustados depois que fizermos a rotina principal do 
programa, por isso, os valores que iremos escrever agora serão provisórios. 
Para definir as constantes, usamos a diretiva EQU: 
 
;********************************************************************************************** 
; CONSTANTES 
 
INI_DELAY_0 EQU .255 ;VALOR QUE DELAY_0 INICIA 
INI_DELAY_1 EQU .50 ;VALOR QUE DELAY_1 INICIA 
INI_DELAY_2 EQU .13 ;VALOR QUE DELAY_2 INICIA 
;*********************************************************************************************** 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
10 
 
No momento em que o MPLAB for montar o programa, onde estiver escrito 
INI_DELAY_0, ele irá substituir essa expressão pelo valor 255 (decimal); INI_DELAY_1 por 50 e 
INI_DELAY_2 por 13. 
 
A vantagem de fazer isso é que se constatarmos que os valores para aquelas 
variáveis não estavam satisfatórios, basta alterá-los ali, em vez de modificá-los em todas as linhas 
do programa onde forem feitas reinicializações das variáveis. 
A propósito, vamos falar de como representar, no programa, os valores numéricos 
usando o número 10 como exemplo. 
Quando estivermos nos referindo ao número 10 do sistema decimal, escreveremos 
assim: D'10' ou ainda .10 
Se for o numero 10 do sistema binário (2 do sistema decimal), escreveremos assim: 
B'10' 
Se for o número 10 do sistema hexadecimal (16 do sistema decimal), 
escreveremos assim: H'10' ou assim: 0X10 
A seguir vamos atribuir a “label” LED para o bit 0 do registrador PORTA. 
 
;*********************************************************************************************** 
; SAÍDA 
 
 #DEFINE LED PORTA,0 ;LED LIGADO EM RA0 
 
;*********************************************************************************************** 
 
A diretiva #DEFINE atribuiu a “label” LED para o bit 0 do registrador 
PORTA. 
Toda vez que aparecer no programa a palavra LED, o MPLAB saberá que se 
trata do bit 0 do registrador PORTA. 
Os registradores associados aos pinos de I/O são o PORTA e o PORTB. 
O próprio nome do pino já nos diz qual é o registrador e o bit. 
Pino RA0 – bit 0 do PORTA 
Pino RA1 – bit 1 do PORTA 
Pino RA2 – bit 2 do PORTA 
Pino RA3 – bit 3 do PORTA 
Pino RA4 – bit 4 do PORTA 
Pino RA5 – bit 5 do PORTA 
Pino RA6 – bit 6 do PORTA 
Pino RA7 – bit 7 do PORTA 
Pino RB0 – bit 0 do PORTB 
Pino RB1 – bit 1 do PORTB 
Pino RB2 – bit 2 do PORTB 
Pino RB3 – bit 3 do PORTB 
Pino RB4 – bit 4 do PORTB 
Pino RB5 – bit 5 do PORTB 
Pino RB6 – bit 6 do PORTB 
Pino RB7 – bit 7 do PORTB 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
11 
 
Quando um pino estiver configurado como entrada (veremos depois como 
se faz a configuração dos pinos como entradas ou saídas), o nível lógico presente nele poderá ser 
verificado fazendo-se a leitura do valor do bit correspondente. Se o valor do bit é igual a 1, então o 
nível lógico no pino é alto e vice-versa. 
Por exemplo, suponhamos que o pino RB2 esteja configurado como entrada. 
Para sabermos qual é o seu nível lógico, fazemos a leitura do bit 2 do 
registrador PORTB (veremos no momento oportuno como verificar o nível lógico de um bit). 
Para o pino RA6, lemos o bit 6 do PORTA e assim por diante. 
Se um pino estiver configurado como saída, e quisermos levar o seu nível 
para alto, tornamos o valor do seu bit correspondente igual a 1. Para levar o pino para nível baixo, 
tornamos o valor do bit correspondente igual a 0, ou seja, controlando o valor do bit controlamos o 
nível no pino. 
O próximo passo é o vetor de reset. 
 
;*********************************************************************************************** 
; VETOR DE RESET 
 
 ORG 0X00 ;ENDERECO INICIAL DE PROCESSAMENTO 
 GOTO INICIO ;DESVIA PARA INICIO 
 
;*********************************************************************************************** 
Após a inicialização e depois de um reset, o microcontrolador executa a 
instrução que estiver no endereço 0X00 da memória de programa. 
Em seguida ele irá executar a instrução presente no endereço 0X01, depois 
0X02 e assim por diante. 
A diretiva ORG indica em qual endereço da memória de programa deverá 
ser escrita a instrução seguinte. No nosso programa, a instrução GOTO INICIO ocupará o endereço 
0X00 da memória de programa, ou seja, será a primeira instrução a ser executada pelo 
microcontrolador. 
 O microcontrolador ao executar esta instrução desvia para o endereço da 
memória de programa ocupado pela instrução que estiver após a label INICIO. 
Mas, porque fazer esse desvio? 
Os microcontroladores possuem um recurso muito útil chamado Interrupção, 
que é a interrupção da execução do programa devido a um evento provocado por um periférico do 
microcontrolador configurado para isso. Periféricos são os circuitos presentes no microcontrolador 
que fazem funções específicas como contadores, geradores de sinal PWM, comparadores, etc... 
Quando uma interrupção ocorre, o microcontrolador executa a instrução 
presente no endereço 0X04 da memória de programa (no caso do PIC16F628A). 
Este é o motivo de fazermos um desvio logo no endereço 0X00. Este desvio 
será para depois do fim da rotina de interrupção, pois, o programa não caberia entre o endereço 
0X00 e 0X03 e ele não pode ocupar os endereços a partir do 0X04, pois, ali estará a rotina de 
interrupção. 
Como neste programa não iremos utilizar o recurso da interrupção, iremos 
escrever no nosso programa a instrução RETFIE no endereço 0X04 para que se, por acaso, ocorrer 
uma interrupção indesejada, o programa possa retornar para o ponto de onde foi desviado: 
;********************************************************************************************** 
; ROTINA DE INTERRUPÇÃO 
 ORG 0X04 ;VETOR DAS INTERRUPÇÕES 
 RETFIE ;RETORNA 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
12 
;*********************************************************************************************** 
Em outra parte deste tutorial falaremos detalhadamente sobre interrupções. 
O próximopasso é configurar os Registradores de Uso Específico. 
 
;*********************************************************************************************** 
; CONFIGURACAO DOS REGISTRADORES DE USO ESPECÍFICO 
 
INICIO 
 
 BANCO_1 ;SELECIONA BANCO 1 DE MEMORIA 
 
 MOVLW B'11111110' ;W = B'11111110' 
 MOVWF TRISA ;CONFIGURA RA0 COMO SAÍDA E DEMAIS COMO ENTRADAS 
 MOVLW B'11111111' 
 MOVWF TRISB ;TODOS OS PINOS DO PORTB COMO ENTRADAS 
 
 BANCO_0 ;SELECIONA BANCO 0 DE MEMORIA 
 
 MOVLW B'00000111' 
 MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O 
 
;*********************************************************************************************** 
 
Repare que aqui está a label INICIO. 
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 de 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 essa regra. 
Observe, na figura 4, que o registrador TRISA está no banco 1. 
Para termos acesso a esse registrador precisamos selecionar o banco 1, 
escrevendo BANCO_1 (label que definimos para isso). 
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 
ou no 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). 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
13 
 
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 esse número no registrador W. 
Fazemos isso com a instrução MOVLW, desta forma: 
MOVLW B'11111110' 
Assim, 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 lembra mover. L lembra 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 escrevê-lo 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 ou saída: 
MOVLW B'11111111' 
MOVWF TRISB 
 
No PIC16F628A, bem como noutros modelos de microcontroladores, a 
maioria dos pinos são compartilhados por mais de um recurso do microcontrolador. 
É o caso do pino RA0 que estamos utilizando. 
Além de ele ser um pino que podemos usar como entrada ou saída de sinal, 
também é um dos pinos de entrada do módulo comparador. 
O módulo comparador é um circuito do PIC16F628A que funciona como 
um CI comparador de tensão. 
Na inicialização do PIC16F628A, os pinos RA0, RA1, RA2 e RA3, estão 
vinculados ao módulo comparador de tensão e, por isso, para que possamos utilizá-los como pinos 
de entrada ou saída de sinal, precisamos configurar o registrador CMCON. 
O registrador CMCON está no banco 0 de memória, conforme você pode 
ver na figura 4 e, então, selecionamos este banco, escrevendo BANCO_0. 
Conforme pode ser visto no datasheet do PIC16F628A, se os bits 2, 1 e 0 do 
CMCON tiverem os valores 1, 0, e 1, respectivamente, os pinos RA0 e RA3 ficarão disponíveis 
para serem usados como entrada ou saída e se os valores desses mesmos bits forem 1, 1 e 1, os 
pinos RA0, RA1, RA2 e RA3 ficaram disponíveis. 
No nosso caso qualquer das duas alternativas serve, pois, só iremos usar o 
pino RA0. 
Então, vamos escrever o valor B'00000111' no registador CMCON: 
MOVLW B'00000111' 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
14 
MOVWF CMCON 
São apenas esses os Registradores de Uso Específico que precisamos 
configurar nesse programa. 
 
O próximo passo é inicializar as variáveis. 
 
;*********************************************************************************************** 
; INICIALIZACAO DAS VARIAVEIS 
 
 MOVLW INI_DELAY_0 ;W = INI_DELAY_0 
 MOVWF DELAY_0 ;INICIALIZA DELAY_0 
 MOVLW INI_DELAY_1 ;W = INI_DELAY_1 
 MOVWF DELAY_1 ;INICIALIZA DELAY_1 
 MOVLW INI_DELAY_2 ;W = INI_DELAY_2 
 MOVWF DELAY_2 ;INICIALIZA DELAY_2 
 
;*********************************************************************************************** 
Inicializar as variáveis é escrever nesses registradores os valores que eles 
devem ter na inicialização do programa. 
Nós criamos 3 variáveis: DELAY_0, DELAY_1 e DELAY_2. 
A variável DELAY_0 deve ser iniciada com o valor decimal 255. A 
DELAY_1 com o valor decimal 50 e a DELAY_3 com o valor decimal 13. 
Nós criamos constantes para esses valores, que foram INI_DELAY_0, para 
o valor 255, INI_DELAY_1, para o valor 50 e INI_DELAY_2, para o valor 13. 
Por isso, quando escrevemos MOVLW INI_DELAY_0, o registrador W 
assume o valor 255, ocorrendo o mesmo para os outros dois valores. 
 
O próximo passo é a rotina principal do programa. 
Nosso programa aguarda que passe meio segundo e testa o LED para ver se 
está aceso ou apagado. Se estiver aceso, apaga e se estiver apagado, acende, voltando a aguardar 
meio segundo para testar o LED novamente. 
Há mais de uma forma de contar este tempo de meio segundo. Neste 
programa vamos fazer isso decrementando os valores de variáveis. No próximo programa iremos 
utilizar 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 meio segundo. 
A maioria das instruções no PIC16F628A são executadas em 1 ciclo de 
instrução, sendo 1 ciclode instrução igual a 4 ciclos do sinal de clock. Algumas instruções são 
executadas em 2 ciclos de instrução, entre elas GOTO e CALL. 
Neste projeto, estamos utilizando o oscilador interno numa frequência de 4 
MHz e, portando, o ciclo do sinal de clock é de 250 nanosegundos (1/4.000.000). Sendo assim, o 
ciclo de instrução é de 1 microssegundo. 
Durante a simulação, iremos medir o tempo gasto até que DELAY_2 chegue 
a 0, para então definirmos os valores definitivos das variáveis, pois, os valores que definimos são 
uma estimativa. 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
15 
Vamos lá! 
Primeiramente escrevemos a label PRINCIPAL. 
Toda vez que quisermos que o programa volte a este ponto escreveremos: 
GOTO PRINCIPAL. (goto em Inglês significa vá para). 
Há certo preconceito a respeito da instrução GOTO. Algumas pessoas dizem 
que se deve evitar usar essa instrução. 
O que se deve evitar é usá-la desnecessariamente. 
Sempre que for necessário usar essa instrução use-a sem medo. Ela foi feita 
para ser usada! 
A primeira instrução é DECFSZ DELAY_0,F 
Essa instrução decrementa o valor de DELAY_0 e, após, verifica se o valor 
ficou igual a 0. 
Repare na letra F após o DELAY_0. Ela indica que o resultado será gravado 
nele próprio, ou seja, supondo que o valor de DELAY_0 fosse 255, então, ficará igual a 254. 
Se a letra fosse W, o resultado seria gravado no registrador W e o registrador 
DELAY_0 teria ficado com o mesmo valor de antes, ou seja, W ficaria com o valor de 254 e 
DELAY_0 com 255. 
Se após decrementar DELAY_0, o seu valor for igual a 0, a próxima linha 
do programa será pulada, se não, a próxima linha será executada. 
Repare no nome desta instrução: DEC vem de decrementar, F, o registrador 
que será decrementado, S, da palavra skip (neste caso, pular, em Inglês) e Z de zero. DECFSZ = 
decrementa o registrador F e pula a próxima linha se o resultado for zero. 
Se você procurar fazer essas associações entre o nome das instrução e sua 
função, irá memorizá-las mais facilmente. 
Voltando ao nosso programa, se o resultado da operação for diferente de 
zero, a próxima linha do programa será executada. 
O que precisamos que ocorra quando a variável DELAY_0 ainda não 
chegou a 0? 
Precisamos que ela continue a ser decrementada até que o seu valor seja 
igual a 0. 
Por isso, na próxima linha escrevemos: GOTO PRINCIPAL. 
Isso faz com que a variável DELAY_0 seja decrementada novamente até 
que seu valor chegue a 0, quando então, a linha após a instrução DECFSZ será pulada. 
Neste momento em que DELAY_0 chega a zero, nós iremos reiniciá-la. 
Fazemos isto, da mesma forma que fizemos para escrever o seu valor, na 
parte de Inicialização das Variáveis: 
 
MOVLW INI_DELAY_0 
MOVWF DELAY_0 
 
Após reinicializar DELAY_0, vamos decrementar DELAY_1 e testar se seu 
valor chegou a 0: 
DECFSZ DELAY_1,F 
 
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 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
16 
 
Porém, se o valor de DELAY_1 chegou a 0, reiniciaremos DELAY_1 e 
iremos decrementar DELAY_2 e testar se o seu valor chegou a 0: 
 
MOVLW INI_DELAY_1 
MOVWF DELAY_1 
DECFSZ DELAY_2,F 
 
Igualmente, se DELAY_2 não chegou a 0, o programa deverá voltar para 
decrementar DELAY_0: 
 
GOTO PRINCIPAL 
 
Mas, se DELAY_2 chegou a 0, iremos reiniciá-la e terá terminado a 
contagem do tempo: 
 
MOVLW INI_DELAY_2 
MOVWF DELAY_2 
 
Parece complicado? Com a prática isso fica bem simples. 
Recapitulando: DELAY_0 é decrementada até que seu valor chegue a 0, 
quando então, DELAY_1 é decrementada. Quando DELAY_1 chega a 0, DELAY_2 é 
decrementada. Quando DELAY_2 chega a 0, a contagem de tempo terminou. 
Com os valores que escrevemos provisoriamente nestas variáveis, 
DELAY_0 terá que zerar 50 vezes para que DELAY_1 seja zerada, enquanto que DELAY_1 terá 
zerar 13 vezes para que DELAY_2 seja zerada. 
Fazendo os cálculos, DELAY_0 será decrementada 165750 vezes para que a 
contagem de tempo chegue ao fim. 
Parece muito? Lembre-se de que o microcontrolador executa 1 instrução em 
1 microssegundo. 
Quando fizermos a simulação da execução do programa, iremos medir o 
tempo que demorou para DELAY_2 zerar e então, faremos os ajustes nos valores das variáveis, para 
que esse tempo seja de aproximadamente meio segundo. 
 
A rotina principal até o momento está assim: 
 
************************************************************************************************ 
 
PRINCIPAL ;ROTINA PRINCIPAL DO PROGRAMA 
 
 DECFSZ DELAY_0,F ;DECREMENTA DELAY_0. DELAY_0 = 0? 
 GOTO PRINCIPAL ;NÃO 
 MOVLW INI_DELAY_0 ;SIM, W = INI_DELAY_0 
 MOVWF DELAY_0 ;REINICIALIZA DELAY_0 
 DECFSZ DELAY_1,F ;DECREMENTA DELAY_1. DELAY_1 = 0? 
 GOTO PRINCIPAL ;NÃO 
 MOVLW INI_DELAY_1 ;SIM, W = INI_DELAY_1 
 MOVWF DELAY_1 ;REINICIALIZA DELAY_1 
 DECFSZ DELAY_2,F ;DECREMENTA DELAY_2. DELAY_2 = 0? 
 GOTO PRINCIPAL ;NÃO 
 MOVLW INI_DELAY_2 ;SIM, W = INI_DELAY_2 
 MOVWF DELAY_2 ;REINICIALIZA DELAY_2 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
17 
 
Agora que passou o tempo de meio 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 
 
Com isso o LED irá apagar. 
Mas, se quando testamos o bit 0 do PORTA com a instrução BTFSS, o valor 
do bit era igual a 0, então, a próxima linha do programa seria executada. 
Sendo o valor do bit 0 do PORTA igual a 0, significa que o LED está 
apagado e, então, precisamos acendê-lo. 
Para isso usamos a instrução BSF para fazer o valor do bit 0 do PORTA 
igual a 1: 
BSF LED 
 
Com isso acendemos o LED. 
Então, este trecho do nosso programa ficou assim: 
 
BTFSS LED ;testa o valor do bit 0 do PORTA 
BSF LED ;valor = 0, acende o LED 
BCF LED ;valor = 1, apaga o LED 
 
Espere. Temos um problema aí: 
No caso do valor do bit ser igual a 0, ele executa a instrução BSF LED e 
em seguida executa a instrução BCF LED, ou seja, o LED é aceso e apagado em seguida. Como 
faremos para resolver isso? 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
18 
Faremos assim: 
 
 BTFSS LED ;testa o valor do bit 0 do PORTA 
 GOTOACENDE_LED ;valor = 0, desvia 
 BCF LED ;valor = 1, apaga o LED 
 GOTO PRINCIPAL ;desvia 
 
ACENDE_LED 
 BSF LED ;ACENDE O LED 
 GOTO PRINCIPAL ;desvia 
 
 END ;Fim do programa 
 
Desta forma, quando o valor do bit for igual a 0, o programa será desviado 
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 isso chegamos ao final 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, finalizando o programa: 
 
;*********************************************************************************************** 
; PROGRAMA: PISCA LED 
; VERSÃO 1.0 
; DESENVOLVIDO POR: MULDER_FOX 
; DATA DE CONCLUSÃO: / / 
;*********************************************************************************************** 
 
 #INCLUDE <P16F628A.INC> ;ARQUIVO PADRAO MICROCHIP PARA O PIC16F628A 
 
;*********************************************************************************************** 
; BITS DE CONFIGURAÇÃO 
 
 __CONFIG _INTOSC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BOREN_OFF 
& _LVP_OFF & _CP_OFF & DATA_CP_OFF 
 
;********************************************************************************************** 
; 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 
;********************************************************************************************** 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
19 
 
; VARIAVEIS 
 
 CBLOCK 0X20 ;ENDERECO INICIAL DA MEMORIA DO USUARIO 
 
 DELAY_0 ;USADO PARA GERAR O TEMPO DE 0,5 SEGUNDO 
 DELAY_1 ;USADO PARA GERAR O TEMPO DE 0,5 SEGUNDO 
 DELAY_2 ;USADO PARA GERAR O TEMPO DE 0,5 SEGUNDO 
 
 ENDC ;FIM DO BLOCO DE MEMORIA 
 
;********************************************************************************************** 
; CONSTANTES 
 
INI_DELAY_0 EQU .255 ;VALOR QUE DELAY_0 INICIA 
INI_DELAY_1 EQU .50 ;VALOR QUE DELAY_1 INICIA 
INI_DELAY_2 EQU .13 ;VALOR QUE DELAY_2 INICIA 
 
;*********************************************************************************************** 
; SAÍDA 
 
 #DEFINE LED PORTA,0 ;LED LIGADO EM RA0 
 
;*********************************************************************************************** 
; VETOR DE RESET 
 
 ORG 0X00 ;ENDERECO INICIAL DE PROCESSAMENTO 
 GOTO INICIO ;DESVIA PARA INICIO 
 
;*********************************************************************************************** 
; ROTINA DE INTERRUPÇÃO 
 
 ORG 0X04 ;VETOR DAS INTERRUPÇÕES 
 RETFIE ;RETORNA 
 
;*********************************************************************************************** 
; CONFIGURACAO DOS REGISTRADORES DE USO ESPECÍFICO 
 
INICIO 
 
 BANCO_1 ;SELECIONA BANCO 1 DE MEMORIA 
 MOVLW B'11111110' ;W = B'11111110' 
 MOVWF TRISA ;CONFIGURA RA0 COMO SAÍDA E DEMAIS COMO ENTRADAS 
 MOVLW B'11111111' 
 MOVWF TRISB ;TODOS OS PINOS DO PORTB COMO ENTRADAS 
 BANCO_0 ;SELECIONA BANCO 0 DE MEMORIA 
 MOVLW B'00000111' 
 MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O 
 
;*********************************************************************************************** 
 
 
 
 
 
 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
20 
 
;********************************************************************************************** 
; INICIALIZACAO DAS VARIAVEIS 
 
 MOVLW INI_DELAY_0 ;W = INI_DELAY_0 
 MOVWF DELAY_0 ;INICIALIZA DELAY_0 
 MOVLW INI_DELAY_1 ;W = INI_DELAY_1 
 MOVWF DELAY_1 ;INICIALIZA DELAY_1 
 MOVLW INI_DELAY_2 ;W = INI_DELAY_2 
 MOVWF DELAY_2 ;INICIALIZA DELAY_2 
 
;*********************************************************************************************** 
 
PRINCIPAL ;ROTINA PRINCIPAL DO PROGRAMA 
 
 CLRWDT ;LIMPA O WDT 
 DECFSZ DELAY_0,F ;DECREMENTA DELAY_0. DELAY_0 = 0? 
 GOTO PRINCIPAL ;NÃO 
 MOVLW INI_DELAY_0 ;SIM, W = INI_DELAY_0 
 MOVWF DELAY_0 ;REINICIALIZA DELAY_0 
 DECFSZ DELAY_1,F ;DECREMENTA DELAY_1. DELAY_1 = 0? 
 GOTO PRINCIPAL ;NÃO 
 MOVLW INI_DELAY_1 ;SIM, W = INI_DELAY_1 
 MOVWF DELAY_1 ;REINICIALIZA DELAY_1 
 DECFSZ DELAY_2,F ;DECREMENTA DELAY_2. DELAY_2 = 0? 
 GOTO PRINCIPAL ;NÃO 
 MOVLW INI_DELAY_2 ;SIM, W = INI_DELAY_2 
 MOVWF DELAY_2 ;REINICIALIZA DELAY_2 
 BTFSS LED ;TESTA O VALOR DO BIT 0 DO PORTA 
 GOTO ACENDE_LED ;VALOR = 0, DESVIA 
 BCF LED ;VALOR = 1, APAGA O LED 
 GOTO PRINCIPAL ;DESVIA 
ACENDE_LED 
 BSF LED ;ACENDE O LED 
 GOTO PRINCIPAL ;DESVIA 
 
;********************************************************************************************** 
 END ;FIM DO PROGRAMA 
 
;********************************************************************************************** 
 
Nosso próximo passo é simular a execução do programa para ver se ele se 
comporta como esperamos. 
No menu “Project”, clique em “Project Wizard”. 
Na janela que se abre clique em “Avançar”: 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
21 
Figura 5 
 
 
Na janela seguinte (“Step One”), selecione o PIC16F628A e clique em 
“Avançar”: 
 
 
Figura 6 
 
 
 
 
 
 
 
 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
22 
 
 
Na próxima janela (“Step Two”), clique em “Avançar”: 
 
Figura 7 
 
 
Na próxima janela (“Step Three”), clique em “Browse”: 
 
 
 
 
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”: 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
23 
 
Figura 9 
 
 
 
 
Em seguida clique em “Avançar” 
 
 
Figura 10 
 
 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
24 
 
 
 
Na janela seguinte (“Step Four”), selecione o arquivo Pisca LED.asm, 
clique em “Add” e em seguida clique em “Avançar”: 
 
Figura 11 
 
Na janela seguinte (“Summary”), clique em concluir: 
 
Figura 12 
 
 
 
 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
25No menu “Project”, clique em “Build All”. Na janela que se abre, clique em 
“Absolute”: 
Figura 13 
 
A seguir, expanda a janela chamada “Output”: 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
26 
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á à linha 56 e veja que o registrador em questão é o TRISA, que está no 
banco 1. Repare que nós selecionamos esse banco antes e, por isso, não precisamos nos preocupar. 
O mesmo ocorre para a mensagem da linha 58. 
Agora vamos à simulação: 
Clique no menu “Debugger” e depois, em “Select Tool”, selecione “MPLAB 
SIM”. 
Clique novamente no menu “Debugger” e depois em “Settings” 
Na aba “Osc/Trace”, em “Processor Frequency” digite 4 e selecione Mhz. 
Na aba “Animation / Real Time Updates”, selecione “Enable Real Time 
Watch Updates” e leve o cursor todo para a esquerda “Fastest”. 
Clique em “OK”. 
No menu “View”, clique em “Watch”. 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
27 
Na janela “Watch”, clique onde está indicado na figura abaixo, selecione o 
PORTA e clique em “Add SFR”: 
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 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
28 
Em “Add SFR” adicionamos os Registradores de Uso Específico que 
queremos visualizar, enquanto em “Add Symbol” adicionamos as variáveis por nós criadas que 
queremos visualizar. 
No menu “Window”, clique em “Pisca LED.asm”: 
 
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”: 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
29 
Figura 18 
Clique no botão “Reset”. 
O cursor vai para a linha 46 onde está a instrução GOTO INICIO. 
Esta é a posição 0X00 da memória de programa, e, portanto é a instrução 
contida nesta posição que o microcontrolador irá executar em primeiro lugar, quando for ligado ou 
resetado. 
Repare que apareceu uma seta verde do lado esquerdo: 
Figura 19 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
30 
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 
 
Outras informações podem ser vistas nessa barra, como o modelo do 
microcontrolador, o valor do contador de programa (0X2), o valor do registrador W, dos bits z, dc e 
c do registrador STATUS, etc... 
O contador de programa – PC, armazena o endereço na memória de 
programa onde está a instrução que será executado pelo microcontrolador. 
Veremos o significado dos valores dos bits z, dc e c do registrador STATUS 
em outra parte deste tutorial. 
Continue clicando no botão “Step Into” e acompanhando a simulação da 
execução do programa. 
Após ser executada a instrução MOVWF DELAY_0, no menu “Window” 
escolha a janela “Watch” e repare que a variável DELAY_0 assumiu o valor 255. 
Volte para a janela do programa, escolhendo-a no menu “Window”, 
continue clicando em “Step Into” e depois visualize na janela “Watch” que DELAY_1 e DELAY_2, 
assumem os valores 50 e 13 respectivamente. 
Continue clicando no botão “Step Into” e veja que após a instrução 
DECFSZ DELAY_0 ser executada, o valor de DELAY_0 passa a ser 254 e que como o seu valor 
é diferente de 0, o programa volta para a linha após a label PRINCIPAL, pois, executa a instrução 
GOTO PRINCIPAL. 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
31 
Se continuar clicando em “Step Into”, você poderá acompanhar a variável 
DELAY_0 sendo decrementada. 
Ela irá ser decrementada até chegar ao valor 0, quando, então, o programa 
irá pular a linha com a instrução GOTO PRINCIPAL. 
Para agilizar, na janela “Watch”, dê um duplo clique no valor da variável 
DELAY_0, e altere o seu valor para 1. 
Depois, volte a clicar em “Step Into” e repare que, como DELAY_0 chegou 
ao valor 0, a linha com a instrução GOTO PRINCIPAL é pulada, sendo executadas as instruções 
que reiniciam DELAY_0 e depois a que decrementa DELAY_1. 
 
DELAY_1, agora vale 49 e como é diferente de 0, o programa é desviado 
para onde está a label PRINCIPAL. 
A partir de agora, DELAY_0 voltará a ser decrementada até chegar a 0 de 
novo. 
Vamos mudar os valores de DELAY_0 e de DELAY_1 para 1 e continuar 
clicando em “Step Into”. 
Veremos que DELAY_1 chega a 0, é reiniciada e DELAY_2 é decrementada. 
Agora vamos mudar o valor das três para 1. 
Clicando em “Step Into” veremos que agora DELAY_2 chega a 0, é 
reiniciada e o programa irá executar a instrução BTFSS LED para testar o valor do bit 0 do PORTA, 
o que é o mesmo que verificar se o LED está aceso ou apagado. 
Neste teste ele constata que o valor do bit é igual a 0 e o programa, então, é 
desviado para a instrução após a label ACENDE_LED, onde é executada a instrução BSF LED. 
Em seguida ele volta para PRINCIPAL. 
Vá para a janela “Watch” e veja que o bit 0 do PORTA foi setado, isto é, seu 
valor é igual a 1, acendendo o LED. 
Agora, o programa voltará a decrementar as variáveis. 
Vamos agilizar, alterando o valor das três variáveis para 1. 
Desta vez no teste do bit ele verifica que o valor é 1 e executa a instrução 
BCF LED, fazendo o valor do bit igual a 0, apagando o LED. 
Verifique na janela “Watch” que o bit 0 do PORTA foi apagado (= 0). 
Agora vamos medir se o tempo que demora para a variável DELAY_2 
chegar a 0 é de aproximadamente 500 milissegundos. 
Dê um duplo clique na linha que contêm a instrução BTFSS LED. 
Você verá que aparece uma letra B dentro de um círculo vermelho, 
conforme a figura abaixo: 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
32 
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 à linha onde está a instrução CLRWDT. 
No menu “Debugger”, clique em “StopWatch”. 
Eis a janela do “StopWatch”: 
 
Tutorial de Programação Assembly para Microcontroladores PIC- Parte 1 – Pisca LED 
33 
 
 
Figura 22 
 
Nesta janela, clique no botão “Zero”. 
Volte para a janela do programa, selecionando-a no menu “Window” e 
clique no botão “Run” da barra de ferramentas do simulador. 
O programa será executado até a linha onde está o Breakpoint, ou seja, na 
linha onde está a instrução BTFSS. 
Volte para a janela do “StopWatch”. 
Veja no campo “Time” que se passaram 665 milissegundos desde que o 
“StopWatch” foi zerado (quando clicamos em “Zero”): 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
34 
 
Figura 23 
 
 
 
Ou seja, está demorando 665 milissegundos para que a variável DELAY_2 
chegue a 0, mas, nós queremos que demore 500 milissegundos. 
Vamos medir de quanto em quanto tempo a variável DELAY_2 é 
decrementada. 
Para isto, vamos inserir outro Breakpoint na linha onde está a instrução 
DECFSZ DELAY_2. 
Após inserir o Breakpoint, clique no botão “Reset” do simulador e vá 
clicando no botão “Step Into” até chegar à instrução CLRWDT. 
Vá para a janela do “StopWatch” e clique em “Zero”. 
Volte para a janela do programa e clique em “Run”. 
Quando o programa parar na linha onde está o Breakpoint vá para a janela 
do “StopWatch”. 
Repare que passaram 51 milissegundos, ou seja, a variável DELAY_2 é 
decrementada a cada 51 milissegundos. 
 
 
 
 
 
 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
35 
 
 
 
 
Figura 24 
 
 
 
 
Estamos com um excesso de 125 milissegundos no tempo total. 
Se nós diminuirmos o valor de inicialização da variável DELAY_2 em 3 
unidades, ou seja, diminuirmos para 10, o tempo total deverá cair para cerca de 512 milissegundos. 
Vamos verificar. 
Vá para a janela do programa e na parte “CONSTANTES”, altere a linha 
INI_DELAY_2 EQU .13 para INI_DELAY_1 EQU .10 
Como alteramos o programa, precisamos compilar de novo e para isso, no 
menu “Project” clique em “Build All”. 
Retire o Breakpoint da linha onde está a instrução DECFSZ DELAY_2, 
dando um duplo clique nessa linha, e deixe o outro que está na linha com a instrução BTFSS LED. 
Clique no botão “Reset” do simulador e vá clicando em “Step Into” até 
chegar à linha com a instrução CLRWDT. Neste momento, vá para a janela “StopWatch” e clique 
em “Zero”. 
Volte para a janela do programa e clique no botão “Run” do simulador. 
Quando o programa parar no Breakpoint, abra a janela “StopWatch”. 
Repare que realmente o tempo total caiu para 512 milissegundos. 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
36 
Figura 25 
 
Ainda temos um excesso de 12 milissegundos. 
Vamos experimentar diminuir o valor de inicialização de DELAY_1 para 49, 
da mesma forma que mudamos o valor de DELAY_2. 
Lembre-se de que temos que compilar de novo, clicando no menu “Project” 
e em “Build All”. 
Agora o tempo total é bem próximo de 500 milissegundos: 
 
Figura 26 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
37 
 
Vamos experimentar diminuir o valor da variável DELAY_0 para 254. 
Agora, o tempo é de praticamente 500 milissegundos. 
Figura 27 
 
 
Ficamos, então com estes valores para as variáveis: DELAY_0 = 254, 
DELAY_1 = 49 e DELAY_2 = 10. 
Nosso programa está como queríamos e agora é hora de gravá-lo no 
microcontrolador. 
Você poderá comprar um gravador ou montar o seu próprio gravador. 
Há vários modelos à venda e também vários esquemas de gravadores na 
Internet para quem quiser montar o seu. 
Existem gravadores que são conectados na porta paralela, outros na porta 
serial e também os que são conectados na porta USB. 
Os melhores são os USB, pela praticidade. 
Alguns gravadores funcionam com o MPLAB, enquanto outros necessitam 
de outro software. 
A figura a seguir é de um esquema de gravador para ser conectado na porta 
serial do computador (conector DB9). 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
38 
 
Figura 28 
Para utilizá-lo é necessário o programa IC-prog: 
http://www.ic-prog.com/icprog106B.zip 
Também é necessário o driver para Windows XP: 
http://www.ic-prog.com/icprog_driver.zip. 
 
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. 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
39 
Figura 29 
 
 
Na próxima janela também clique em OK, deixando como está, pois, este 
gravador é baseado no JDM. 
 
Figura 30 
 
 Se for exibida a mensagem vista na figura a seguir ou outras de mesmo teor 
clique em OK. 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
40 
Figura 31 
 
A janela do IC-prog é vista na figura a seguir. 
 
Figura 32 
 
No menu “Settings”, clique em “Options”. 
Na aba “Language” escolha “Portuguese”. 
No menu “Configuração” clique em “Opções”. 
Na aba “Diversos”, marque “Activar Driver NT/2000/XP” 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
41 
Na janela que abre clique em “Yes” para reiniciar o IC-prog. 
 
 
Figura 33 
 
Na janela que se abre, perguntando se deseja instalar o driver, clique em 
“Yes”. 
 
Figura 34 
 
No menu “Configuração”, clique em “Opções” e na aba “Diversos”, em 
“Processo Prioritário”, selecione “Alto” e clique em “OK”. 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
42 
No menu “Configuração”, aponte para “Dispositivo” e depois para 
“Microchip PIC” e escolha o PIC16F628A. 
No menu “Arquivo”, clique em “Abrir”. 
Localize e selecione o arquivo Pisca LED.hex e clique em “Abrir”. 
 
 
Figura 35 
 
 
 
Repare do lado direito da janela, que o tipo de oscilador e os “Fusíveis” já 
estão configurados, pois nós os configuramos no programa, com a diretiva CONFIG. 
Certifique-se de que o gravador está conectado na porta serial do 
computador. 
No menu “Comando”, clique em “Programar Tudo” e na janela de 
confirmação, clique em “Yes”. 
Será gravado o programa no microcontrolador e depois o programa gravado 
será lido e comparado com o arquivo. Se estiverem iguais, será apresentada a mensagem 
“Dispositivo verificado com sucesso”, conforme figura a seguir. 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 1 – Pisca LED 
43 
Figura 36 
 
Agora podemos montar o circuito da figura 2 e constatar o seu 
funcionamento. 
Aqui termina a primeira parte deste tutorial. Espero que você tenha gostado. 
Na próxima parte, vamos criar um programa para a mesma finalidade, 
porém, utilizando o TIMER 0 para obter o intervalo de meio segundo entre as piscadas do LED.
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 2 – Pisca LED II 
44 
Parte 2 
 
Pisca LED II 
 
Nesta 2ª parte iremos montar o mesmo circuito da Parte 1, mas utilizaremos 
o Timer 0 do PIC16F628A para obter a frequência de cerca de 1 Hz para o LED. 
O Timer 0 é um circuito do microcontrolador que incrementa um registrador 
chamado TMR0, ou seja, é um circuito que faz com que o valor desse registrador vá aumentando de 
1 em 1. 
O registrador TMR0 é de 8 bits (como todos os registradores do 
PIC16F628A) e, portanto,seu valor pode variar de 0 a 255. O seu valor pode ser lido e também 
alterado, ou seja, podemos escrever o valor que quisermos nele (de 0 a 255). 
O Timer 0 pode ser configurado para incrementar o registrador TMR0 a 
partir do ciclo de instrução ou a partir do ciclo de um sinal externo aplicado no pino T0CKI (pino 3). 
Quando ele é incrementado pelo ciclo de instrução, diz-se que ele está sendo 
usado como timer e quando é incrementado por um sinal aplicado no pino T0CKI, diz-se que ele 
está sendo usado como contador (pois pode ser usado para contar os ciclos do sinal externo). 
No nosso caso vamos configurá-lo para que seja incrementado a partir do 
ciclo de instrução, pois, desejamos obter um determinado intervalo de tempo, conhecendo o tempo 
de duração do ciclo de instrução. 
Podemos configurar o Timer 0 para que o registrador TMR0 seja 
incrementado a cada ciclo ou para que seja incrementado a cada 2, 4, 8, 16, 32, 64, 128 e 256 ciclos. 
Isso é o que se chama de Prescaler. Quando ele estiver configurado para incrementar a cada ciclo, 
dizemos que o valor do prescaler é 1:1, quando for incrementado a cada 2 ciclos, 1:2, e assim por 
diante. 
Quando o registrador TMR0 estiver com o valor 255, o próximo incremento 
fará seu valor voltar a 0 e, então, dizemos que ele “estourou”. 
Quando o TMR0 estoura, o bit T0IF do registrador INTCON é setado, ou 
seja, o valor desse bit passa a ser igual a 1, sendo que ele precisa ser apagado na rotina do programa 
para que se detecte nova mudança de seu estado. Ao mesmo tempo uma interrupção é provocada, se 
estiver habilitada. 
A vantagem de se usar o Timer 0 para obter o tempo que desejamos é que o 
programa fica livre para executar outras funções, bastando monitorar o estado do bit T0IF para ver 
se o tempo que desejamos já passou. Outra opção é habilitar a interrupção de estouro do Timer 0. 
O intervalo de tempo que precisamos é de 500 milissegundos. 
Para uma frequência do oscilação de 4 MHz, o ciclo de instrução é de 1 
microssegundo, como já vimos na parte 1 deste tutorial. 
Dividindo 500 milissegundos por 1 microssegundo, obtemos o valor de 
500.000, ou seja, a cada 500.000 ciclos de instrução terão se passado 500 milissegundos. 
Se configurarmos o prescaler do Timer 0 para 1:1, ou seja, se o registrador 
TMR0 for incrementado a cada ciclo de instrução, ele irá estourar a cada 256 microssegundos. 
Como este tempo é muito menor do que o que estamos querendo, vamos 
configurar o prescaler para o seu valor máximo, isto é, para 1:256. 
 
Dessa forma, o TMR0 será incrementado a cada 256 ciclos de instrução, ou 
seja, a cada 256 microssegundos. 
Assim, o TMR0 irá estourar a cada 256 x 256 microssegundos, isto é, a cada 
65.536 microssegundos, o que equivale a 65,536 milissegundos. 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 2 – Pisca LED II 
45 
Ou seja, mesmo com o prescaler no máximo, serão necessários mais de 1 
estouros do TMR0 para obtermos o tempo que desejamos e, portanto, teremos que contar esses 
estouros. 
Porém, a divisão de 500 milissegundos por 65,536 milissegundos não 
resulta em um número exato. 
Temos que, de alguma forma, obter um número exato de estouros que 
correspondam ao tempo de 500 milissegundos. 
Como vimos, 500 milissegundos correspondem a 500.000 ciclos de 
instrução. 
Dividindo 500.000 pelos valores de prescaler disponíveis, constatamos que 
o maior valor do prescaler que resulta numa divisão exata é 1:32 e este valor é 15.625. 
Por sua vez, 15.625 é igual ao produto de 125 por 125. 
Com o valor do prescaler definido em 1:32, o TMR0 será incrementado a 
cada 32 ciclos de instrução, ou seja, a cada 32 microssegundos. 
Se após todas as vezes que o TMR0 estourar, nós o reiniciarmos com o valor 
de 131 (escrevendo este valor nele), após 125 incrementos (256 – 131) ele irá estourar, ou seja, irá 
estourar a cada 32 x 125 microssegundos = 4.000 microssegundos = 4 milissegundos. 
Se contarmos 125 estouros do TMR0, teremos o tempo de 500 
milissegundos. 
Vamos ao programa! 
O fluxograma é o mesmo e o programa é igual até este ponto: 
 
;*********************************************************************************************** 
; PROGRAMA: PISCA LED II 
; VERSÃO 1.0 
; DESENVOLVIDO POR: MULDER_FOX 
; DATA DE CONCLUSÃO: / / 
;*********************************************************************************************** 
 
 #INCLUDE <P16F628A.INC> ;ARQUIVO PADRAO MICROCHIP PARA O PIC16F628A 
 
;*********************************************************************************************** 
; BITS DE CONFIGURAÇÃO 
 
 __CONFIG _INTOSC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BOREN_OFF 
& _LVP_OFF & _CP_OFF & DATA_CP_OFF 
 
;********************************************************************************************** 
; 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 
 
;********************************************************************************************** 
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 é a definição das variáveis. 
Iremos utilizar apenas uma variável, que será usada para contar os estouros 
do TMR0. 
Vamos nomeá-la de CONT_EST_TMR0: 
 
;********************************************************************************************** 
; VARIÁVEIS 
 
 CBLOCK 0X20 ;ENDERECO INICIAL DA MEMORIA DO USUARIO 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 2 – Pisca LED II 
46 
 CONT_EST_TMR0 ;USADO PARA CONTAR OS ESTOUROS DO TMR0 
 
 ENDC ;FIM DO BLOCO DE MEMORIA 
 
;********************************************************************************************** 
 
O próximo passo é a definição das constantes. 
Iremos utilizar duas constantes, uma no valor de 131 que será usada para 
reinicializar o TMR0 e outra no valor de 125 para a variável que irá contar os estouros do TMR0. 
Vamos chamá-las de INI_TMR0 e INI_CONT_EST_TMR0. 
A partir daí, o programa é igual até a configuração dos registradores: 
 
;********************************************************************************************** 
; CONSTANTES 
 
INI_TMR0 EQU .131 ;VALOR QUE TMR0 INICIA 
INI_CONT_EST_TMR0 EQU .125 ;VALOR QUE CONT_EST_TMR0 INICIA 
 
;*********************************************************************************************** 
; SAÍDA 
 
 #DEFINE LED PORTA,0 ;LED LIGADO EM RA0 
 
;*********************************************************************************************** 
; VETOR DE RESET 
 
 ORG 0X00 ;ENDERECO INICIAL DE PROCESSAMENTO 
 GOTO INICIO ;DESVIA PARA INICIO 
 
;*********************************************************************************************** 
; ROTINA DE INTERRUPÇÃO 
 
 ORG 0X04 ;VETOR DAS INTERRUPÇÕES 
 RETFIE ;RETORNA 
 
;*********************************************************************************************** 
 
Como iremos utilizar o Timer 0, precisamos configurar o registrador 
OPTION_REG, que está associado a ele. 
Esse registradorencontra-se no banco 1 de memória. 
Conforme consta no datasheet do PIC16F628A, o bit 5 desse registrador, é o 
que define se o TMR0 será incrementado pelo ciclo de instrução ou a partir de um sinal externo. 
Para que ele seja incrementado pelo ciclo de instrução, o valor desse bit deve ser igual a 0. 
 
 
O bit 3 define se o prescaler será usado pelo Timer 0. Para que o Timer 0 
use o prescaler, o valor desse bit deve ser igual a 0. 
Os bits 2, 1 e 0 definem o valor do prescaler. No nosso caso, iremos utilizar 
o valor 1:32, e, portanto, os valores desses bits deverão ser 1, 0 e 0, respectivamente. 
Os demais bits não nos interessam e, portanto, vamos deixá-los com o valor 
1, valor com o qual eles são inicializados. 
Dessa forma, iremos escrever o seguinte número binário no registrador 
OPTION_REG: 11010100. 
As configurações dos outros registradores são as mesmas. 
A seguir, inicializamos a variável e teremos chegado à rotina principal: 
 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 2 – Pisca LED II 
47 
;*********************************************************************************************** 
; CONFIGURACAO DOS REGISTRADORES DE USO ESPECÍFICO 
 
INICIO 
 
 BANCO_1 ;SELECIONA BANCO 1 DE MEMORIA 
 MOVLW B'11010100' ;W = B'11010100' 
 MOVWF OPTION_REG ;TIMER 0 INCREMENTADO PELO CICLO DE INSTRUCAO, COM PRESCALER DE 1:32 
 MOVLW B'11111110' ;W = B'11111110' 
 MOVWF TRISA ;CONFIGURA RA0 COMO SAÍDA E DEMAIS COMO ENTRADAS 
 MOVLW B'11111111' 
 MOVWF TRISB ;TODOS OS PINOS DO PORTB COMO ENTRADAS 
 BANCO_0 ;SELECIONA BANCO 0 DE MEMORIA 
 MOVLW B'00000111' 
 MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O 
 
;*********************************************************************************************** 
; INICIALIZACAO DA VARIAVEL 
 
 MOVLW INI_CONT_EST_TMR0 ;W = INI_CONT_EST_TMR0 
 MOVWF CONT_EST_TMR0 ;INICIALIZA CONT_EST_TMR0 
 
;*********************************************************************************************** 
 
PRINCIPAL ;ROTINA PRINCIPAL DO PROGRAMA 
 
A primeira instrução da rotina principal é CLRWDT para limpar o WDT. 
A seguir, iremos testar o bit T0IF do registrador INTCON para verificarmos 
se o TMR0 estourou: 
BTFSS INTCON,TOIF ;TMR0 ESTOUROU? 
 
Se o TMR0 não houver estourado, o valor desse bit será igual a 0 e a 
próxima linha do programa será executada. Portanto, nessa linha escreveremos a instrução GOTO 
PRINCIPAL, para que o bit seja testado novamente. 
 
GOTO PRINCIPAL ;NAO 
 
Se o TMR0 houver estourado, o valor do bit será igual a 1 e a linha com a 
instrução GOTO PRINCIPAL será pulada. 
Nesse caso, a primeira providência que iremos tomar é zerar o bit TOIF para 
que na próxima vez que o TMR0 estourar possamos detectar a mudança do seu valor para 1: 
BCF INTCON,T0IF ;SIM 
 
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: 
 
DECFSZ CONT_EST_TMR0,F ;DECREMENTA CONT_EST_TMR0. CONT_EST_TMR0 = 0? 
 
Se o seu valor não for igual a 0, a próxima linha será executada e, nesse caso, 
desviaremos o programa para o começo da rotina principal: 
 
GOTO PRINCIPAL ;NAO 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 2 – Pisca LED II 
48 
Se o valor da variável houver chegado a 0, iremos reiniciá-la e, nesse caso, 
terão se passado cerca de 500 milissegundos. 
A partir daqui, o resto da rotina é igual ao do programa da parte I deste 
tutorial. 
Portanto, o programa ficou assim: 
 
;*********************************************************************************************** 
; PROGRAMA: PISCA LED II 
; VERSÃO 1.0 
; DESENVOLVIDO POR: MULDER_FOX 
; DATA DE CONCLUSÃO: / / 
;*********************************************************************************************** 
 
 #INCLUDE <P16F628A.INC> ;ARQUIVO PADRAO MICROCHIP PARA O PIC16F628A 
 
;*********************************************************************************************** 
; BITS DE CONFIGURAÇÃO 
 
 __CONFIG _INTOSC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BOREN_OFF 
& _LVP_OFF & _CP_OFF & DATA_CP_OFF 
 
;********************************************************************************************** 
; 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 
 
 CBLOCK 0X20 ;ENDERECO INICIAL DA MEMORIA DO USUARIO 
 
 CONT_EST_TMR0 ;USADO PARA CONTAR OS ESTOUROS DO TMR0 
 
 ENDC ;FIM DO BLOCO DE MEMORIA 
 
;********************************************************************************************** 
; CONSTANTES 
 
INI_TMR0 EQU .131 ;VALOR QUE TMR0 INICIA 
INI_CONT_EST_TMR0 EQU .125 ;VALOR QUE CONT_EST_TMR0 INICIA 
 
;*********************************************************************************************** 
; SAÍDA 
 
 #DEFINE LED PORTA,0 ;LED LIGADO EM RA0 
 
;*********************************************************************************************** 
; VETOR DE RESET 
 
 ORG 0X00 ;ENDERECO INICIAL DE PROCESSAMENTO 
 GOTO INICIO ;DESVIA PARA INICIO 
 
;*********************************************************************************************** 
; ROTINA DE INTERRUPÇÃO 
 
 ORG 0X04 ;VETOR DAS INTERRUPÇÕES 
 RETFIE ;RETORNA 
 
 
 
Tutorial de Programação Assembly para Microcontroladores PIC - Parte 2 – Pisca LED II 
49 
;*********************************************************************************************** 
; CONFIGURACAO DOS REGISTRADORES DE USO ESPECÍFICO 
 
INICIO 
 
 BANCO_1 ;SELECIONA BANCO 1 DE MEMORIA 
 MOVLW B'11010100' ;W = B'11010100' 
 MOVWF OPTION_REG ;TIMER 0 INCREMENTADO PELO CICLO DE INSTRUCAO , COM PRESCALER DE 1:32 
 MOVLW B'11111110' ;W = B'11111110' 
 MOVWF TRISA ;CONFIGURA RA0 COMO SAÍDA E DEMAIS COMO ENTRADAS 
 MOVLW B'11111111' 
 MOVWF TRISB ;TODOS OS PINOS DO PORTB COMO ENTRADAS 
 BANCO_0 ;SELECIONA BANCO 0 DE MEMORIA 
 MOVLW B'00000111' 
 MOVWF CMCON ;CONFIGURA RA3, RA2, RA1 E RA0 COMO I/O 
 
;*********************************************************************************************** 
; INICIALIZACAO DA VARIAVEL 
 
 MOVLW INI_CONT_EST_TMR0 ;W = INI_CONT_EST_TMR0 
 MOVWF CONT_EST_TMR0 ;INICIALIZA CONT_EST_TMR0 
 
;*********************************************************************************************** 
PRINCIPAL ;ROTINA PRINCIPAL DO PROGRAMA 
 
 CLRWDT ;LIMPA O WDT 
 BTFSS INTCON,T0IF ;TMR0 ESTOUROU? 
 GOTO PRINCIPAL ;NAO 
 BCF INTCON,T0IF ;SIM 
 MOVLW INI_TMR0 ;W = INI_TMR0 
 MOVWF TMR0 ;REINICIA TMR0 
 DECFSZ CONT_EST_TMR0,F ;DECREMENTA CONT_EST_TMR0. CONT_EST_TMR0 = 0? 
 GOTO PRINCIPAL ;NAO 
 MOVLW INI_CONT_EST_TMR0 ;SIM, W = INI_CONT_EST_TMR0 
 MOVWF CONT_EST_TMR0 ;REINICIALIZA CONT_EST_TMR0 
 BTFSS LED

Outros materiais