Buscar

ApostilaPIC_1

Prévia do material em texto

IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 1 de 13 
Microcontroladores PIC16F628A – Parte 1 
 
1. Introdução 
 
Os microcontroladores se caracterizam por incorporarem internamente uma CPU, memórias de 
programa e dados e vários periféricos como timers, watchdog timers, interface serial, conversores 
analógicos-digitais, geradores de PWM, etc., fazendo com que a aplicação final fique extremamente 
compacta. 
Uma linha de microcontroladores muito utilizada atualmente é a família PIC, fabricados pela 
Microchip. Essa família de microcontroladores faz uso da tecnologia RISC (Reduced Instruction Set 
Computer ou computador com conjunto de instruções reduzidos) e são baseados na arquitetura Harvard. 
 Na arquitetura von Neumann, o sistema utiliza o mesmo barramento de dados para acessar a 
memória de programa e a memória de dados, o qual deve ser usado de forma compartilhada para a 
transferência de dados e instruções entre os diversos blocos. O fato de instruções e dados utilizarem o 
mesmo caminho para serem transferidos da memória principal para a CPU inviabiliza a possibilidade de 
se explorar o paralelismo de operações para acelerar o processamento. Levando-se em conta que os 
tempos de execução das instruções que envolvem apenas operações internas à CPU são muito 
menores do que o tempo necessário para transferências entre memória e CPU, caso fosse possível 
carregar instruções e dados ao mesmo tempo, o computador como um todo ficaria mais veloz. Porém, 
com um único barramento, isso é impossível. Este problema é comumente referido como o “gargalo” do 
modelo de von Neumann (von Neumann’s bottleneck). 
Já a arquitetura Harvard possui um barramento para dados e outro para o programa, com 
tamanhos diferenciados, sendo o barramento de programa maior que o de dados. Com um barramento 
de programa maior, o opcode se torna maior, permitindo que em uma única palavra esteja contida a 
instrução e o operando. Com isso, consegue-se um opcode compacto e que pode ser executado em alta 
velocidade. Com barramentos diferenciados, elimina-se o gargalo da arquitetura de von Neumann e 
pode-se aumentar a eficiência de esquemas como o pipeline, aumentando a velocidade do sistema. 
 
A tecnologia RISC faz uso de um conjunto de instruções pequeno e simples, possibilitando que a 
CPU decodifique o código das instruções utilizando apenas circuitos lógicos, sem o uso de microcódigo. 
Dessa forma, obtém-se uma CPU mais otimizada que as contidas em processadores CISC. 
Os processadores CISC (Complex Instruction Set Computer ou computador com conjunto de 
instruções complexas) usam comandos que necessitam de vários passos para serem executados. São 
bastante versáteis e permitem que programas complexos sejam mais facilmente elaborados do que em 
um processador RISC. 
 
2. Família PIC 
 
É uma linha de processadores bastante robusta. O alto desempenho da família de 
microcontroladores PIC pode ser atribuído às seguintes características de sua arquitetura: 
 
- Arquitetura Harvard 
- Conceito de registrador arquivo 
- Todas as instruções com palavras simples 
- LWI - Long Word Instruction , ou seja, Instrução com Palavra Longa 
- Arquitetura de instruções em pipeline 
- Instruções de apenas um ciclo de máquina (com algumas exceções) 
- Conjunto de instruções reduzido (RISC) 
 
Dentre as características da família, podemos destacar: 
 
- Família bastante extensa 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 2 de 13 
- Tipos e características da memória de programa: 
 ROM (PIC16CRXXX) 
 EPROM e OTP (PIC16CXXX) 
 FLASH (PIC16FXXX) 
 Tamanho: de 512 bytes (interna) a 64 Kbytes (externa) 
 Tamanho da instrução: 12, 14 e 16 bits 
 Proteção do código (memória de programa) 
- Memória de dados do tipo RAM: 
 Tamanho: desde 16 bytes (interna) até 128 Kbytes (externa) 
- Quantidade de Pinos: variando de 6 a 84 pinos 
- Número de Portas de E/S: de 4 a 80 portas 
- Velocidade de operação: desde alguns KHz até um máximo de 48 MHz 
- Ciclo de máquina: CM = 4 / FOSC , onde FOSC = FCRISTAL 
- Intervalo de Tensão de Operação 
 Standard: 4,5 V a 6,0 V 
 Extended: 2,5 V a 6, 0 V 
- 6 sub-famílias: PIC10xxx, PIC12xxx, PIC14xxx, PIC16xxx, PIC17xxx e PIC18xxx 
- Baixo consumo de corrente: tipicamente 2 mA em operações a 4 MHz 
- Enorme quantidade de periféricos: temporizadores / contadores, conversores A/D, PWM, I2C, 
interface serial, comparadores, memória EEPROM, Watch-dog, interface USB 
 
O curso terá como base o PIC16F628A, que é um bom modelo de PIC para iniciar os estudos 
dessa grande família de microcontroladores da Microchip. Ele possui vários periféricos que podem ser 
explorados para se construir sistemas com razoável complexidade. Além disso, é fácil de ser entendido e 
programado. Outro detalhe é que o seu conjunto (set) de instruções praticamente não muda em relação 
a outros processadores PIC. Assim, entendendo o PIC16F628A, será possível migrar para qualquer 
outro componente dessa família, bastando ler o datasheet. 
 
2.1. Características básicas do microcontrolador PIC16F628A: 
 
- Pertence à família intermediária (“Mid Range”) 
- CPU de 8 bits com um conjunto de 35 instruções 
 100% de uma só palavra  código reduzido (todas as instruções ocupam uma única 
posição de memória) 
 100% com tamanho de 14 bits  uniformidade 
 instruções para manipulação de bits na RAM interna 
 quase todas as instruções executadas em apenas 1 ciclo  velocidade (exceto as 
instruções de desvio que são executadas em 2 ciclos) 
 Endereçamentos imediato, direto e indireto 
- Freqüência máxima de operação: 20 MHz com cristal externo 
- Várias opções para o oscilador externo: RC, ressonador cerâmico, cristal 
- Oscilador interno preciso de 4 MHz  1% 
- Tensão de operação de 2 a 5,5 volts 
- Mem. de programa Flash de 2K x 14 bits (2048 instruções) 
- 224 bytes de RAM interna de dados (8 bits) 
- 128 bytes de EEPROM interna de dados 
- Alta durabilidade da Flash/EEPROM 
 100.000 ciclos de escrita na Flash 
 1.000.000 de ciclos de escrita na EEPROM 
 40 anos de retenção dos dados 
- 2 Temporizadores de 8 bits e 1 de 16 bits 
- Até 16 portas bidirecionais de 8 bits com o uso do oscilador e reset internos 
- Resistores internos de pull-up na porta B 
- Interface serial (USART) 
- PWM de 10 bits 
- Comparadores internos 
- Diversas fontes de interrupções: 
 Pino RB0 / INT 
 Em caso de transição (portas RB4 a RB7) 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 3 de 13 
 Overflow do Temporizadores (transição FF  00) 
 Fim de escrita na EEPROM 
 Dado enviado ou recebido da interface serial 
- Pilha com 8 níveis de profundidade (por hardware) 
- Modo de economia de energia (SLEEP) 
- Temporizador Watch-Dog (WDT) 
- Proteção do código 
- Programação serial In-circuit 
 
2.1.1. Pinagem do microcontrolador PIC16F628A: 
 
 2 tipos de encapsulamento muito utilizados (18 pinos): 
- PDIP: plastic dual in pack 
- SOIC: small outline integrated circuit 
 Pode ser encontrado também nos encapsulamento SSOP (20 pinos) e QFN (28 pinos) 
 Porta A: porta de entrada e saída bidirecional (não simultânea) de 8 bits, RA0 a RA7, sem resistores 
de pull-up internos. Pode receber e fornecer até 25 mA por pino. 
 Porta B: porta de entrada e saída bidirecional (não simultânea) de 8 bits, RB0 a RB7, com resistores 
de pull-up internos configuráveis. Pode receber e fornecer até 25 mA por pino. 
 
2.1.2. Função de cada pino: 
 
Número 
do pino 
Nome Função 
1 RA2 / AN2 / VREF Pino com função compartilhada: pode operar como o bit 2 de E/S da 
porta A, como entrada analógica 2 dos comparadores e como saídada tensão de referência VREF. 
2 RA3 / AN3 / CMP1 Pino com função compartilhada: pode operar como o bit 3 de E/S da 
porta A, como entrada analógica 3 dos comparadores e como saída 
do comparador interno 1. 
3 RA4 / T0CKI / CMP2 Pino com função compartilhada: pode operar como o bit 4 de E/S da 
porta A (saída em coletor aberto), como entrada de clock do 
temporizador 0 em operações no modo contador e como saída do 
comparador interno 2 (coletor aberto). 
4 RA5 / MCLR / Vpp Pino com função compartilhada: pode operar como o bit 5 da porta 
A apenas como entrada, como entrada de reset do processador 
(Master Clear) ativa em nível baixo e como entrada da tensão de 
programação nas operações de gravação do processador. 
5 Vss Negativo da fonte de alimentação. 
6 RB0 / INT Pino com função compartilhada: pode operar como o bit 0 de E/S da 
porta B e como entrada da interrupção externa. 
7 RB1 / RX / DT Pino com função compartilhada: pode operar como o bit 1 de E/S da 
porta B, como entrada RX da interface serial assíncrona e como 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 4 de 13 
dado na interface síncrona. 
8 RB2 / TX / CK Pino com função compartilhada: pode operar como o bit 2 de E/S da 
porta B, como saída TX da interface serial assíncrona e como clock 
na interface síncrona. 
9 RB3 / CCP1 Pino com função compartilhada: pode operar como o bit 3 de E/S da 
porta B e como E/S do módulo de captura, comparação e PWM. 
10 RB4 / PGM Pino com função compartilhada: pode operar como o bit 4 de E/S da 
porta B e como entrada de programação de baixa tensão. 
11 RB5 Bit 5 de E/S da porta B. 
12 RB6 / T1OSO / T1CKI 
/ PGC 
Pino com função compartilhada: pode operar como o bit 6 de E/S da 
porta B, como saída do oscilador do temporizador 1, como entrada 
de clock do temporizador 1 em operações no modo contador e 
como clock nas programações In-circuit. 
13 RB7 / T1OSI / PGD Pino com função compartilhada: pode operar como o bit 7 de E/S da 
porta B, como entrada do oscilador do temporizador 1 como dado 
nas programações In-circuit. 
14 VDD Positivo da fonte de alimentação. 
15 RA6 / OSC2 / 
CLKOUT 
Pino com função compartilhada: pode operar como o bit 6 de E/S da 
porta A e como saída do cristal oscilador. No modo RC este pino é a 
saída do CLKOUT, que é ¼ da freqüência de OSC1 e representa o 
ciclo de máquina do processador. 
16 RA7 / OSC1 / CLKIN Pino com função compartilhada: pode operar como o bit 7 de E/S da 
porta A e como entrada do cristal oscilador. Se for usado um relógio 
(clock) externo, serve como entrada para esse sinal. 
17 RA0 / AN0 Pino com função compartilhada: pode operar como o bit 0 de E/S da 
porta A e como entrada analógica 0 dos comparadores. 
18 RA1 / AN1 Pino com função compartilhada: pode operar como o bit 1 de E/S da 
porta A e como entrada analógica 1 dos comparadores. 
 
- Obs.: a função de cada pino é selecionada a partir de valores colocados nos registradores de 
configuração (SFR) do PIC na inicialização do sistema. Algumas dessas funções podem ser 
selecionadas no instante da gravação do processador. 
 
2.1.3. Ciclo de máquina: 
 
 Conforme visto anteriormente, o ciclo de máquina é uma métrica para definirmos o tempo gasto 
na execução de uma determinada instrução. Dessa forma, conhecer o valor do ciclo de máquina de um 
processador é essencial para uma boa programação e desenvolvimento do sistema. 
 O PIC possui um circuito oscilador no qual basta-se conectar um cristal externo ou um 
ressonador cerâmico para que sua freqüência de operação seja definida. Pode ser feito uso também do 
oscilador interno que define um freqüência de operação de 4 MHz. 
Durante sua operação, o PIC divide a freqüência do oscilador por 4 para poder realizar as 
operações de busca, decodificação e execução da instrução, que definem o tempo total de execução da 
instrução. Dessa forma, o ciclo de máquina do PIC é o período dessa freqüência interna. 
Assim, o ciclo de máquina do PIC é calculado da seguinte forma: CM = 4 / FOSC ou 4 / FCRISTAL. 
 
3. Conjunto de instruções do microcontrolador PIC16F628A 
 
3.1. Formato das instruções: 
 
Mnemônico Operando1,Operando2 
 
Ex.: ANDWF f,d , onde ANDWF é o Mnemônico da instrução, f é o Operando1 e d o Operando2 
 
3.2. Convenções para os operandos: 
 
 W = Working register ou o acumulador do PIC. 
 f = File register, indica uma posição (endereço) da memória RAM do PIC. Os registradores 
especiais (SFR) estão mapeados na RAM. 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 5 de 13 
 b = Bit address, indica a posição de um bit dentro do byte. Como o byte possui 8 bits, b só pode 
assumir valores de 0 a 7. 
 k = Constant, uma constante a ser utilizada em uma operação lógica ou aritmética. Como o PIC é 
um processador de 8 bits, o valor máximo de k é FFH (255 em decimal). 
 d = Destiny, indica onde o resultado de uma operação lógica ou aritmética será colocado e só pode 
assumir dois valores: 0 ou 1. Se d for igual a zero o destino será o registrador W, caso contrário, o 
destino será a posição da memória RAM (file register) que está sendo acessada pela instrução. Se d 
for omitido, o compilador assumirá que o destino é a memória RAM. Ao invés de 0 e 1, comumente 
utiliza-se W e F para indicar o destino do resultado. 
 end = indica um endereço da memória de programa para onde o fluxo será desviado. Em um 
programa em Assembly será normalmente representado por um label. 
 
3.3. Conjunto de instruções do PIC16F628A: 
 
3.3.1. Instruções de acesso à memória RAM (file registers) orientadas a byte: 
 
Instrução 
 
Descrição Opcode 
(14 bits) 
Ciclos 
de 
Máquina 
Flags 
afetadas 
ADDWF f,d Soma o valor do reg. W com o conteúdo da posição de memória 
indicada por f, com o resultado colocado em d 
00 0111 dfff ffff 1 C, DC, Z 
ANDWF f,d Efetua a operação AND entre o valor do reg. W e a posição de 
memória indicada por f, com o resultado colocado em d 
00 0101 dfff ffff 1 Z 
CLRF f Zera o conteúdo da posição de memória indicada por f 00 0001 1fff ffff 1 Z 
CLRW Zera o valor do registrador W, ou seja, faz W = 0 00 0001 0xxx xxxx 1 Z 
COMF f,d Complementa (inverte o valor dos bits) o conteúdo da posição de 
memória indicada por f, com o resultado colocado em d 
00 1001 dfff ffff 1 Z 
DECF f,d Decrementa (subtrai 1) o conteúdo da posição de memória 
indicada por f, com o resultado colocado em d 
00 0011 dfff ffff 1 Z 
DECFSZ f,d Decrementa (subtrai 1) o conteúdo da posição de memória 
indicada por f, com o resultado colocado em d, e ignora a 
próxima instrução (skip) se o resultado for igual a zero 
00 1011 dfff ffff 1 (2) * 
INCF f,d Incrementa (soma 1) o conteúdo da posição de memória indicada 
por f, com o resultado colocado em d 
00 1010 dfff ffff 1 Z 
INCFSZ f,d Incrementa (soma 1) o conteúdo da posição de memória indicada 
por f, com o resultado colocado em d, e ignora a próxima 
instrução (skip) se o resultado for igual a zero 
00 1111 dfff ffff 1 (2) * 
IORWF f,d Efetua a operação OR entre o valor do reg. W e a posição de 
memória indicada por f, com o resultado colocado em d 
00 0100 dfff ffff 1 Z 
MOVF f,d Move o conteúdo da posição de memória indicada por f para o 
destino indicado por d 
00 1000 dfff ffff 1 Z 
MOVWF f Move o conteúdo do registrador W para a posição de memória 
indicada por f 
00 0000 1fff ffff 1 
NOP Não faz nada (no operation) 00 0000 0xx0 0000 1 
RLF f,d Rotaciona à esquerda (rotate left), juntamente com a flag carry 
(C), o conteúdo da posição de memória indicada por f, com o 
resultado colocado em d 
00 1101 dfff ffff 1 C 
RRF f,d Rotaciona à direita (rotate right), juntamente com a flag carry (C), 
o conteúdo da posição de memória indicada por f, com o 
resultado colocado em d 
00 1100 dfff ffff 1C 
SUBWF f,d ** Subtrai o valor do reg. W do conteúdo da posição de memória 
indicada por f (f – W), com o resultado colocado em d 
00 0010 dfff ffff 1 C, DC, Z 
SWAPF f,d Troca (swap) os nibbles do conteúdo da posição de memória 
indicada por f, com o resultado colocado em d 
00 1110 dfff ffff 1 
XORWF f,d Efetua a operação Exclusive OR (XOR) entre o valor do reg. W e a 
posição de memória indicada por f, com o resultado colocado em 
d 
00 0110 dfff ffff 1 Z 
 
3.3.2. Instruções de acesso à memória RAM (file registers) orientadas a bit: 
 
Instrução 
 
Descrição Opcode 
(14 bits) 
Ciclos 
de 
Máquina 
Flags 
afetadas 
BCF f,b Coloca em zero (clear) o bit indicado pelo conjunto f (posição de 
memória) e b (posição do bit) 
01 00bb bfff ffff 1 
BSF f,b Coloca em 1 (set) o bit indicado pelo conjunto f (posição de 
memória) e b (posição do bit) 
01 01bb bfff ffff 1 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 6 de 13 
BTFSC f,b Testa se o bit indicado pelo conjunto f (posição de memória) e b 
(posição do bit) é igual a 0 (zero) e, se for, ignora a próxima 
instrução (skip) 
01 10bb bfff ffff 1 (2) * 
BTFSS f,b Testa se o bit indicado pelo conjunto f (posição de memória) e b 
(posição do bit) é igual a 1 (um) e, se for, ignora a próxima 
instrução (skip) 
01 11bb bfff ffff 1 (2) * 
 
3.3.3. Instruções de controle e que utilizam constantes: 
 
Instrução 
 
Descrição Opcode 
(14 bits) 
Ciclos 
de 
Máquina 
Flags 
afetadas 
ADDLW k Soma o valor do reg. W com a constante (literal) k, com o 
resultado armazenado em W 
11 111x kkkk kkkk 1 C, DC, Z 
ANDLW k Efetua a operação AND entre o valor do reg. W e a constante 
(literal) k, com o resultado armazenado em W 
11 1001 kkkk kkkk 1 Z 
CALL end Chama a subrotina endereçada (apontada) por end 10 0kkk kkkk kkkk 2 
CLRWDT Zera o valor do temporizador WatchDog 00 0000 0110 0100 1 TO, PD 
GOTO end Desvia incondicionalmente o fluxo do programa para o endereço 
end 
10 1kkk kkkk kkkk 2 
IORLW k Efetua a operação OR entre o valor do reg. W e a constante 
(literal) k, com o resultado armazenado em W 
11 1000 kkkk kkkk 1 Z 
MOVLW k Move a constante k para o registrador W, ou seja, faz W = k 11 00xx kkkk kkkk 1 
RETFIE Retorna de uma rotina de tratamento de interrupção 00 0000 0000 1001 2 
RETLW k Retorna de uma subrotina carregando (movendo) uma constante 
k para o registrador W 
11 01xx kkkk kkkk 2 
RETURN Retorna de uma subrotina sem alterar o conteúdo do registrador W 00 0000 0000 1000 2 
SLEEP Coloca o PIC em um modo de “repouso” (sleep), ou seja, de 
baixo consumo 
00 0000 0110 0011 1 TO, PD 
SUBLW k ** Subtrai o valor do reg. W da constante (literal) k, com o resultado 
armazenado em W (W = k – W) 
11 110x kkkk kkkk 1 C, DC, Z 
XORLW k Efetua a operação Exclusive OR (XOR) entre o valor do reg. W e a 
constante k, com o resultado armazenado em W 
11 1010 kkkk kkkk 1 Z 
 
* Estas instruções gastam um ciclo se o teste for falso e dois ciclos se o teste for verdadeiro 
** Se o resultado é positivo, C = 1. Se o resultado é negativo, C = 0. 
 
3.4. Exemplos: 
 
Trecho de programa Comentários 
MOVLW 35 Carrega o registrador W com o valor (constante) 35H 
 MOVWF 21 Transfere o conteúdo de W para a posição 21H da RAM 
 MOVF 20,W Pega o conteúdo da posição 20H da RAM e coloca em W 
 ADDWF 21,F Soma o conteúdo de W com o conteúdo da posição 21H e coloca o 
resultado na posição 21H 
 BTFSS STATUS,C Testa se a flag de carry foi “setada” na operação anterior 
 GOTO POS1 Se não foi (C = 0), desvia para o endereço POS1 
 MOVLW 5 Se foi (C = 1), carrega W com o valor 05H 
POS1: MOVWF 22 Transfere o conteúdo de W para a posição de memória 22H 
 
Obs.: 1 - Note que o compilador opera, por default, com valores em hexadecimal. Se, na primeira linha do programa 
exemplo, quiséssemos que o valor (constante) a ser carregado no registrador W fosse 35 em decimal, um ponto 
deveria ser colocado antes do número para indicar essa condição (MOVLW .35) . 
2 - Para indicar o conteúdo de uma posição de memória será utilizada a notação [ ]. Assim, de acordo 
com a figura abaixo, [32H] = F8H e [35H] = 1AH. 
 
 MOVLW 06H ; W = 06H 
 ADDWF 33H,W ; W = 2BH e [33H] = 25H 
 MOVWF 35H ; [35H] = 2AH 
 
 
 MOVLW 06H ; W = 06H 
 ADDWF 33H,F ; W = 06H e [33H] = 2BH 
 MOVWF 35H ; [35H] = 06H 
 
 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 7 de 13 
3.5. Registradores do PIC: 
 
 Para desenvolvimento de aplicativos, o microcontrolador PIC16F628A 
possui um único registrador acessível dentro de sua CPU, o registrador W 
(work register). Assim, algumas operações, como uso de constantes ou 
transferência de valores entre registradores, só poderão ser realizadas por 
intermédio desse registrador W. 
Os demais registradores que o PIC utiliza são definidos dentro de sua 
memória RAM. Dessa forma, o PIC irá reservar uma parte dessa memória 
(endereços iniciais) para seu uso. Esses registradores “especiais” são 
chamados de SFRs (Special Function Register) e indicam ao PIC como ele 
deve operar, sendo essenciais ao funcionamento do sistema. 
 Os programas desenvolvidos também podem definir seus próprios registradores (ou variáveis) 
na memória RAM, desde que não utilizem a região reservada. 
 Essa arquitetura permite que tanto o acesso aos registradores especiais do PIC (que ocupam 
uma região reservada da memória RAM), quanto o acesso aos registradores definidos no programa, 
sejam feitos da mesma forma, utilizando as mesmas instruções. Essa abordagem simplifica a estrutura 
interna do PIC como também facilita a programação. 
 
3.6. Tipos de endereçamento no PIC: 
 
3.6.1. Imediato: uma constante é carregada no registrador W. No PIC, apenas o registrador W pode ser 
usado nesse tipo de endereçamento. Exemplos: MOVLW 25H, ADDLW 37H, XORLW F7H. 
 
3.6.2. Direto: fazem referência explícita a uma determinada posição ou endereço da memória RAM. 
Exemplos: CLRF 25H ; MOVWF 1FH ; ADDWF 37H,W ; RLF 42H,F . 
 
3.6.3. Indireto: fazem uso de um ponteiro para indicar a posição ou endereço da memória RAM a ser 
acessada. No PIC, o endereçamento indireto utiliza os registradores especiais FSR e INDF. O 
registrador FSR atua como um ponteiro e a referência à memória (acesso indireto) é feita por intermédio 
do registrador INDF. 
 
Se a memória RAM estiver com os dados de acordo com a figura ao lado, 
temos: 
 
 Imediato: MOVLW 23H (W = 23H) 
 Direto: MOVF 23H,W (W = 45H) 
 Indireto: MOVLW 24H (W = 24H) 
MOVWF FSR (FSR = 24H) 
 MOVF INDF,W (W = 57H) 
 
4. Mapa das memórias de programa e dados do PIC 
 
4.1. Mapa da memória de programa do PIC16F628A: 
 
000H Reset 0 
 
004H Interrupções 4 
 
 
 
 Programa 
 
 
7FFH 2047 
 
- A memória de programa possui um tamanho de 2.048 bytes, ou seja, 2Kbytes. 
- Todo programa inicia a partir do endereço 000H quando o processador é ligado (reset) 
- Quando ocorre uma interrupção, o fluxo do programa é desviado para o endereço 004H 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 8 de 13 
4.2. Mapa da memória de dados (RAM) do PIC16F628A: 
 
000H INDF 080H INDF 100H INDF 180H INDF 
001H TMR0 081H OPTION_REG 101H TMR0 181H OPTION_REG 
002H PCL 082H PCL 102H PCL 182H PCL 
003H STATUS 083H STATUS 103H STATUS 183H STATUS 
004H FSR 084H FSR 104H FSR 184H FSR 
005H PORTA 085H TRISA 105H 185H 
006H PORTB 086H TRISB 106H PORTB 186H TRISB 
007H 087H 107H 187H 
008H 088H 108H 188H 
009H 089H 109H 189H 
00AH PCLATH 08AH PCLATH 10AH PCLATH 18AH PCLATH 
00BH INTCON 08BH INTCON 10BH INTCON 18BH INTCON 
00CH PIR1 08CH PIE1 10CH 18CH 
00DH 08DH 10DH 18DH 
00EH TMR1L 08EH PCON 10EH18EH 
00FH TMR1H 08FH 10FH 18FH 
010H T1CON 090H 110H 190H 
011H TMR2 091H 111H 191H 
012H T2CON 092H PR2 112H 192H 
013H 093H 113H 193H 
014H 094H 114H 194H 
015H CCPR1L 095H 115H 195H 
016H CCPR1H 096H 116H 196H 
017H CCP1CON 097H 117H 197H 
018H RCSTA 098H TXSTA 118H 198H 
019H TXREG 099H SPBRG 119H 199H 
01AH RCREG 09AH EEDATA 11AH 19AH 
01BH 09BH EEADR 11BH 19BH 
01CH 09CH EECON1 11CH 19CH 
01DH 09DH EECON2 11DH 19DH 
01EH 09EH 11EH 19EH 
01FH CMCON 09FH VRCON 11FH 19FH 
020H 0A0H 120H 1A0H 
 48 bytes 
 80 bytes 80 bytes Uso Geral 
 Uso Geral Uso Geral 14FH 
 150H 
 
06FH 0EFH 16FH 1EFH 
070H 0F0H 170H 1F0H 
 16 bytes Acessa Acessa Acessa 
 Uso Geral 070H - 07FH 070H - 07FH 070H - 07FH 
07FH 0FFH 17FH 1FFH 
 
 Banco 0 Banco 1 Banco 2 Banco 3 
 
 A memória de dados do PIC está dividida em 4 bancos: Banco 0, Banco 1, Banco 2 e Banco 3. 
 Para mudar de banco de memória, são utilizados os bits RP0 e RP1 do registrador STATUS. 
 As primeiras 32 posições do Banco 0 (de 000H a 01FH), do Banco 1 (de 080H a 09FH), do Banco 2 
(de 100H a 11FH) e do Banco 3 (de 180H a 19FH) são reservadas para os registradores com 
funções especiais (SFRs) para o funcionamento do PIC e não podem ser utilizadas para outro 
propósito. 
 Alguns registradores SFRs são acessados nos quatro bancos (INDF, PCL, STATUS, FSR, INTCON) 
e outros só existem em um dos bancos. 
 Os 80 bytes da memória RAM que vão dos endereços 020H a 06FH do Banco 0, bem como os 80 
bytes que vão dos endereços 0A0H a 0EFH do Banco 1 e os 48 bytes que vão dos endereços 120H 
a 14FH do Banco 2, totalizando 208 bytes, são de uso geral dos programas e podem armazenar 
quaisquer dados. Os endereços que vão de 150H a 16FH do Banco 2 e 1A0H a 1EFH do Banco 3 
não podem armazenar valores e em qualquer acesso de leitura é lido 0. 
 Os 16 bytes de RAM que vão dos endereços 070H a 07FH do Banco 0 são de uso geral dos 
programas e podem armazenar quaisquer dados. Se os endereços 0F0H a 0FFH do Banco 1 forem 
acessados, esses acessos serão mapeados para o Banco 0. O mesmo ocorre para os endereços 
170H a 17FH do Banco 2 e para os endereços 1F0H a 1FFH do Banco 3. 
 Dessa forma, o PIC16F628A possui um total de 224 bytes de RAM de uso geral para os programas. 
 
 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 9 de 13 
4.3. Bits do registrador especial (SFR) STATUS: 
 
Legenda: R (read): o bit pode ser lido pelo processador 
 W (write): o bit pode ser modificado pelo programa em execução no processador 
 – : bit sem função (flag não implementada), lido com o valor 0 
 1 : o bit é colocado em nível lógico alto (1) no POR (power-on reset) 
 0 : o bit é colocado em nível lógico baixo (0) no POR 
 x : o valor do bit é desconhecido no POR 
 
 
R/W - 0 R/W - 0 R/W - 0 R - 1 R - 1 R/W - x R/W - x R/W - x 
IRP RP1 RP0 TO PD Z DC C 
bit 7 bit 0 
 
 
 IRP (bit 7): Indirect Register Page ou bit de seleção do banco nos acessos indiretos à memória 
 
0 : Acesso aos bancos 0 e 1 (de 000H a 0FFH) 
1 : Acesso aos bancos 2 e 3 (de 100H a 1FFH) 
 
 RP1 e RP0 (bits 6 e 5): Register Bank Select bits ou bits de seleção do banco de registradores 
 
RP1 RP0 Banco 
0 0 0 (de 000H a 07FH) 
0 1 1 (de 080H a 0FFH) 
1 0 2 (de 100H a 17FH) 
1 1 3 (de 180H a 1FFH) 
 
 TO (bit 4): Time out bit ou tempo esgotado 
 
1 : Após um POR (power-on reset), uma instrução CLRWDT ou uma instrução SLEEP 
0 : Quando ocorrer um estouro do tempo do temporizador Watch-dog 
 
 PD (bit 3): Power down bit ou modo de economia de energia 
 
1 : Após um POR ou uma instrução CLRWDT 
0 : Após a execução de uma instrução SLEEP 
 
 Z (bit 2): Zero flag 
 
1 : O resultado de uma operação lógica ou aritmética foi zero 
0 : O resultado de uma operação lógica ou aritmética não foi zero 
 
 DC (bit 1): Digit carry flag 
 
1 : Ocorreu um “vai um” do bit 3 para o bit 4 
0 : Não ocorreu um “vai um” do bit 3 para o bit 4 
 
 C (bit 0): Carry flag 
 
1 : Ocorreu um “vai um” do MSB (most significant bit ou bit 7) do resultado da operação 
0 : Não ocorreu um “vai um” do MSB (most significant bit ou bit 7) do resultado da operação 
 
- Obs.: para as operações de subtração, a polaridade da flag C é invertida. Isso ocorre porque a 
subtração é feita por intermédio de uma soma com o segundo operando em complemento de 2. Assim, 
se o resultado da subtração for positivo, a flag C = 1, sendo igual a zero, caso contrário. A flag carry 
também é afetada pelas instruções RLF e RRF. 
 
 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 10 de 13 
5. Operações básicas em Assembly: 
 
5.1. Colocar uma constante em uma posição de memória: 
 
MOVLW 5AH ; Carrega W com a constante (no caso, 5AH) 
MOVWF 20H ; Coloca o valor de W na posição de memória 20H 
 
5.2. Mover o valor (conteúdo) de uma posição de memória para outra: 
 
MOVF 25H,W ; Carrega W com o conteúdo da posição de memória 25H 
MOVWF 20H ; Coloca o valor de W na posição de memória 20H 
 
5.3. Teste para ver se uma posição de memória contém 0: 
 
MOVF DADO,F ; Se a posição DADO contiver 0, flag Z = 1 
BTFSS STATUS,Z ; Testa a flag Z 
GOTO DIF_ZERO ; Posição DADO não contém 0, fluxo é desviado 
... ; Esse trecho de programa será executado se DADO = 0 
 
O teste poderia ter sido BTFSC STATUS,C. Nesse caso, o programa seria desviado se a posição 
DADO contivesse 0. 
 
5.4. Teste para ver se uma posição de memória contém um determinado valor: 
 
MOVLW 5AH ; Carrega valor a ser testado (no caso, 5AH) 
XORWF DADO,W ; Se DADO = 5AH, flag Z = 1 e DADO não é afetado 
BTFSS STATUS,Z ; Testa a flag Z 
GOTO DIFERENTE ; Posição DADO não contém 5AH, fluxo é desviado 
... ; Esse trecho de programa será executado se DADO = 5AH 
 
Novamente, o teste poderia ter sido BTFSC STATUS,C. Nesse caso, o programa seria desviado 
se a posição DADO contivesse 5AH. 
 
5.5. Teste para ver se uma posição de memória é >, <, >= ou <= que um determinado valor: 
 
Lembrando que se fizermos a operação A – B em um programa escrito em assembly do PIC, 
essa conta utilizará a representação em complemento de 2. Com isso, os possíveis resultados são: 
 Se A > B, resultado é positivo, flag C = 1 e flag Z = 0; 
 Se A = B, resultado é positivo, flag C = 1 e flag Z = 1; 
 Se A < B, resultado é negativo, flag C = 0 e flag Z = 0. 
Após efetuar a subtração, a flag C deverá ser testada para que a decisão seja tomada. Nos 
testes de > e <, verifica-se se a flag C = 0 e nos testes de >= ou <=, verifica-se se a flag C = 1. 
Nas instruções de subtração, o registrador W é sempre o subtraendo. Nesse tipo de teste, a 
ordem da operação é bastante importante. Existem duas formas possíveis de efetuar a subtração entre 
uma posição de memória e uma constante: 
 
MOVLW 5AH ; Carrega valor a ser testado (no caso, 5AH) 
SUBWF DADO,W ; W = DADO – 5AH (se DADO >= 5AH, C=1. Se DADO < 5AH, C=0) 
 
MOVF DADO,W ; W = DADO 
SUBLW 5AH ; W = 5AH – DADO (se DADO <= 5AH, C=1. Se DADO > 5AH, C=0) 
 
5.6. Multiplicação por 2: 
 
BCF STATUS,C ; Garante flag C = 0 
RLF DADO,F ; Desloca DADO uma posição à esquerda (DADO = DADO x 2) 
 
5.7. Divisão por 2: 
 
BCF STATUS,C ; Garante flag C = 0 
RRF DADO,F ; Desloca DADO uma posição à direita (DADO = DADO  2) 
 
 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 11 de 13 
5.8. Multiplicação por uma constante: 
 
Pega-se a constante e a mesma deve ser “desmembrada” em potências de 2. Por exemplo, 10 x 
A = (8 + 2) x A = 8 x A + 2 x A. Lembrando que 8 = 23 e 2 = 21, cada multiplicação por 2 é efetuada com 
uma rotaçãoà esquerda. Assim, para multiplicarmos por 8 são necessárias 3 rotações à esquerda. 
 
BCF STATUS,C ; Garante flag C = 0 
RLF DADO,F ; Desloca DADO uma posição à esquerda (DADO = 2 x DADO) 
MOVF DADO,W ; W = 2 x DADO 
RLF DADO,F ; DADO = 4 x DADO 
RLF DADO,F ; DADO = 8 x DADO 
ADDWF DADO,F ; DADO = 2 x DADO + 8 x DADO, ou seja, DADO = 10 x DADO 
 
5.9. Laços de repetição: 
 
Muitas vezes, um determinado trecho de código deve ser repetido várias vezes. Quando isso é 
necessário, os laços de repetição devem ser usados. 
 
MOVLW 5 ; Carrega quantidade de vezes da repetição (no caso, 5) 
MOVWF CONTA ; Transfere quantidade para o contador de repetições 
REPETE: 
 ... ; Trecho de programa que será repetido (5 vezes no caso) 
 DECFSZ CONTA,F ; Decrementa (subtrai 1) contador e testa se igual a zero 
 GOTO REPETE ; Se contador ainda não é zero, volta e repete código 
 ... ; Quando o contador atingir 0, o programa seguirá adiante 
 
5.10. Operações lógicas com “máscaras”: 
 
Máscaras são constantes utilizadas em operações lógicas com a intenção de alterar 
determinados bits de um byte, sem afetar os demais. Lembre-se que toda a operação lógica afeta a flag 
Z, embora não seja esse o objetivo. A operação AND serve para zerar determinados bits, a operação OR 
serve para setar determinados bits e a operação XOR serve para inverter determinados bits: 
 
MOVLW B’01001101’ ; Máscara para operação AND 
ANDWF DADO,F ; Zera os bits B1, B4, B5 e B7 da posição DADO 
 
MOVLW B’10010110’ ; Máscara para operação OR 
IORWF DADO,F ; Seta os bits B1, B2, B4 e B7 da posição DADO 
 
MOVLW B’01010001’ ; Máscara para operação XOR 
XORWF DADO,F ; Inverte os bits B0, B4, e B6 da posição DADO 
 
6. Laços (loop) de tempo 
 
Os microcontroladores PIC, assim como os processadores em geral, são dispositivos bastante 
rápidos. Muitas vezes, durante a execução dos programas, essa velocidade pode prejudicar o bom 
funcionamento do sistema. Se colocarmos um led para piscar na velocidade de processamento do PIC, 
ele piscará tão rápido que teremos a sensação que ele está apenas aceso e não piscando. 
O laço de tempo serve basicamente para que o microcontrolador aguarde um tempo desejado 
antes de voltar ao processamento normal dos sinais e informações. È composto de um contador e um 
pequeno trecho de programa que não faz “nada” e que será repetido tantas vezes quantas forem o valor 
do contador. Em geral, o pequeno trecho de programa é constituído de uma ou mais instruções NOP (no 
operation) e instruções para decrementar o contador e verificar se o mesmo já chegou a zero. O valor a 
ser carregado no contador depende do tempo que se deseja manter o processador “ocioso” e é 
calculado baseado na quantidade de ciclos de máquina que o pequeno trecho de programa gasta em 
cada execução. 
Um laço de tempo padrão pode ser escrito da seguinte forma: 
 
MOVLW .200 ; Carrega valor inicial do contador 1CM 
MOVWF CONTADOR 1CM 
LOOP: NOP 1CM x 200 
 DECFSZ CONTADOR,F ; Decrementa contador 1CM x 199 + 2CM 
 GOTO LOOP ; Se não for zero, prossegue no laço 1CM x 199 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 12 de 13 
 
 Nessa estrutura genérica, vemos que as duas primeiras instruções são executadas apenas uma 
vez durante o laço e cada uma delas gasta 1 ciclo de máquina (CM). A instrução NOP gasta 1 CM e é 
executada a quantidade de vezes definida para o contador. Já a instrução DECFSZ também é executada 
a quantidade de vezes definida para o contador, só que ela gasta 1CM enquanto o contador é diferente 
de 0 e na última passada, quando o valor do contador atinge zero, essa instrução gasta 2 CM, já que 
ocorre um desvio na seqüência do programa. Finalmente, a instrução GOTO gasta 2 CM e é executada 
uma vez menos que o valor do contador, já que quando o contador zera, a instrução DECFSZ impede 
que a instrução GOTO seja executada. 
 Generalizando o problema, chamando de K o valor a ser carregado no contador, temos a 
seguinte situação: 
 
MOVLW K ; Carrega valor inicial do contador 1CM 
MOVWF CONTADOR 1CM 
LOOP: NOP 1CM x K 
 DECFSZ CONTADOR,F ; Decrementa contador 1CM x (K-1) + 2CM 
 GOTO LOOP ; Se não for zero, prossegue no laço 2CM x (K-1) 
 
 ... ; Segue o processamento 
 
 Efetuando o somatório desse tempo: TEMPO = 1CM + 1CM + 1CM x K + 1CM x K – 1CM + 2CM 
+ 2CM x K – 2CM  TEMPO = 4CM x K + 1CM. Regra geral, o valor de K será grande e, assim, 4CM x 
K será muito maior que 1CM. Dessa forma, podemos dizer que o tempo gasto no laço de tempo que 
segue essa estrutura padrão é dado pela seguinte “fórmula”: TEMPO  4CM x K. Resumidamente, essa 
fórmula nos diz que as instruções do laço de tempo gastam 4CM e elas são executadas K vezes. 
 Vamos supor que o PIC em questão está trabalhando com um cristal de 5 MHz. Seu ciclo de 
máquina (CM) seria de: CM = 4 / FOSC  CM = 4 / (5 x 106)  CM = 0,8 x 10–6  CM = 0,8 seg. 
No primeiro trecho de programa, no qual o valor 200 (em decimal) foi carregado no contador, 
teríamos: 4 x CM x K = 4 x 0,8 seg x 200, ou seja, um tempo gasto no laço de 640 seg. 
Supondo agora que queremos utilizar a mesma estrutura para gerar um laço de tempo que gaste 
350 seg, que valor K deveria ser carregado no contador ? 
De acordo com a análise feita, esse laço de tempo gasta 4CM executado K vezes. Temos que: 4 
x CM x K = 350 seg  K = 109,375. Como os registradores só aceitam números inteiros, o valor (K) a 
ser carregado no contador do laço de tempo seria 109. 
Alterando novamente a situação, vamos supor que o laço de tempo necessite gastar 950 seg. 
Efetuando os mesmos cálculos que no caso anterior, temos: K x 4 x CM = 950 seg  K = 296,875. 
Note agora que o valor de K é maior que 255, ou seja, supera o maior valor possível de ser carregado 
em um registrador de 8 bits. Nesse caso, podemos adicionar mais uma instrução NOP ao pequeno trecho 
de programa (laço de tempo) para que ele gaste um tempo maior. Com a adição dessa instrução, esse 
trecho passaria a gastar 5CM e nosso cálculo ficaria: 5 x CM x K = 950 seg  K = 237,5. Perceba que 
agora K está dentro da faixa permitida. 
Dessa forma, concluímos que o trecho a ser repetido não tem necessariamente uma quantidade 
fixa de instruções NOP. A estrutura padrão possui um instrução NOP e gasta 4 CM, mas ela pode ser 
alterada de acordo com a situação desejada. Para se obter tempos mais elevados, poderão ser 
necessárias várias instruções NOP no “corpo” do laço de tempo. 
Na hipótese dessa quantidade de instruções crescer muito, estruturas como laços aninhados 
devem ser utilizadas. Nessas estruturas, são utilizados dois ou mais contadores e o laço de um contador 
engloba o laço do outro contador. Supondo ainda o cristal de 5 MHZ, o pequeno trecho abaixo 
exemplifica essa situação: 
 
MOVLW .200 ; 200 repetições do laço interno: 200 x 0,5 mseg = 100 mseg 
MOVWF CONTA1 
LOOP1: MOVLW .156 ; Carrega contador do laço de tempo interno (contador 2) 
MOVWF CONTA2 
LOOP2: NOP ; 4 x CM x 156 = 499,2 useg ou aprox. 500 useg = 0,5 mseg 
 DECFSZ CONTA2,F 
 GOTO LOOP2 
 DECFSZ CONTA1,F ; Repete o laço do contador 2 enquanto contador 1 não zera 
 GOTO LOOP1 
 
 ... ; Segue o processamento 
 
IESB - Instituto de Educação Superior de Brasília 
Engenharia de Computação e Eng. de Telecomunicações 
Disciplina: Aplicações de Microprocessadores e Microcontroladores 
 
Página 13 de 13 
7. Uso de tabelas 
 
 Muitos programas precisam que códigos sejam convertidos de um formato para outro. Outros 
programas precisam que determinados cálculos sejam efetuados. A determinação do seno de um valor 
ou mesmo seu logaritmo podem ser operações bastante complexas de se realizar com um processador. 
 Para essas situações, em grande parte das vezes, a melhor solução é tabelar a conversão dos 
códigos ou o cálculo dos valores desejados. 
A estrutura básica de uma pesquisaem tabela é mostrada no código a seguir: 
 
 
MOVF VALOR,W ; Carrega W com valor a ser pesquisado na tabela 
CALL TAB ; Busca dado na tabela 
... ; Segue o processamento 
 
 
TAB: ADDWF PCL,F 
RETLW VAL1 ; Valor retornado quando W = 0 
RETLW VAL2 ; Valor retornado quando W = 1 
RETLW VAL3 ; Valor retornado quando W = 2 
RETLW VAL4 ; Valor retornado quando W = 3 
... 
 
A tabela nada mais é que uma pequena subrotina. O registrador W atua como um índice e indica 
o valor que será retornado dessa subrotina. 
 O registrador PCL é a parte menos significativa (8 bits) do ponteiro de programa (PC) que é um 
registrador composto por outros dois registradores. O PC necessita de mais de 8 bits para poder 
endereçar toda a memória de programa. 
Lembre-se que o PIC faz uso de pipeline e quando uma instrução está sendo executada, a 
instrução seguinte já está sendo buscada. Assim, durante a execução da instrução ADDWF PCL,F , o 
ponteiro de programa já está apontando para a primeira instrução RETLW. A instrução ADDWF PCL,F 
soma o conteúdo de W com o PC, colocando o resultado da soma no PC. Se o valor de W for 0, o valor 
do PC não será alterado e a primeira instrução RETLW será executada após a instrução ADDWF. Já se 
W contiver 1, o PC será “deslocado” para a segunda instrução RETLW, que será a executada após o 
ADDWF. Com W igual a 2, o PC irá apontar para a terceira instrução RETLW após a execução da soma. 
Raciocínio análogo pode ser empregado para outros valores de W. Com isso, o valor que foi carregado 
em W antes da subrotina da tabela ser chamada é que vai indicar qual o valor a ser retornado. 
Supondo que queremos calcular a “tabuada” de multiplicação do 9. Podemos montar a seguinte 
tabela: 
 
MOVF VALOR,W ; Carrega W com valor a ser pesquisado na tabela 
ANDLW 0F ; Garante que W é menor ou igual a 15 
CALL TAB_9 ; Busca dado na tabela 
... ; Segue o processamento 
 
 
TAB_9: ADDWF PCL,F 
RETLW 0 ; Se W = 0, retorna 0 x 9 = 0 
RETLW 9 ; Se W = 1, retorna 1 x 9 = 9 
RETLW .18 ; Se W = 2, retorna 2 x 9 = 18 
RETLW .27 ; Se W = 3, retorna 3 x 9 = 27 
RETLW .36 ; Se W = 4, retorna 4 x 9 = 36 
RETLW .45 ; Se W = 5, retorna 5 x 9 = 45 
RETLW .54 ; Se W = 6, retorna 6 x 9 = 54 
RETLW .63 ; Se W = 7, retorna 7 x 9 = 63 
RETLW .72 ; Se W = 8, retorna 8 x 9 = 72 
RETLW .81 ; Se W = 9, retorna 9 x 9 = 81 
RETLW .90 ; Se W = 10, retorna 10 x 9 = 90 
RETLW .99 ; Se W = 11, retorna 11 x 9 = 99 
RETLW .108 ; Se W = 12, retorna 12 x 9 = 108 
RETLW .117 ; Se W = 13, retorna 13 x 9 = 117 
RETLW .126 ; Se W = 14, retorna 14 x 9 = 126 
RETLW .135 ; Se W = 15, retorna 15 x 9 = 135

Continue navegando