Curso de Programação PIC 1/1

Curso de Programação PIC
Prof. Msc. Engº Getúlio Teruo Tateoki


Este Curso de Programação foi projetado para introduzir ao aluno na programação dos
microcontroladores PIC16F84.

Para se entender como programar um microcontrolador faz-se necessário de
contribuição de muitas fontes diferentes. Isso inclui idéias e discussões de instrutores
diferentes. Cada um oferece um ponto de vista diferente com uma terminologia para
descrever uma característica, especialmente sobre algo tão complexo quanto
programação.
Este trabalho, baseado no artigo de Jim Brown descreve muito das características do
microcontrolador PIC16F84 e ajuda a adquirir um conhecimento geral sobre este
surpreendente dispositivo.


































Curso de Programação PIC 2/2
Conteúdo:
1- Introdução
2- O que é preciso
3- O que é preciso saber
4- Arquitetura ao PIC16F84
5- Conjunto de Instruções
6- Um programa simples para o PIC16F84
7- Usando MPLAB para depurar um programa
8- O Conjunto de Instruções
Formato da Instrução
O Registrador STATUS

8.1- Instruções Move
MOVF f,d (Move f)
MOVWF f (Move W para f)
MOVLW k (Move literal para W)

8.2- Instruções Clear
CLRF f (Limpa f)
CLRW (Limpa W)

8.3- Instruções Aritméticas
ADDWF f,d (Soma W & f)
SUBWF f,d (Subtrai W de f)
ADDLW k (Soma literal e W)
SUBLW k (Subtrai W de literal)

8.4- Funções Lógicas
ANDWF f,d (E W com f)
IORWF f,d (Inclusive OU W com f)
XORWF f,d (Exclusive OU W com f)
ANDLW k (E literal com W)
IORLW k (Inclusive OU literal com W)
XORLW k (Exclusive OU literal com W)
COMF f,d (Complemento f)

8.5- Decrementando & Incrementando
DEC f,d (Decrementa f)
INC f,d (Incrementa f)

8.6- Ligando e limpando Bit
BCF f,b (Bit limpa f)
BSF f,b (Bit liga f)

8.7- Controle do Programa
GOTO k (Vai para endereço)
CALL k (Chama sub-rotina)
RETURN (Retorna de sub-rotina)
RETLW k (Retorna com literal em W)
RETFIE (Retorna de Interrupção)
Curso de Programação PIC 3/3

8.8- Instruções Skip
DECFSZ f,d (Decrementa f, ignora se 0)
INCFSZ f,d (Incrementa f, ignora se 0)
BTFSC f,b (Bit testa f, ignora se limpo)
BTFSS f,b (Bit testa f, ignora se ligado)

8.9- Rotações e Troca
RRF f,d (Rotaciona f para a direita por transporte)
RLF f,d (Rotaciona f para a esquerda por transporte)
SWAPF f,d (Troca os meio-bytes em f)

8.10- Sleep & Timer Watchdog
SLEEP (Sleep,)
CLRWDT (Limpa o timer watchdog.)

8.11- Miscelânea
NOP (Nenhuma operação)
OPTION (Não recomendado)
TRIS (N]ao recomendado)
Pausa para refletir
Interrupções no PIC16F84
O que é uma interrupção?
Tipos de interrupção e o registrador INTCON
Lidando com uma interrupção
Timers no PIC16F84
A Idéia básica
O módulo TIMER0
Usando overflow do timer
Usando a memória de dados EEPROM

9- Interrupções no 84
9.1- Tipos de Interrupção e o registrador INTCON
9.2- Lidando com uma Interrupção
9.3- Timers no '84
9.4- O Módulo TIMER0
9.5- Usando o estouro do timer












Curso de Programação PIC 4/4
1- Introdução
Ao se deparar na programação PIC 16F84, ao primeiro momento parece ser muito
complexo. A folha de dados (Datasheet) do PIC16F84 da Microchip é um excelente
documento técnico e o manual do MPASM é um guia de referência completo. Porém,
utilizando somente deles são insuficientes para saber e entender a sua programação.
Assim este trabalho é um tutorial para programar o PIC16F84, abrangendo o conjunto de
instruções e algumas diretivas do MPASM. Pelo seu conteúdo ele cobre o próprio
PIC16F84 em termos de registros, pinos e assim por diante.

No final, é esperado do aluno que ele esteja bastante à vontade para dar início aos
primeiros passos de sua programação deste dispositivo.

2- O Quê é preciso
Primeiro, é preciso ter em mãos alguma da documentação da Microchip. Como um
mínimo, é necessária a folha de dados (Datasheet) do PIC16F84. Ela contém toda a
informação real que necessário do próprio chip. Também deve se em mãos o Guia de
usuário do MPASM. Ambos estes estão disponíveis no site da Microchip
(http://www.microchip.com/).

Faz-se necessário também o aplicativo MPLAB (for Windows) instalado no PC, pois o
mesmo possui o Ambiente de Desenvolvimento Interativo (IDE) deles, e contém um
editor, o assembler e um simulador. Aqui, você pode criar seu código fonte (editor),
produzir o código executável (assembler) e executar no seu PC (simulador). No
simulador, pode-se observar a execução do programa enquanto mantém a vista nos
registros e pode-se até mesmo simular eventos como mudanças causadas por fatores
externos nos pinos de I/O. É interessante realmente adquiri-lo, pois também está
disponível como o manual do MPASM. Entendendo-se os apéctos básicos e funcionais
destes aplicativos irá a facilitar muito o entendimento da maioria dos tópicos que está
sendo abordado neste trabalho. O Simulador (Emulador) é muito bom para observar os
registradores e executar um programa em um modo passo a passo, mas isso não resolve
todos os problemas quando uma eventual falha ocorrer.

O modo passo a passo não leva em conta o efeito de uma entrada em um programa e
uma rotina de delay deve ser ignorada para se prevenir horas de espera para a execução
do programa.

Isso é tudo que é preciso, mas há muito mais coisas das quais pode ser apreciado.
Não menos, um chip PIC16F84 e um programador. O programador GTP-Gravador
Testador PIC apresentado no curso é o equipamento mais barato no mercado e vem com
a vantagem da não necessidade retirar o microprocessador da placa para se efetuar os
testes o que tornaria os processos de desenvolvimento ou estudo mais moroso e de certa
forma evitaria assim erros ou acidentes durante o intercambio entre o gravador e a placa
de testes, caso fossem utilizados separadamente.

Para um trabalho mais complexo, as Notas de Aplicação da Microchip (ANs) também
são de extrema ajuda. Estas notas cobrem todos os tipos de usos dos PIC’s, com muitas
dicas úteis para uso no mundo real. As ANs estão em formato Adobe .pdf: Usando o
Adobe Acrobat você pode procurar pelas ANs por situações como 'motor' ou 'serial' e ler
as anotações destinadas às suas necessidades.

Um das notas, AN585 sobre sistemas operacionais de tempo real para o PIC, refere-
Curso de Programação PIC 5/5
se à Programação de Tempo Real - Tópicos Negligenciados. É de extremamente
interessante que se tenha uma cópia pois é em tutorial fascinante sobre todo o assunto
das interrupções, controle de laço-fechado e similares.


3- O que é preciso saber

Para uma maior facilidade de entendimento e conseqüentemente um melhor
aproveitamento nas atividades deste trabalho proposto, seria interessante ter algum
conhecimento prévio sobre algumas terminologias básicas dos computadores, como bits,
bytes & EEPROM e conceitos como binário e hexa.


4- Arquitetura do PIC16F84

Um microcontrolador como o PIC16F84 é por sua natureza, um computador completo
em um chip.Ele possui: Um processador, registradores, programa e memória de dados.

Isto o faz diferente de uma CPU, (Unidade de Processador Central) que tem só o
processador e registradores.

• O PIC16F84 tem um processador de 8-bits, e isso é tudo que nós precisamos
saber.
• Os 90 registradores são a área de armazenamento interno do processador. Estes
têm nomes como (STATUS, PORTA, etc). Alguns têm funções especiais que é
examinado neste trabalho. Por exemplo, PORTA armazena os conteúdos de uma
das portas de I/O, isto é a chamada porta A. Dos 90 registradores, 68 são
registradores de propósito gerais, e podem ser considerados como utilitários (ao
contrário daqueles especiais do processador) pois podem ser usados como 'bloco
de rascunho''.

• O PIC16F84 tem uma memória de programa de 1k. Isso significa que há 1024
locais para programa. A memória vai do endereço 000h até o 3FFh. 3FFhex são
1023 em notação decimal, sendo assim há 1024 locais que incluem 000.

• O PIC16F84 tem 64 bytes de memória de dados, chamados de memória de
EEPROM a qual é usada para armazenamento de, por exemplo, valores para
ajuste de dados recebidos do mundo externo. O uso dessa memória EEPROM
será analisado por último. Além disso, o dispositivo inclui quatro tipos de
interrupção e 13 pinos de I/O.

• Interrupções são uns meios de parar a execução do programa e atender a uma
operação definida pela interrupção. Por exemplo, o acionamento de um botão
poderia interromper o fluxo normal do programa e poderia executar alguma
operação especial. É examinadas posteriormente as técnicas de interrupção do
PIC16F84.

• O uso dos pinos de I/O é a chave para o uso de um dispositivo como os '84, uma
vez que qualquer processo consiste em 3 partes: a entrada para o processo, o
próprio processo, e a saída. O PIC16F84 tem 13 pinos configurados como 2
porta: porta A tem 5 pinos e a porta B tem 8; e será usado mais adiante.
Curso de Programação PIC 6/6
5- Conjunto de instruções

Há 35 instruções no conjunto de instruções do PIC16F84, consistindo em um opcode
(código de operação) e operando(s). Basicamente, o opcode especifica o que fazer e o(s)
operando(s) especificam como ou onde. Estas instruções são divididas em 3 grupos:
orientadas por byte, orientadas a bit e literal & controle. Mais tarde será utilizada cada
uma dessas operações.

Por enquanto, serão analisadas apenas para uma das instruções. Será focado mais no
formato, em lugar da função, a qual será visto posteriormente logo mais adiante. Foi
escolhida a instrução ADDWF. A sintaxe desta instrução é:

ADDWF f,d

Onde ADDWF é o opcode e "f d" são os operandos.

As letras ADDWF são chamadas de um mnemônico. Esta é uma abreviação que tanto
o computador quanto os humanos podem entender. Será visto este mesmo layout em
todas as instruções.

O registrador de trabalho é um registrador especial (acima de todos já mencionados),
conhecido como registrador W e é onde a unidade aritmética e lógica (ALU) faz os
cálculos. Qualquer instrução com W no nome age em W. Os outros registradores são
conhecidos como arquivos e nós usamos a letra 'F' nos comandos para indicar que um
arquivo está sendo acessado. Assim, nós podemos entender que o comando ADDWF
soma W ao arquivo F.

Mas o que é arquivo F?

Para cada arquivo (diferente de W) é determinado um endereço hexadecimal. Por
exemplo, o arquivo 0C é chamado "0C", arquivo 10 é chamado "10" e arquivo 2F é
chamado "2F”. A letra minúscula "h" sempre é incluída para indicar que arquivo tem um
valor hexadecimal, como arquivo 10h, por exemplo, que é na realidade o décimo sexto
arquivo na memória.

Alguns arquivos têm nomes, como por exemplo: PORTA é 05h, PORTB é 06h e TRISA
é 85h. O 'f' na instrução acima é o endereço atual do arquivo. Não há nenhum arquivo
chamado "F" ou "f". Isso é um símbolo para representar qualquer um dos arquivos. Assim,
é codificada a instrução: "some W ao arquivo 3C" como:

ADDWF 3Ch,d

Bem, não totalmente - para que serve aquele 'd'?

É o destino do resultado, e será visto isto em muitas instruções. Dependendo da
exigência, o resultado da instrução pode ser posto no registro de funcionamento (W) ou
no próprio arquivo F.

Se 'd' for 0, o resultado estará em W,

Se 'd' for 1, o resultado estará em F.
Curso de Programação PIC 7/7

A instrução pode ser seja qualquer um do seguinte:

ADDWF 3Ch,0; soma W ao arquivo 3C, resultado em W

ADDWF 3Ch,1; soma W ao arquivo 3C, resultado em 3C



6- Um programa simples para o PIC'84

Este programa de exemplo serve para vários propósitos. Além de mostrar como usar
alguns instruções, apresenta também alguns conceitos do assembler e vai também
mostrar algumas técnicas simples para o simulador.

O programa, Simple.asm é apresentado abaixo; Eu lhe guiarei linha por linha.

Programa 1: Simple.asm

;simple.asm
;para demonstrar o aspecto de um programa
;e introduzir algumas instruções e diretivas
;***************** setup ***************************
processor 16F84 ;tipo de processador
org 0010h ;origem do programa na memória
w equ 0 ;para instruções de byte, use w & f
f equ 1 ; ao invés de 0 & 1, isso é bem mais claro
MyReg_1 equ H'10' ;posição Meus Registradores na memória
MyReg_2 equ H'15' ; em h'10' & H'15'
;***************** programa ******************************
;Nós vamos carregar o acumulador (reg w) com valores
; e efetuar algumas operações aritméticas em W utilizando
; MyReg_1&2
movlw H'08' ;coloca o valor H'08' no registrador w
movwf MyReg_1 ;move o conteúdo de w para MyReg_1
; nota – é o mesmo que movwf 10h, já que
; MyReg_1 e 10h são a mesma coisa.
movlw 32h ;coloca 32h no registrador W
addwf MyReg_1,f ;soma o conteúdo de w àquele em MyReg_1
; a resposta vai para MyReg_1, devido ao f.
movlw 92h ;coloca o valor 92h no registrador w
movwf MyReg_2 ;move o conteúdo de W para MyReg_2
; nota – é o mesmo que movwf 15h, já que
; MyReg_2 e 15h são a mesma coisa.
movlw 26h ;coloca 26h no acumulador W
subwf MyReg_2,w ;subtrai w de MyReg_2
; a resposta vai para w
end
Curso de Programação PIC 8/8

Observando-se este exemplo, pode-se verificar o que irá ser encontrado depois de
cada diretiva ou instrução. Qualquer coisa depois de um ';' é um comentário. Todo livro
de programação recomenda a criação de comentários para explicar o que está
acontecendo.

Na seção chamada 'setup', nós encontramos três diretivas do assembler:

"processador 16F84" informa ao assembler para qual chip o programa foi escrito. Se isto
estiver incorreto, o código será preparado pelo assembler para o processador errado
.
"org" diz ao assembler aonde começar a colocar o código na memória de programa.
Você deve colocar seu código além de 004h para ficar claro o endereço para onde o
processador deve ir quando uma interrupção é descoberta.

"equ" é uma equivalência ou "igual a." Simplesmente significa que os itens em qualquer
lado de equ significam a mesma coisa. Por exemplo, a instrução ADDWF espera um 0 ou
1 no lugar de 'd': igualando 'w' a 0' significa que podem ser utilizados 'w' na instrução em
lugar de 0'. Isto é mais fácil de se lembrar durante a codificação, e para ler depois.
Analogamente, igualando MyReg_1 a 10h toda vez que ao se referir ao registrador, será
mais fácil de fazê-lo através do seu nome mais significante e fácil de lembrar.

Na parte chamada 'programa', é encontrada várias instruções do PIC16F84. Podem
ser conferidas as descrições completas que será objeto de estudo mais tarde.

MOVLW k faz o valor k (no exemplo 08h) ser colocado no registrador de trabalho.

MOVWF f copia o conteúdo de W no registrador f. Notar que movwf é estritamente uma
nomenclatura equivocada, já que na realidade ocorre uma cópia (W não é esvaziado), e
não uma movimentação (na qual W seria esvaziado). Notar também a convenção da
Microchip de comparar movlw e movwf: descrevendo a operação os parênteses ()
significam 'o conteúdos de'. Assim k (W) quer dizer que o valor k se torna o conteúdo
de W; (W) (f) meios que o conteúdo de W se tornam o conteúdo de f.
Por último, certificar de entender o uso do conceito de equ com respeito a registradores.
O ' f ' em MOVWF f refere-se a um arquivo. Ele mostra que arquivos têm endereços
hexadecimais e de se esperar ler a instrução como MOVWF 10h por exemplo. Igualando
MyReg_1 a 10h, quer dizer que podem ser escritos MOVWF MyReg_1 com o mesmo
resultado.

ADDWF f,d e SUBWF f,d respectivamente executam a adição e subtração aritmética nos
conteúdos de W e f. Note o uso de equivalências aqui também. Podem ser referidos a
MyReg_1 como antes, e também substituir os valores permitidos de d (no exemplo 0 e1)
por w e f respectivamente.
Conseqüentemente podem ser escritos ADDWF MyReg_1,f no lugar de ADDWF 10h,1.

Montar e executar esse programa.


7- Usando MPLAB para depurar o programa
Este é um processo de três passos: Editar o código fonte, montá-lo e então executá-o
no simulador.
Curso de Programação PIC 9/9
Com o exemplo.asm montado com sucesso, e o editor sendo a única janela aberta no
MPLAB, executar o programa passo a passo (o ícone de pegada). Não ajuda muito –
pode ser visto cada linha do programa ser realçada à medida que é ativada, mas isso é
tudo.
Assim, pode-se começar a usar algumas das outras facilidades do simulador. Sugere-
se que seja aberta a seguinte janela no MPLAB. Todas servem a propósitos semelhantes
- isto é, ver o que está acontecendo nos registradores - mas todas executam
diferentemente. Seria útil ter todas abertas simultaneamente para comparar as
implementações:

Janela > File Register
Esta janela lista o conteúdo de todos os registradores de arquivos de 00 a 4F - ie, não
mostra aqueles na região 80 a 8B. À medida que se caminha pelo programa poderá ser
visto o conteúdo hexadecimal dos registradores 10h e 15h mudando. Note que qualquer
registrador cujo conteúdo mudou há pouco é mostrado em vermelho - e volta para azul no
próximo passo (a menos que haja outra mudança).

Janela > Special Function Registers
Aqui você pode ver os SFRs (Registradores de Função Especial) por nome ao invés
de local, que é o que mostra a janela anterior. O conteúdo é mostrado em decimal, hexa
e binário.

Janela > New Watch Window
Esta é sua janela personalizada para os registradores, e é permitido selecionar quais
registradores se quer monitorar. Todos os registradores estão disponíveis para serem
escolhidos, SFRs e GPRs. Quando se escolher esta janela é mostrada uma caixa de
seleção com uma seta para baixo. Clicar na seta, e uma lista de todos os registradores
aparece: escolher qual irá quer (eg, Myreg_1) e então clicar OK. Será visto o conteúdo do
registrador exibido na janela. Para adicionar outros registradores pode-se clicar no ícone
no canto esquerdo superior da janela e então escolher Add Watch; ou simplesmente
apertar a tecla insert (enquanto a janela está ativa). Você pode salvar as combinações
usadas com mais freqüência como arquivos watch, e então carregá-las depois através da
Janela> Load Watch Window.
Pode-se perguntar de onde veio a lista de nomes de registradores para selecionar. Os
SFRs são óbvios: o MPLAB sabe a respeito deles de qualquer maneira. Os outros, como
MyReg_1 e2, entram das diretivas de equ em seu código, o que é excelente. Porém, em
neste exemplo, foi utilizado também w equ 0 e f equ 1 embora estes não são planejados
como nomes de registro. Porém, eles ainda aparecem na lista de possibilidades que pode
estar o problema de não se querer escolher. Porém não se pode esquecer que aquele W
é um registrador: então agora há duas entradas de W na lista, uma desde o princípio (o
registro de funcionamento) e a que foi criada a outra com equ. Usar qualquer uma delas,
causa um erro de símbolo não encontrado em sua tabela de observação, o que significa
que não se pode monitorar o registro de funcionamento se foi declarado um equ de W em
seu código. Tentar, então comentando a linha com erro com um ‘;', re-montar e tentar
novamente.
Agora se pode usar o registro de trabalho no monitoramento.
Com estas três janelas, caminhar pelo seu programa: agora você tem alguma noção
do que está acontecendo.


Curso de Programação PIC 10/10
8- O Conjunto de Instruções

A Microchip tem detalhes completos do conjunto de instruções. Elas se agrupam em 3
categorias, o que não consideradas particularmente útil. Estas categorias são operações
Orientadas a Byte, a Bit e a Literal/Controle. O interessante seria em agrupar as
instruções dentro daquilo que é utilizado para cada comando, tais como executar
operações aritméticas, tal qual é feito neste trabalho logo a seguir. Para cada instrução, é
explicada a operação. (Por exemplo, há uma explicação o que um Inclusive-OU de fato
está em IORWF). Talvez o mais importante ainda é os exercícios sugeridos para usar as
instruções apresentadas que são bastante simples, mas permitem usar cada instrução, e
também praticar o uso do simulador. Lembrar de se usar os recursos, como a janela de
monitoramento para ver o que está acontecendo a cada passo do seu programa: prestar
atenção nos registradores que se decidiu usar, bem como nos registradores W e
STATUS.

Formato da instrução

O agrupamento da Microchip mantém as instruções de formato semelhante juntas. As
instruções aparecem assim:

byte_command f,d
onde f é a designação do arquivo do registrador e d é o destino; se d=0, o resultado vai
para W. Se d=1, o resultado vai para o registrador f.

bit_command f,b
onde f é o arquivo do registrador, e b é o bit dentro dele; bits são numerados da direita
para a esquerda de 0 a 7. No texto, um bit é escrito como FILE_REG <n>, por exemplo
INTCON <4> significa o bit número 4 no registrador intcon. O registrador INTCON fica no
local 0B.

other_command k
onde k é uma constante ou literal de 8-bit.

O registrador STATUS
O '84 têm o registrador STATUS em 03h. Ele contém o estado aritmético da unidade
de aritmética e lógica. Muitas instruções do '84 afetam certas partes do STATUS. Muitas
instruções afetam STATUS <2>, Z - a flag Zero que é ligada se o resultado de uma
operação for zero. Certas operações afetam os bits de transporte: STATUS <0>, C - o bit
Carry, é ativado se um transporte ocorrer no bit mais a esquerda no resultado; STATUS
<1>, DC - o bit Digit Carry, é ativado se houver um transporte entre os dígitos
hexadecimais (ie, do meio-bit à -bit 3 - ao bit à esquerda -bit 4). Dois comandos afetam
STATUS <3>, o bit Power Down PD, e STATUS <4>, o bit Time Out TO.

8.1: Instruções Move
É encontrado algumas dessas instruções, que nada fazem além de colocar coisas nos
registradores.

MOVF f,d (Move f)
(f) (dest)
Curso de Programação PIC 11/11

MOVWF f (Move W to f)
(w) (f)

MOVLW k (Move literal to W)
k (W)

Exercício: Escrever um programa para usar estes comandos para (por exemplo) por algo
em W, mover de lá para outro registrador, depois colocar alguma outra coisa em W, e
então mover a coisa original de volta para W.

Solução:
Programa 2: Moves.asm
;moves.asm para mostrar como MOVF, MOVWF & MOVLW funcionam
;*********************************** simulador ***
;watch window: reg1, w, pcl
;*********************************** setup ***
processor 16F84
reg1 equ h'10'
;*********************************** programa ***
start: movlw h'05' ;carrega w
movwf reg1 ;move (w) para reg1
movlw h'82' ;altera w
movf reg1,0 ;restaura w
end


8.2: Instruções Clear
Estes dois comandos limpam um registrador.

CLRF f (Clear f)
00h (f)

CLRW (Clear W)
00h (W)

Exercício: Ampliar o programa anterior para limpar os registradores no final.

Solução:
Program 3: Clears.asm
;clears.asm para mostrar como clrf & clrw funcionam
;baseado em moves.asm
;*********************************** simulador
;watch window: reg1, w, pcl
;*********************************** setup
processor 16F84
reg1 equ h'10'
;*********************************** programa
start: movlw h'05' ;carrega w
movwf reg1 ;move (w) para reg1
movlw h'82' ;altera w
Curso de Programação PIC 12/12
movf reg1,0 ;restaura w
clear: clrf reg1 ;limpa reg1
clrw ;limpa w
end


8.3: Instruções Aritméticas
Executar operações aritméticas é muito importante. O '84 pode apenas somar e
subtrair. A aritmética ocorre entre W e um registrador f:

ADDWF f,d (Add W & f)
(W)+(f) (dest)

SUBWF f,d (Subtract W from f)
(f)-(W) (dest)
or between W and a literal:

ADDLW k (Add literal & W)
(W)+k (W)

SUBLW k (Subtract W from literal)
k-(W) (W)

Exercício: Use estes e os comandos anteriores para carregar um registrador a partir de W
e efetuar algumas adições e subtrações. Preste atenção no bit Carry e no bit Zero no
registrador STATUS.

Solução:
Program 4: Arith.asm
;arith.asm para mostrar o uso de ADDWF, SUBWF, ADDLW, SUBLW
;************************************* simulador
;watch window: reg1,reg2,status,w,pcl
;************************************* setup
processor 16F84
reg1 equ h'10'
reg2 equ h'12'
;************************************* programa
loads: movlw d'20' ;carrega w
movwf reg1 ;carrega reg1
movlw d'80' ;carrega w mais uma vez
movwf reg2 ;carrega reg2
arith: addlw d'05' ;adiciona d'05' a w
sublw d'100' ;subtrai w de d'100'
addwf reg1,1 ;soma w a reg1, dentro de reg1
subwf reg2,1 ;subtrai w de reg2, dentro de reg2
end

Observação: Pode-se ver que a subtração é feita usando o método do segundo
complemento. Este é o modo normal que a subtração acontece com binários. Isto pode
ser explicado com um exemplo.
Curso de Programação PIC 13/13

Primeiramente, se expressa ambos os números em binário. Deixar o número a partir
do qual está se subtraindo inalterado. Formar o segundo complemento do que está sendo
subtraído assim: mudar todos os 0’s para 1’s e todos os 1’s para 0’s (este é o
complemento), somar 1 ao dígito à direita dígito, transportando à esquerda conforme
necessário. Agora acrescentar o resultado ao outro número inalterado. Descartar o
transporte à esquerda, se houver. O resultado é a resposta. Pode-se conferir...
Por exemplo, subtrair 20 de 27 . O resultado obtido deve ser 7. O procedimento deve ser
como se segue:
Converter para binário: 27 11011 . . . . x

20 10100 . . . . y

Fazer o segundo complemento de y: complemento 0: 01011

somar 1: 01100 . . . . z

Somar x e z: + 11011 . . . . x

(1) 00111 = 7

O 1 entre parênteses é o transporte, que é descartado.


8.4: Funções Lógicas

Nesta fase, antes de se examinar as funções lógicas providas pelo 84, podem ser
discutidas as funções lógicas em geral. Considerar um dispositivo eletrônico digital que
apenas atenda em valores binários de 1 e 0 com 3 fios ligados. Supondo-se que 2 fios
são entradas, e o resultado no terceiro fio dependa das entradas. As relações que podem
existir entre as 2 entradas e a saída são o resultado das combinações de entrada que
são: 00, 01, 10 e 11. O fio 3 podem ser 1 se, e somente se, as entradas forem ambas 1
(i.e: 11) ou se uma ou ambas as entradas forem 1 (i.e: 01, 10, 11), e outras combinações.
As relações básicas são conhecidas como E e OU (AND e OR). AND significa ambas as
entradas enquanto OR significa qualquer uma ou ambas. A maioria das explicações a
respeito disso, resultam em uma TABELA da VERDADE, desenhada na tabela 1 para as
seguintes operações lógicas: AND, OR, XOR, NAND, NOR.

Tabela 1 – Tabela Verdade das Funções AND, OR, XOR, NAND e NOR
Entradas A B A AND B A OR B A XOR B A NAND B A NOR B
ambos ou, ambos ou, não ambos não ambos nem um, não ambos
00 0 0 0 1 1
01 0 1 1 1 0
10 0 1 1 1 0
11 1 1 0 0 0

Curso de Programação PIC 14/14
A função AND significa que o resultado só será 1 quando ambas as entradas forem 1.
OR significa que qualquer uma das entradas pode ser um 1 para a saída ser 1, mas assim
também será se ambas as entradas forem 1. A função XOR quer dizer "eXclusive OR", e
significa dizer que qualquer entrada sendo 1 fará o resultado na saída ser 1, e,
especificamente exclui a situação onde ambas as contribuições forem 1. Finalmente,
NAND e NOR são as negações de AND e OR respectivamente: compare as colunas e
você verá o que isso significa.

A propósito, a função OR (ao contrário da função de XOR) às vezes é conhecida como
"Inclusive OR" (IOR). O PIC16F84 usa este termo.

O PIC16F84 provê várias operações lógicas que agem em dois valores de 8-bits;
esses valores são comparados bit a bit. Por exemplo - sem olhar para uma instrução do
'84 - considerar o ANDing dos números (5F)
H
equivalente a (95)
10
ou (0101 1111)
2
e (A3)
H

que é (163)
10
ou (1010 0011)
2
; resultando em (03)
H
que é (3)
10
ou (0000 0011)
2
.

5F: 0101 1111

A3: 1010 0011

and: 0000 0011

Claramente, só nas 2 posições mais à direita AND é satisfeito. O resultado aí é 1, e 0
em qualquer outro lugar.
As instruções fornecidas pelo 'PIC16F84 são:

A comparação ocorre entre os registradores W e f:

ANDWF f,d (AND W with f)
(W) AND (f) (dest)

IORWF f,d (Inclusive OR W with f)
(W) OR (f) (dest)

XORWF f,d (Exclusive OR W with f)
(W) XOR (f) (dest)

ou entre W e uma literal:
ANDLW k (AND literal with W)
(W) AND k (W)

IORLW k (Inclusive OR literal with W)
(W) OR k (W)

XORLW k (Exclusive OR literal with W)
(W) XOR k (W)

Pode-se notar que o '84 não suporta as funções NAND ou NOR. Ao contrário, ele provê
meios de complementar (negar) um registrador; isso significa que para realizar NAND
deve-se primeiro efetuar AND e então:
Curso de Programação PIC 15/15
COMF f,d (Complementa f)
complemento de (f) (dest)

Exercício: É sugerido aqui fazer duas coisas. Primeiro, usando a calculadora do Windows,
verificar os resultados acima: isto irá assegurar que foi amplamente entendido o conceito.
Então, escrever para um programa em assembler para conferir as instruções do '84,
carregando os registros apropriados e executando as operações e conferindo os
resultados.


8.5: Decrementando e Incrementando

Duas instruções simples podem decrementar ou incrementar o conteúdo de um
registrador, assim:

DEC f,d (Decrementa f)
(f)-1 (dest)

INC f,d (Incrementa f)
(f)+1 (dest)

Exercício: Em um programa, talvez aproveitando um dos anteriores nos quais foi realizado
alguma aritmética ou alguma lógica, verificar o funcionamento destes comandos. Ficar
atento à flag Zero, que é ativada se qualquer comando fizer o registro em questão, zerar:
Este fato pode ser utilizado depois para se basear nos dois outros comandos.

8.6: Ativando e limpando Bits
Usando os dois comandos a seguir, você pode ativar ou limpar qualquer bit “b” no
registrador “f” por duas razões:

1- Como exemplo, o registrador em questão pode ser uma porta, controlando algum
equipamento externo. Cada bit pode estar ativando um dispositivo diferente: um motor,
uma luz, ou o que quer que seja. Ativando e limpando cada bit, liga e desliga cada
dispositivo.

2- Como é visto no item 8, pode-se usar o fato de um bit estar ativado ou não para pular
instruções no programa. A capacidade de ativar ou limpar qualquer bit, dá a habilidade
para controlar esse processo.

BCF f,b (limpa Bit em f)
0 (f<b>)

BSF f,b (ativa Bit em f)
1 (f<b>)

Foram lidas essas duas operações como 0 (ou 1) se tornando o conteúdo do bit ‘b’ no
registrador ‘f’.

Exercício: Colocar esses comandos em qualquer um dos programas anteriores e observar
as mudanças a bits individuais em sua janela de monitoramento.

Curso de Programação PIC 16/16


8.7: Controle de Programa

Por muitas razões, há a necessidade de se controlar o fluxo através do programa.
Normalmente, o fluxo procede linearmente a partir do topo; e freqüentemente isto não é
adequado às necessidades.

Primeiramente, pode-se precisar efetuar laços por certas instruções: poderia se ter um
sistema no qual um determinado processo seja contínuo como por exemplo, o controle
de um transportador que continuamente acrescenta ingredientes a um depósito. Aqui,
quando um depósito é realizado é voltado ao topo e passa-se novamente pelos mesmos
passos somando mais depósitos a cada passagem.

Segundo, pode ser uma parte do programa que será útil em muitas outras partes. Em
lugar de se repetir este código em muitos lugares, separa-se esse pedaço do restante do
código; então nós simplesmente chamamos isto tão freqüentemente quanto precisarmos.
O pedaço reutilizável é chamado de SUB-ROTINA. A seqüência de dados devolve o
controle ao ponto em que foi chamada quando terminar.

Observando-se os laços (looping) primeiro:

GOTO k (Vá para um endereço)
k (PC)

Esta instrução ‘vai para k’, e faz isso carregando o endereço k dentro do contador do
programa, PC. Para usar GOTO deve-se primeiro informar para onde quer que o
programa vá, utilizando para isso um Label. Então se usa GOTO Label.

Exercício: Modificar um dos programas que já foi escrito. Pode-se colocar um rótulo
(label) perto do início, e um GOTO mais adiante. À medida que se anda pelo programa
verá realçada a linha em que seu programa está fazendo o loop. Olhar para o contador do
programa (PCL) na janela de monitoramento e conferir isso.

Pode-se examinar agora a seqüência de dados. É preciso entender o conceito de
stack (pilha). A pilha - que tem 8 níveis no PIC16F84 é o lugar onde o endereço da
próxima instrução é colocado, quando uma instrução CALL é encontrada. À medida que
cada instrução é executada, é trabalho do Contador do programa (PC) saber onde o
microcontrolador está, a qualquer tempo. A colocação do próximo endereço na Pilha diz
ao microcontrolador aonde ir, depois que uma sub-rotina tenha acabado.

É referido como popping para carregar a pilha, isto é lendo o último valor e girando a
pilha para cima. A pilha só é acessível pelo topo: assim como uma pilha de pratos. O topo
da pilha é abreviado por TOS (Top of stack).
Há 2 instruções associadas com qualquer sub-rotina - uma para enviar o
microcontrolador à sub-rotina, e a outra para trazê-lo de volta:

CALL k (Call sub-rotina)
(PC)+1 TOS, k (PC)

Curso de Programação PIC 17/17
A chamada CALL para uma sub-rotina empurra o PC+1 atual para o topo da pilha,
então altera o PC para o endereço k. Isto resulta em um salto no fluxo do programa para a
sub-rotina, mas o endereço para voltar após a execução da sub-rotina está preservado na
pilha para recuperação posterior.

RETURN (Retorna da sub-rotina)
TOS (PC)

RETURN é a última instrução da sub-rotina. A instrução de retorno lê e remove o último
dado da pilha e assim o programa retorna ao lugar certo. Pensar na profundidade da
pilha: significa que chamadas podem ser encadeadas, e o fluxo estará correto contanto
que cada chamada tenha um retorno correspondente.

RETLW k (Retorna com literal em W)
k (W), TOS (PC)
Isto retorna com k (W) somado.

RETFIE (Retorna de Interrupção)
TOS (PC), 1 GIE

Quando uma interrupção acontece, o PC é empurrado para a pilha da mesma forma
que acontece com uma chamada de sub-rotina, então RETFIE gira a pilha. Também, a
ocorrência de uma interrupção incapacita interrupções adicionais: alguém não quer as
interrupções sejam interrompidas. O que acontece é que a interrupção faz com que a flag
de interrupção global, GIE (INTCON <7>) seja fixada em 0. Voltar de uma interrupção
significa que devem ser permitidas interrupções adicionais, conseqüentemente RETFIE
fixa GIE de volta a 1.

8.8: Ignorando instruções

Existem 4 instruções que permitem que se ignore a instrução seguinte.

DECFSZ f,d (Decrementa f, ignora se 0)
(f)-1 (dest), ignora se o resultado for = 0

INCFSZ f,d (Incrementa f, ignora se 0)
(f)+1 (dest), ignora se o resultado for = 0

Os comandos acima são baseados nos comandos DECF e INCF vistos anteriormente.
A parte SZ significa ‘skip if zero' (ignora se for zero).

Exercício: Conferir essas 2 instruções carregando um valor inicial em um registrador
chamado 'cont.' Então usar qualquer instrução para mudar esse valor, efetuando laços
nesse bloco de código. Conferir para ver se a instrução que segue o decfsz ou incfsz
(provavelmente um GOTO, para causar laço) é ignorada ou não, como apropriado.

BTFSC f,b (Testa Bit f, ignora se limpo)
skip if (f<b>)=0

BTFSS f,b (Testa Bit f, ignora se ativado)
skip if (f<b>)=1
Curso de Programação PIC 18/18

Ler estas instruções como ‘testa bit f e ignora se ativado’.

Exercício: Escrever um programa com um bloco de código com um loop. Colocar um
BTFSS no final, seguido por um GOTO para retornar ao início. Incluir um pouco mais de
código. O BTFSS precisará referir-se a uma das portas de I/O do PIC16F84 como f (05)
H

ou (06)
H
para PortA e B respectivamente), e pode se usar qualquer pino de 0 a 4 na
PortaA, 0 a 7 na PortaB. Deve-se ter outro GOTO exatamente no final para efetuar um
loop mais externo para o começo, assim pode-se ver o loop do programa para ver o que
acontece quando um pino de entrada sofre alteração.

Há um modo fácil de se fazer com que o pino mude de estado no simulador MPLAB. Ir
em Debug> Simulatos stimulus> Asynchronous stimulus; Poderá ser visto uma tabela de
botões de Stim0 até Stim12. Clicar com o botão direito em qualquer um, por exemplo,
Stim7, e clicar em Assign pin. Dar um duplo-clique no pino que foi escolhido para usar
como sensor, talvez fosse RA3. Stim7 então muda para RA3. Agora clicar com o botão
direito novamente no botão. Pode-se escolher “pulsar”, “tornar LOW”, “HIGH” ou “chavear
o pino”. Aqui vai ser escolhido chavear o pino.

Agora podem se efetuar os testes. Caminhar pelo programa. Dependendo do estado
inicial do pino, o qual ainda é desconhecido na ligação da alimentação, o programa fará o
loop ou não. (No loop mais interno, isto é, ele sempre voltará para o início a partir do final,
para propósitos de teste) A qualquer hora que quando quiser, clicar com o botão esquerdo
no botão “Stim” que se escolher, que agora pode se saber que é RA3. (Se tiver a exibição
das portas em uma janela de monitoramento, será visto o pino mudar de estado nos
limites da próxima instrução). De qualquer modo, da próxima vez o programa chegar ao
passo BTFSS, ele deveria se comportar diferentemente, já que foi chaveado o pino e
assim o BTFSS deveria ter uma resposta diferente.

8.9: Rotações e Trocas

Três instruções permitem a manipulação os bits dentro de um registrador. Destas,
duas deslizam os bits para a direita ou para a esquerda (através do bit de transporte), e a
terceira inverte os dois meio-bits (nibbles) do registrador.

RRF f,d (Rotaciona f à direita através do bit carry).

Cada bit no registrador f é deslocado 1 para a direita. O que sai fora para a direita é
movido para carry, e carry é movido para a esquerda.

RLF f,d (Rotaciona f à esquerda através do bit carry).

Cada bit no registrador f é movido 1 para a esquerda. O que sai fora pela esquerda é
movido para dentro de carry, e carry circula para a direita.

SWAPF f,d (Inverte os nibbles em f)
(f<3:0) (dest<7:4>), (f<7:4>) (dest<3:0>)

Exercício: Observar o efeito desses comandos no conteúdo de um registrador.

Curso de Programação PIC 19/19

8.10: Sleep e o Timer Watchdog

Estes dois comandos estão relacionados. O WDT (Watchdog Timer) é um dos
caminhos para se despertar do comando sleep.

SLEEP (Sleep)
0 WDT, 0 WDT prescaler, 1 TO, 0 PD

CLRWDT (Clear watchdog timer)
0 WDT, 0 WDT prescaler, 1 TO, 1 PD

8.11: Miscelânea

NOP (Nenhuma operação) Esta instrução não faz nada. Ela é bastante útil para a criação
de pequenos intervalos de atraso (1µs) para permitir que alguma coisa seja pré-ajustada
antes que outra operação seja executada.

TRIS 05 Esta instrução controla a direção de cada linha da porta chamada Porta A.
É o Registro de Controle de Direção (DCR). Há 5 linhas na porta A chamadas de RA0,
RA1, RA2, RA3 e RA4. Cada linha pode ser de entrada ou de saída. Para fazer uma
linha entrada, o bit correspondente no registro TRIS é definido como "1. " Para fazer uma
linha saída, o bit correspondente é definido como "0. " Assim o valor 01 fará RA0 uma
entrada e todas as outras linhas serão saídas.

O valor 23 (0010 0011) fará RA0 e RA1 entradas e o bit5 não terá nenhum efeito, pois
nenhuma linha corresponde a esse bit.

TRIS 06 Esta instrução controla a direção de cada linha na porta B.
Existem 8 linhas na porta B. RB0, RB1, RB2, RB3, RB4, RB5, RB6 e RB7. Um "0" no
registrador TRIS torna a linha correspondente na porta B uma Saída. Um “1” no
registrador TRIS torna a linha uma Entrada.
Isso é fácil de ser lembrado, pois “0” é similar a 0utput (saída) e “1” é similar a 1nput
(entrada).

Não se deve usar a instrução a seguir, que foi incluída para efeitos de compatibilidade.

OPTION (Não recomendado)

9- Interrupções no '84

Interrupção é uma forma simples de atrair a atenção no computador. Uma vez
uma interrupção tenha sido tratada, o controle tem que voltar para onde estava
anteriormente. Não só isso, mas todo o estado do sistema deve ser recuperado.
Se qualquer registrador foi mudado durante o controle da interrupção, ele deve ser
restaurado.


9.1- Tipos de Interrupção e o registrador INTCON

Curso de Programação PIC 20/20
O PIC16F84 tem 4 tipos diferentes de interrupção:
. uma interrupção externa no pino 6, também conhecido como: RB0
. uma mudança em qualquer dos pinos de 10 a 13, também chamados RB4 a RB7
. um estouro no cronômetro
. uma de gravação completa na EEPROM.

Para permitir interrupções, e para determinar a sua origem, o processador utiliza o
registrador INTCON (0Bh). Cada bit serve a um propósito específico, e interrompe o
trabalho de acordo com o seu valor (ativado ou não).

Primeiramente, interrupções, como um todo, podem ser habilitadas ou desabilitadas
pelo bit INTCON <7>, o GIE (Habilitação de Interrupção Global). Se esse bit estiver
zerado, então nenhuma interrupção pode acontecer: Esse é o valor no power-up.
Também, se uma interrupção acontecer, então o GIE é zerado para prevenir a interrupção
de ser suspensa; o retorno da interrupção com a instrução RETFIE re-habilita as
interrupções.

Segundo: cada um dos tipos de interrupção deve ser habilitado com seu próprio bit em
INTCON, antes de poder ser utilizada:

- interrupção externa no pino 6: INTCON <4>, o bit INTE

- mudança em quaisquer dos pinos 10-13: INTCON <3>, o bit RBIE

- estouro do cronômetro: INTCON <5>, o bit T0IE

- gravação completa da EEPROM: INTCON <6>, o bit EEIE

Terceiro, quando interrupções acontecem, certos bits (conhecido como flags de
interrupção) são ativados de forma que podem então se determinar a origem da
interrupção:

- interrupção externa no pino 6: INTCON <1>, o bit INTF

- mudança em quaisquer dos pinos 10-13: INTCON <0>, o bit RBIF

- estouro do cronômetro: INTCON <2>, o bit T0IF

Há a necessidade de se saber a origem dessa interrupção porque dependendo do seu
tipo a ação que se deve entra deve ser de modo diferente. Para isso, deve-se verificar o
bit apropriado que diz que tipo de interrupção é. Notar que as flags de interrupção sempre
são ativadas quando há uma interrupção, independente do estado do bit de habilitação
correspondente.

9.2- Lidando com uma Interrupção

No PIC16F84, todas as interrupções são enviadas para 004h. Esse ponto é o vetor de
interrupção e o programa é orientado a dirigir-se para esse endereço. No vetor, deve-se
ter a certeza irá ser suprido o código necessário para tratar com cuidado do problema.
Um ponto crucial é que pode haver a necessidade de se salvar o status da máquina como
ele estava antes da interrupção, antes de ser corrigido a interrupção. Claramente, as
Curso de Programação PIC 21/21
atividades empreendidas durante a correção poderiam mudar algumas coisas tais como
os registradores W e STATUS. É preciso ter-los restabelecidos após ter controlado a
interrupção, para que nosso outro trabalho possa continuar. O PIC16F84 só salva o
Contador do programa na pilha (PC+1, na verdade). É preciso se assegurar que estarão
salva e que poderão ser recuperados qualquer outra coisa que eventualmente houver
necessidade.

Há 3 partes a um programa que devem controlar interrupções simples:

- uma seção initialize onde, em nosso caso, nós habilitaremos as interrupções;

- uma seção Main onde a maior parte do é utilizada (fazendo cálculos ou o que quer
que seja) e a parte de manipulador (handler) onde a interrupção é tratada.

Initialize: ativa GIE , INTCON <7> para habilitar interrupções, ativa INTE, INTCON <4>
para habilitar interrupções no pino 6.

Handler: salva o estado da máquina; provavelmente W e STATUS; checa as flags de
interrupção para determinar a origem; INTF, RBIF, T0IF derivam para o correto 'o sub-
handler' para determinar o tipo de interrupção (embora nós fixamos apenas INTE). Faz o
que é necessário para restaurar o estado anterior à interrupção e retorna.

Main: Efetua cálculos, por exemplo.

Exercício: Começar lentamente com as interrupções. Isto pode se tornar bastante
complexo. Escrever um programa para provocar a menor interrupção possível: habilitar e
fazer uma rotina de serviço de interrupção (ISR – interrupt service routine) que faça bem
pouca, ou coisa alguma que não seja reabilitar as interrupções e retornar, e uma rotina
principal que somente faça loops por algum código que espere por uma interrupção. Não
será preciso preservar o estado da máquina, nem conferir o tipo de interrupção nesta
fase. Para ver este programa funcionando corretamente no simulador, sugere-se usar a
interrupção de mudança na porta B, usando a técnica de estímulo assíncrona discutida
anteriormente. Usar um chaveamento do pino para provocar a mudança. Enquanto o
programa estiver efetuando os loops na seção principal, chavear o pino e verificar que a
interrupção acontece quando se executa o próximo passo do programa. Enquanto o
programa estiver na ISR, chavear o pino novamente. Se tudo estiver funcionando, a
mudança no pino não causará uma interrupção, porque GIE foi sido zerado.

Solução:
Program 5: Inter1.asm
;inter1.asm é um manipulador simples de interrupções-
; ele não salva o estado da máquina
; nem determina o tipo de interrupção.
;*********************************************simulador
;watch window: intcon, pcl
;stack: mantenha aberta também- veja o endereço de retorno ida e volta
;asynch stimulus: tenha um chaveamento em rb4
;********************************************* setup
processor 16F84
movlw h'0'
movwf h'0b' ;limpa intcon
Curso de Programação PIC 22/22
goto main ;salta sobre a isr
;********************************************** início da isr
isr: org h'0004' ;interrupções sempre apontam para cá
nop ;aqui nos lidamos de fato
nop ; com a interrupção
bcf h'0b',0 ;limpa int antes de retornar
retfie ;isto reativa o intcon gie
;*********************************************** fim da isr

;*********************************************** início de main
main org h'0020' ; deixa espaço bastante para a isr!
bsf h'0b',7 ; ativa global int enable
bsf h'0b',3 ; ativa mudança em b int enable
payrol nop ; loop aqui até interrução,
nop ; realize tarefas de payroll
goto payrol
nop
nop
end


Exercício: Agora implementar esse programa para salvar o estado da máquina no
momento da interrupção. Testar e ter a certeza que foi carregado W na parte principal,
então alterar na ISR, e verificar se ele é restaurado corretamente.

Solução:
Program 6: Inter2.asm
;inter2.asm salva o estado da máquina
; mas não determina o tipo de interrupção.
;
;****************************************************simulador
;watch window: intcon, pcl, portb, w, w_saved
;stack: mantenha aberta também- veja o endereço de retorno ida e volta
;asynch stimulus: tenha um chaveamento em rb4
;**************************************************** setup
processor 16F84
w_saved equ h'10' ;um lugar para manter w
movlw h'0'
movwf h'0b' ;limpa intcon
goto main ;salta sobre a isr no início
;**************************************************** isr
isr org h'0004' ;interrupções sempre apontam para cá
movwf w_saved ;salva w como em main
movlw h'65' ;alguma coisa para mudar w
nop ;mais operaçõas da isr
;agora, restaurar w: não há
; "movfw"- 2 swapf's parece ser o caminho a seems to be
; seguir para faze-lo...
swapf w_saved,1 ;primeiro, swap w_salvo nele próprio
swapf w_saved,0 ;então, swap dentro de w
bcf h'0b',0 ;limpa int em b antes de voltar
Curso de Programação PIC 23/23
retfie ;isto reativa intcon gie

;***************************************************** final da isr
;****************************************************** Início de main
main: org h'0020' ; deixe espaço para a isr!
bsf h'0b',7 ; ativa global int enable
bsf h'0b',3 ; ativa mudança em b int enable
payrol nop ; loop aqui até a interrupção,
nop ; fazendo instruções em payroll
movlw h'0f' ; simule um calculo carregando w
goto payrol
nop
nop
end



Exercício: Finalmente, permitir mais de um tipo de interrupção - mudança em um dos
pinos da porta B 4:7 bem como uma interrupção no pino RB0/INT. Neste caso será
preciso determinar o tipo de interrupção, e controlar isso adequadamente.

Solução:
Program 7: Inter3.asm
;inter3.asm salva o estado da máquina
; e determina o tipo de interrupção.
;
;**************************************************simulator
;watch window: intcon, pcl, portb, w_saved, w
;stack:mantenha aberta também- veja o endereço de retorno ida e volta
;asynch stimulus tenha um chaveamento em rb4 (for rbi) e rb0(int)
;************************************************* setup
processor 16F84
w_saved equ h'10' ;Um lugar para manter w
movlw h'0'
movwf h'0b' ;limpa intcon
goto main ; salta sobre a isr no início
;*************************************************** isr
isr org h'0004' ;interrupções sempre apontam para cá
movwf w_saved ;salva w como ele estava am Main
;descobre qual o tipo de interrupção
btfsc h'0b',0 ;é uma rbi?
call _rbi ;sim - chame o 'sub-handler' rbi
btfsc h'0b',1 ;é int?
call _int ;sim – chame o 'sub-handler' int
;termina aqui após os sub-handler
;agora, restaura w
swapf w_saved,1 ;primeiro, swap em w_salvo dentro dele mesmo
swapf w_saved,0 ;então, swap em w
bcf h'0b',0 ;limpa rbif antes de voltar
bcf h'0b',1 ;limpa intf antes de voltar
retfie ;isto reativa intcon gie
Curso de Programação PIC 24/24
_rbi movlw h'65' ;faz algo para mudar w
return
_int movlw h'24' ;faz algo diferente com w
return
;***************************************************** Final da isr
;
;**************************************************** Início de main
main org h'0020' ; leave room for the isr!
bsf h'0b',7 ; ativa global int enable
bsf h'0b',3 ; ativa mudança em b int enable
bsf h'0b',4 ; ativa ext int no pin6 enable
; nós tivemos 2 tipos de interrupção!
payrol nop ; loop aqui até interrupção,
nop ; fazendo operações em payroll
movlw h'0f' ;simule cálculo carregando w
goto payrol
nop
nop
end


9.3- Timers no '84

A idéia básica é a utilização do PIC16F84 para cronometrar algo. Cronometrar, quer
dizer do modo como é utilizado um relógio normal. Poderia acender a iluminação de um
aquário, por exemplo, ou fechar as cortinas às 18h00 todas as noites. Mas não há
nenhum relógio nos 84: nenhum relógio no sentido de um relógio normal. O que há,
entretanto, é uma relação simples entre executar instruções e a velocidade em que o
processador trabalha. Uma instrução é completa em 1µs quando o chip está operando à
4MHz.
Isso poderá ser conferido e ainda ser introduzido uma característica bem útil do
MPLAB ao mesmo tempo: o Cronômetro. No MPLAB preparar para executar qualquer um
dos programas que já foi escrito. Abrir o cronômetro através de Janela >Cronômetro.
Poderá ser visualizado uma janela simples contendo 3 informações importantes: o
número de passos completos em um determinado tempo, e a freqüência. Observar se a
freqüência está fixada agora em 4MHz, clicar zero e executar um passo do programa uma
vez. Deve ser visto que progrediu 1 ciclo em 1µs. (A menos que esse passo fosse,
coincidentemente, um desvio no programa, o que é uma instrução de 2 ciclos.)
Assim, pode-se vislumbrar um relógio comum. É só se saber quantos passos foram
executados para se saber quanto tem se passou. Entrar em Timer0.

Program 8: Time0.asm
;time0.asm para mostrar como timer0 funciona
;************************************ setup
processor 16F84
STATUS EQU H'03'
OPTIO EQU H'81'
tmr0 EQU H'01'
BANK_ EQU H'05'
T0CS EQU H'05'
PSA EQU H'03'
Curso de Programação PIC 25/25
clocked equ h'10'
INTCON equ h'0B'
T0IE equ h'05'
GIE EQU H'07'
goto top
;************************************ isr
isr ORG h'0004'
incf clocked ;clocked é o ‘relógio comum’
BCF INTCON,2
retfie
;************************************ programa
top org h'0010'
clrf tmr0 ;limpa o registrador tmr0
clrf clocked
mode bsf STATUS,BANK_ ;alterna para page 1
bcf OPTIO,T0CS ;vai do counter para o timer
bsf OPTIO,PSA ;sem prescaler ainda
bsf INTCON,GIE
bsf INTCON,T0IE
loop nop
nop
goto loop
END





9.4- O Módulo TIMER0

O cronômetro do PIC16F84, TIMER0, trabalha numa base em que cada vez que
acontece um ciclo de instrução, um certo intervalo de tempo decorreu. Quando TIMER0
está correndo, seu registrador (TMR0) é incrementado a cada ciclo; a cada 1µs se o clock
for de 4MHz. Então, o valor de TMR0 representa o 'tempo' em passos de 1µs. Mas TMR0,
como todos os registradores, é um registrador de 8 bits e assim só pode contar até FF:
isso significa que o tempo vai até 255µS o que não é muito tempo. Projetar a sua mente
até a discussão de interrupções, onde foi dito que um dos tipos de interrupção era uma
interrupção de estouro de cronômetro: isso significa que o registrador TMR0 ultrapassou o
limite de FF e retornou para 00. Isso significa que essa interrupção acontece a cada
256µS do tempo real. Pode-se aproveitar com esta interrupção incrementar um
registrador.

Pode-se analisar passo a passo este processo observando simplesmente TIMER0
funcionando, sendo usado as técnicas de interrupção com initialize, handler e main, vistas
anteriormente.

Initialize: ativa GIE, INTCON<7> para habilitar interrupções, ativa T0IE, INTCON<5> para
habilitar a interrupção do timer.

limpa T0CS, OPTION<5> para habilitar o timer - veja ativar PSA, OPTIOPN<3>, para
manter o prescaler fora disto.
Curso de Programação PIC 26/26

Handler: incremento 'cronometrado em função do clock', nosso contador de overflow
(estouro).

Main: tem um loop para manter o programa rodando.

Exercício: Escrever um programa para implementar o cronômetro simples acima, tendo
em mente que nós não se está fazendo nada com os estouros a não ser clicá-los. Conferir
o programa no simulador, observando os registradores que devem ser monitorados e
também o cronômetro. Antes de começar, será preciso entender como acessar o
registrador de opção (OPTION), o que não é exatamente tão simples quanto acessar o
STATUS.

Acessando registradores em Bank1: Pode se perceber que alguns registradores como
OPTION estão naquilo que é referido como Bank1, ao invés de Bank0. Outros como
STATUS está em ambos Bank0 e Bank1. O que isto significa na prática, é que estes
registradores do Bank1 normalmente não estão disponíveis, porque nossa esfera de
operações é o Bank0. Foi utilizado o registrador de STATUS para alternar entre os
bancos, com RP0 (STATUS <5>) fazendo o truque. Isto simplesmente significa que há a
necessidade de ativar RP0 para ir para Bank1 e zerá-lo para retornar. Para aqueles
registradores que estão em ambos os bancos, tem-se o acesso não importa de onde se
esteja, mas lembrar que o registrador tem 2 endereços diferentes: STATUS tem seus
endereços conhecidos em h'03' e h'83'.

9.5- Usando o estouro do timer

Pode-se observar que o registrador o registrador fica se atualizando sempre que o
cronômetro estoura e isto acontece a cada 256µs, ou seja o timer vai estourar em 256.
Existe a necessidade também em contar estes estouros em outro registrador (arquivo).
Agora, se está chegando mais perto de um segundo na cronometragem, que é o objetivo
que a ser perseguido. Até quanto é preciso contar no segundo arquivo para alcançar 1
segundo?
Incrementar a cada .0,0256 segundos significa que existem aproximadamente 39
incrementos em um Segundo, então isso significa que podem ser contados segundos de
tempo-real incrementando um outro registrador, SECONDS por exemplo, a cada 39
passos. Para conseguir minutos e horas, simplesmente é tratado com o estouro do
registrador SECONDS para minutos a cada 60 segundos e o mesmo com um registrador
de minutos, a cada 60 minutos para marcar as horas.

Exercício: Criar um programa para implementar o anterior, pelo menos até a parte do
registrador SECONDS.
Usando a memória de dados EEPROM









Curso de Programação PIC 27/27
Apêndice 1 – Conjunto de Instruções


• Instruções Aritméticas
ADDLW
ADDWF
SUBLW
SUBWF
INCF
DECF
CLRF
CLRW
• Instruções de Movimentação de
Dados
MOVLW
MOVWF
MOVF
RLF
RRF


• Instruções Lógicas
ANDLW
ANDWF
IORLW
IORWF
XORLW
XORWF
COMF
SWAPF
• Instruções de atendimento a
Rotinas
GOTO
CALL
RETURN
RETLW
RETFIE

• Instruções de controle de Bit e
Teste de variáveis
BCF
BSF
BTFSS
BTFSC
INCFSZ
DECFSZ
• Instruções de controle ao
Processamento
NOP
CLRWDT
SLEEP


MOVLW Escrever constante no registro W
Sintaxe: MOVLW k
Descrição: A constante de 8-bits k vai para o registro W.
Operação:
k ( W )
Operando:
0 ≤ k ≤ 255
Flag: -
Número de
palavras:
1
Número de ciclos: 1
MOVLW 0x5A Exemplo 1:
Depois da instrução: W= 0x5A
MOVLW REGISTRAR
Antes da instrução: W = 0x10 e REGISTRAR = 0x40
Exemplo 2:
Depois da instrução: W = 0x40


MOVWF Copiar W para f
Sintaxe: MOVWF f
Descrição: O conteúdo do registro W é copiado para o registro f
Operação:
W ( f )
Operando:
0 ≤ f ≤ 127
Flag: -
Curso de Programação PIC 28/28
Número de
palavras:
1
Número de ciclos: 1
MOVWF OPTION_REG
Antes da instrução: OPTION_REG = 0x20
W = 0x40
Depois da instrução: OPTION_REG = 0x40
Exemplo 1:
W = 0x40
MOVWF INDF
Antes da instrução: W = 0x17
FSR = 0xC2
Conteúdo do endereço 0xC2 = 0x00
Depois da instrução: W = 0x17
FSR = 0xC2
Exemplo 2:
Conteúdo do endereço 0xC2 = 0x17

MOVF Copiar f para d
Sintaxe:
MOVF f, d
O conteúdo do registo f é guardado no local determinado pelo
operando d
Se d = 0, o destino é o registro W
Se d = 1, o destino é o próprio registro f
Descrição:
A opção d = 1, é usada para testar o conteúdo do registro f,
porque a execução desta instrução afeta a flag Z do registro
STATUS.
Operação:
f ( d )
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
MOVF FSR, 0
Antes da instrução: FSR = 0xC2
W = 0x00
Depois da instrução: W = 0xC2
Exemplo 1:
Z = 0
MOVF INDF, 0
Antes da instrução: W = 0x17
FSR = 0xC2
Exemplo 2:
conteúdo do endereço 0xC2 = 0x00
Curso de Programação PIC 29/29
Depois da instrução: W = 0x00
FSR = 0xC2
conteúdo do endereço 0xC2 = 0x00

Z = 1




CLRW Escrever 0 em W
Sintaxe: CLRW
Descrição: O conteúdo do registo W passa para 0 e a flag Z do registro
STATUS toma o valor 1.
Operação:
0 ( W )
Operando: -
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
CLRW
Antes da instrução: W = 0x55
Depois da instrução: W = 0x00
Exemplo:
Z = 1

CLRF Escrever 0 em f
Sintaxe: CLRF f
Descrição: O conteúdo do registro 'f' passa para 0 e a flag Z do registro
STATUS toma o valor 1.
Operação:
0 f
Operando:
0 ≤ f ≤ 127
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
CLRF STATUS
Antes da instrução: STATUS = 0xC2
Depois da instrução: STATUS = 0x00
Exemplo 1:
Z = 1
CLRF INDF
Antes da instrução: FSR = 0xC2
conteúdo do endereço 0xC2 = 0x33
Exemplo 2:
Depois da instrução: FSR = 0xC2
Curso de Programação PIC 30/30
conteúdo do endereço 0xC2 = 0x00
Z = 1




SWAPF Copiar o conteúdo de f para d, trocando a posição
dos 4 primeiros bits
com a dos 4 últimos
Sintaxe: SWAPF f, d
Os 4 bits + significativos e os 4 bits - significativos de f, trocam
de posições.
Se d = 0, o resultado é guardado no registro W
Descrição:
Se d = 1, o resultado é guardado no registro f
Operação:
f <0:3> d <4:7>, f <4:7> d <0:3>,
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: -
Número de
palavras:
1
Número de ciclos: 1
SWAPF REG, 0
Antes da instrução: REG = 0xF3
Depois da instrução: REG = 0xF3
Exemplo 1:
W = 0x3F
SWAPF REG, 1
Antes da instrução: REG = 0xF3
Exemplo 2:
Depois da instrução: REG = 0x3F



ADDLW Adicionar W a uma constante
Sintaxe: ADDLW k
Descrição: O conteúdo do registro W, é adicionado à constante de 8-bits k e
o resultado é guardado no registro W.
Operação:
( W ) + k W
Operando:
0 ≤ k ≤ 255
Flag: C, DC, Z
Número de
palavras:
1
Número de ciclos: 1
ADDLW 0x15 Exemplo 1:
Antes da instrução: W= 0x10
Curso de Programação PIC 31/31
Depois da instrução: W= 0x25
ADDLW REG
Antes da instrução: W = 0x10
REG = 0x37
Exemplo 2:
Depois da instrução: W = 0x47




ADDWF Adicionar W a f
Sintaxe: ADDWF f, d
Adicionar os conteúdos dos registros W e f
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
(W) + ( f ) d, d ∈ [0, 1]
Operando:
0 ≤ f ≤ 127
Flag: C, DC, Z
Número de
palavras:
1
Número de ciclos: 1
ADDWF FSR, 0
Antes da instrução: W = 0x17
FSR = 0xC2
Depois da instrução: W = 0xD9
Exemplo 1:
FSR = 0xC2
ADDWF INDF,0
Antes da instrução: W = 0x17
FSR = 0xC2
conteúdo do endereço 0xC2 = 0x20
Depois da instrução: W = 0x37
FSR = 0xC2
Exemplo 2:
Conteúdo do endereço 0xC2 = 0x20

SUBLW Subtrair W a uma constante
Sintaxe: SUBLW k
Descrição: O conteúdo do registro W, é subtraído à constante k e, o
resultado, é guardado no registro W.
Operação:
k - ( W ) W
Operando:
0 ≤ k ≤ 255
Flag: C, DC, Z
Número de 1
Curso de Programação PIC 32/32
palavras:
Número de ciclos: 1
SUBLW 0x03
Antes da instrução: W= 0x01, C = x, Z = x
Depois da instrução: W= 0x02, C = 1, Z = 0 Resultado
> 0
Antes da instrução: W= 0x03, C = x, Z = x
Depois da instrução: W= 0x00, C = 1, Z = 1 Resultado
= 0
Antes da instrução: W= 0x04, C = x, Z = x
Exemplo 1:
Depois da instrução: W= 0xFF, C = 0, Z = 0 Resultado
< 0
SUBLW REG
Antes da instrução: W = 0x10
REG = 0x37
Depois da instrução: W = 0x27
Exemplo 2:
C = 1 Resultado > 0

SUBWF Subtrair W a f
Sintaxe: SUBWF f, d
O conteúdo do registro W é subtraído ao conteúdo do registro f
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
( f ) - (W) d
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: C, DC, Z
Número de
palavras:
1
Número de ciclos: 1
SUBWF REG, 1
Antes da instrução: REG= 3, W= 2, C = x, Z = x
Depois da instrução: REG= 1, W= 2, C = 1, Z = 0
Resultado > 0
Antes da instrução: REG= 2, W= 2, C = x, Z = x
Depois da instrução: REG=0, W= 2, C = 1, Z = 1
Resultado = 0
Antes da instrução: REG=1, W= 2, C = x, Z = x
Exemplo:
Depois da instrução: REG= 0xFF, W=2, C = 0, Z =
0 Resultado < 0

ANDLW Fazer o “E” lógico de W com uma constante
Sintaxe: ANDLW k
Curso de Programação PIC 33/33
É executado o "E¨ lógico do conteúdo do registro W, com a
constante k
Descrição:
O resultado é guardado no registro W.
Operação:
( W ) .AND. k W
Operando:
0 ≤ k ≤ 255
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
ANDLW 0x5F
Antes da instrução: W= 0xA3 ; 0101 1111
(0x5F)
; 1010
0011 (0xA3)
Exemplo 1:
Depois da instrução: W= 0x03; 0000
0011 (0x03)
ANDLW REG
Antes da instrução: W = 0xA3 ; 1010
0011 (0xA3)
REG = 0x37 ; 0011
0111 (0x37)
Exemplo 2:
Depois da instrução: W = 0x23 ; 0010
0011 (0x23)

ANDWF Fazer o “E” lógico de W com f
Sintaxe: ANDWF f, d
Faz o "E¨ lógico dos conteúdos dos registros W e f
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
(W) .AND. ( f ) d
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
ANDWF FSR, 1
Antes da instrução: W= 0x17, FSR= 0xC2; 0001 1111
(0x17)
; 1100 0010
(0xC2)
Exemplo 1:
Depois da instrução: W= 0x17, FSR= 0x02 ; 0000 0010
(0x02)
Exemplo 2: ANDWF FSR, 0
Curso de Programação PIC 34/34
Antes da instrução: W= 0x17, FSR= 0xC2; 0001
1111 (0x17)
; 1100
0010 (0xC2)

Depois da instrução: W= 0x02, FSR= 0xC2; 0000 0010
(0x02)

IORLW Fazer o “OU” lógico de W com uma constante
Sintaxe: IORLW k
Descrição: É executado o "OU¨ lógico do conteúdo do registro W, com a
constante de 8 bits k, o resultado é guardado no registro W.
Operação:
( W ) .OR. k W
Operando:
0 ≤ k ≤ 255
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
IORLW 0x35
Antes da instrução: W= 0x9A
Depois da instrução: W= 0xBF
Exemplo 1:
Z= 0
IORLW REG
Antes da instrução: W = 0x9A
conteúdo de REG = 0x37
Depois da instrução: W = 0x9F
Exemplo 2:
Z = 0

IORWF Fazer o “OU” lógico de W com f
Sintaxe: IORWF f, d
Faz o "OU¨ lógico dos conteúdos dos registos W e f
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
(W) .OR. ( f ) d
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
IORWF REG, 0
Antes da instrução: REG= 0x13, W= 0x91
Exemplo 1:
Depois da instrução: REG= 0x13, W= 0x93
Curso de Programação PIC 35/35
Z= 0
IORWF REG, 1
Antes da instrução: REG= 0x13, W= 0x91
Depois da instrução: REG= 0x93, W= 0x91
Exemplo 2:
Z= 0

XORLW “OU- EXCLUSIVO” de W com uma constante
Sintaxe: XORLW k
Descrição: É executada a operação "OU-Exclusivo¨ do conteúdo do registro
W, com a constante k. O resultado é guardado no registro W.
Operação:
( W ) .XOR. k W
Operando:
0 ≤ k ≤ 255
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
XORLW 0xAF
Antes da instrução: W= 0xB5 ; 1010 1111
(0xAF)
; 1011 0101
(0xB5)
Exemplo 1:
Depois da instrução: W= 0x1A; 0001 1010
(0x1A)
XORLW REG
Antes da instrução: W = 0xAF ; 1010 1111
(0xAF)
REG = 0x37 ; 0011 0111
(0x37)
Depois da instrução: W = 0x98 ; 1001 1000
(0x98)
Exemplo 2:
Z = 0

XORWF “OU-EXCLUSIVO” de W com f
Sintaxe: XORWF f, d
Faz o "OU-EXCLUSIVO¨ dos conteúdos dos registros W e f
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
(W) .XOR. ( f ) d
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: Z
Número de
palavras:
1
Curso de Programação PIC 36/36
Número de ciclos: 1
XORWF REG, 1
Antes da instrução: REG= 0xAF, W= 0xB5 ; 1010
1111 (0xAF)
; 1011 0101
(0xB5)
Exemplo 1:
Depois da instrução: REG= 0x1A, W= 0xB5 001
1010 (0x1A)
XORWF REG, 0
Antes da instrução: REG= 0xAF, W= 0xB5; 1010
1111 (0xAF)
; 1011 0101
(0xB5)
Exemplo 2:
Depois da instrução: REG= 0xAF, W= 0x1A ; 0001
1010 (0x1A)

INCF Incrementar f
Sintaxe: INCF f, d
Incrementar de uma unidade, o conteúdo do registro f.
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
( f ) + 1 d
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
INCF REG, 1
Antes da instrução: REG = 0xFF
Z = 0
Depois da instrução: REG = 0x00
Exemplo 1:
Z = 1
INCF REG, 0
Antes da instrução: REG = 0x10
W = x
Z = 0
Depois da instrução: REG = 0x10
W = 0x11
Exemplo 2:
Z = 0

DECF Decrementar f
Sintaxe: DECF f, d
Curso de Programação PIC 37/37
Decrementar de uma unidade, o conteúdo do registro f.
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
( f ) - 1 d
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
DECF REG, 1
Antes da instrução: REG = 0x01
Z = 0
Depois da instrução: REG = 0x00
Exemplo 1:
Z = 1
DECF REG, 0
Antes da instrução: REG = 0x13
W = x
Z = 0
Depois da instrução: REG = 0x13
W = 0x12
Exemplo 2:
Z = 0

RLF Rodar f para a esquerda através do Carry
Sintaxe: RLF f, d
O conteúdo do registro f é rodado um espaço para a esquerda,
através de C (flag do Carry).
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
( f <n>) d<n+1>, f<7> C, C d<0>;
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: C
Número de
palavras:
1
Número de
ciclos:
1

RLF REG, 0
Antes da instrução: REG = 1110 0110
C = 0
Exemplo 1:
Depois da instrução: REG = 1110 0110
Curso de Programação PIC 38/38
W = 1100 1100
C = 1
RLF REG, 1
Antes da instrução: REG = 1110 0110
C = 0
Depois da instrução: REG = 1100 1100
Exemplo 2:
C = 1

RRF Rodar f para a direita através do Carry
Sintaxe: RRF f, d
O conteúdo do registro f é rodado um espaço para a direita,
através de C (flag do Carry).
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
( f <n>) d<n-1>, f<0> C, C d<7>;
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: C
Número de
palavras:
1
Número de ciclos: 1

RRF REG, 0
Antes da instrução: REG = 1110 0110
W = x
C = 0
Depois da instrução: REG = 1110 0110
W = 0111 0011
Exemplo 1:
C = 0
RRF REG, 1
Antes da instrução: REG = 1110 0110
C = 0
Depois da instrução: REG = 0111 0011
Exemplo 2:
C = 0

COMF Complementar f
Sintaxe: COMF f, d
O conteúdo do registro f é complementado.
Se d=0, o resultado é guardado no registro W
Descrição:
Se d=1, o resultado é guardado no registro f
Operação:
() d
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Curso de Programação PIC 39/39
Flag: Z
Número de
palavras:
1
Número de ciclos: 1
COMF REG, 0
Antes da instrução: REG= 0x13 ; 0001 0011 (0x13)
Depois da instrução: REG= 0x13 ; complementar
Exemplo 1:
W = 0xEC ; 1110 1100 (0xEC)
COMF INDF, 1
Antes da instrução: FSR= 0xC2
conteúdo de FSR = (FSR) = 0xAA
Depois da instrução: FSR= 0xC2
Exemplo 2:
conteúdo de FSR = (FSR) = 0x55

BCF Pôr a “0” o bit b de f
Sintaxe: BCF f, b
Descrição: Limpar (pôr a `0´), o bit b do registro f
Operação:
0 f<b>
Operando:
0 ≤ f ≤ 127, 0 ≤ b ≤ 7
Flag: -
Número de
palavras:
1
Número de ciclos: 1
BCF REG, 7
Antes da instrução: REG = 0xC7 ; 1100 0111 (0xC7)
Exemplo 1:
Depois da instrução: REG = 0x47 ; 0100 0111 (0x47)
BCF INDF, 3
Antes da instrução: W = 0x17
FSR = 0xC2
conteúdo do endereço em FSR (FSR) = 0x2F
Depois da instrução: W = 0x17
FSR = 0xC2
Exemplo 2:
conteúdo do endereço em FSR (FSR) = 0x27

BSF Pôr a “1” o bit b de f
Sintaxe: BSF f, b
Descrição: Pôr a `1´, o bit b do registro f
Operação:
1 f<b>
Operando:
0 ≤ f ≤ 127, 0 ≤ b ≤ 7
Flag: -
Curso de Programação PIC 40/40
Número de
palavras:
1
Número de ciclos: 1
BSF REG, 7
Antes da instrução: REG = 0x07 ; 0000 0111 (0x07)
Exemplo 1:
Depois da instrução: REG = 0x17 ; 1000 0111 (0x87)
BSF INDF, 3
Antes da instrução: W = 0x17
FSR = 0xC2
conteúdo do endereço em FSR (FSR) = 0x2F
Depois da instrução: W = 0x17
FSR = 0xC2
Exemplo 2:
conteúdo do endereço em FSR (FSR) = 0x28

BTFSC Testar o bit b de f, saltar por cima se for = 0
Sintaxe: BTFSC f, b
Descrição: Se o bit b do registro f for igual a zero, ignorar instrução
seguinte. Se este bit b for zero, então, durante a execução da
instrução atual, a execução da instrução seguinte não se
concretiza e é executada, em vez desta, uma instrução NOP,
fazendo com que a instrução atual, demore dois ciclos de
instrução a ser executada.
Operação: Ignorar a instrução seguinte se (f<b>) = 0
Operando:
0 ≤ f ≤ 127, 0 ≤ b ≤ 7
Flag: -
Número de
palavras:
1
Número de ciclos: 1 ou 2 dependendo do valor lógico do bit b
LAB_01 BTFSC REG, 1; Testar o bit 1 do registo REG
LAB_02 ........... ; Ignorar esta linha se for 0
LAB_03 ........... ; Executar esta linha depois da
anterior, se for 1
Exemplo:
Antes da instrução, o contador de programa contém o endereço
LAB_01.
Depois desta instrução, se o bit 1 do registo REG for zero, o
contador de programa contém o endereço LAB_03. Se o bit 1 do
registo REG for `um´, o contador de programa contém o endereço
LAB_02.

BTFSS Testar o bit b de f, saltar por cima se for = 1
Sintaxe: BTFSS f, b
Descrição: Se o bit b do registro f for igual a um, ignorar instrução seguinte.
Se durante a execução desta instrução este bit b for um, então, a
execução da instrução seguinte não se concretiza e é executada,
Curso de Programação PIC 41/41
em vez desta, uma instrução NOP, assim, a instrução atual
demora dois ciclos de instrução a ser executada.
Operação: Ignorar a instrução seguinte se (f<b>) = 1
Operando:
0 ≤ f ≤ 127, 0 ≤ b ≤ 7
Flag: -
Número de
palavras:
1
Número de ciclos: 1 ou 2 dependendo do valor lógico do bit b
LAB_01 BTFSS REG, 1; Testar o bit 1 do registro REG
LAB_02 ........... ; Ignorar esta linha se for 1
LAB_03 ........... ; Executar esta linha depois da
anterior, se for 0
Exemplo:
Antes da instrução, o contador de programa contém o endereço
LAB_01.
Depois desta instrução, se o bit 1 do registro REG for `um´, o
contador de programa contém o endereço LAB_03. Se o bit 1 do
registro REG for zero, o contador de programa contém o endereço
LAB_02.

INCFSZ Incrementar f, saltar por cima se der = 0
Sintaxe: INCFSZ f, d
Descrição: O conteúdo do registro f é incrementado de uma
unidade.
Se d = 0, o resultado é guardado no registro W.
Se d = 1, o resultado é guardado no registro f.
Descrição:
Se o resultado do incremento for = 0, a instrução seguinte é
substituída por uma instrução NOP, fazendo com que a instrução
atual, demore dois ciclos de instrução a ser executada.
Operação:
(f) + 1 d
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: -
Número de
palavras:
1
Número de ciclos: 1 ou 2 dependendo do resultado
LAB_01 INCFSZ REG, 1; Incrementar o conteúdo de REG de
uma unidade
LAB_02 ........... ; Ignorar esta linha se resultado = 0
Exemplo:
LAB_03 ........... ; Executar esta linha depois da
anterior, se der 0
Curso de Programação PIC 42/42
Conteúdo do contador de programa antes da instrução, PC =
endereço LAB_01. Se o conteúdo do registro REG depois de a
operação REG = REG + 1 ter sido executada, for REG = 0, o
contador de programa aponta para o rótulo de endereço LAB_03.
Caso contrário, o contador de programa contém o endereço da
instrução seguinte, ou seja, LAB_02.

DECFSZ Decrementar f, saltar por cima se der = 0
Sintaxe: DECFSZ f, d
O conteúdo do registro f é decrementado uma unidade.
Se d = 0, o resultado é guardado no registro W.
Se d = 1, o resultado é guardado no registro f.
Descrição:
Se o resultado do decremento for = 0, a instrução seguinte é
substituída por uma instrução NOP, fazendo assim com que a
instrução atual, demore dois ciclos de instrução a ser executada.
Operação:
(f) - 1 d
Operando:
0 ≤ f ≤ 127, d ∈ [0, 1]
Flag: -
Número de
palavras:
1
Número de ciclos: 1 ou 2 dependendo do resultado
LAB_01 DECFSZ REG, 1; Decrementar o conteúdo de REG de
uma unidade
LAB_02 ........... ; Ignorar esta linha se resultado = 0
LAB_03 ........... ; Executar esta linha depois da
anterior, se der 0
Exemplo:
Conteúdo do contador de programa antes da instrução, PC =
endereço LAB_01.
Se o conteúdo do registro REG depois de a operação REG = REG
- 1 ter sido executada, for REG = 0, o contador de programa
aponta para o rótulo de endereço LAB_03. Caso contrário, o
contador de programa contém o endereço da instrução seguinte,
ou seja, LAB_02.

GOTO Saltar para o endereço
Sintaxe: GOTO k
Descrição: Salto incondicional para o endereço k.
Operação:
k PC<10:0>, (PCLATH<4:3>) PC<12:11>
Operando:
0 ≤ k ≤ 2048
Flag: -
Número de
palavras:
1
Número de ciclos: 2
Exemplo: LAB_00 GOTO LAB_01; Saltar para LAB_01
Curso de Programação PIC 43/43
:
LAB_01 ............
Antes da instrução: PC = endereço LAB_00

Depois da instrução: PC = endereço LAB_01

CALL Chamar um programa
Sintaxe: [rótulo] CALL k
Descrição: Esta instrução, chama um subprograma. Primeiro, o endereço de retorno
(PC+1) é guardado na pilha, a seguir, o operando k de 11 bits,
correspondente ao endereço de início do subprograma, vai para o
contador de programa (PC).
Operação:
PC+1 Topo da pilha (TOS – Top Of Stack)
Operando:
0 ≤ k ≤ 2048
Flag: -
Número de
palavras:
1
Número de ciclos: 2
LAB_00 CALL LAB_02 ; Chamar a subrotina LAB_02
LAB_01 :
:
LAB_02 ............
Antes da instrução: PC = endereço LAB_00
TOS = x
Depois da instrução: PC = endereço LAB_02
Exemplo:
TOS = LAB_01

RETURN Retorno de um subprograma
Sintaxe: RETURN
Descrição: O conteúdo do topo da pilha é guardado no contador de
programa.
Operação:
TOS Contador de programa PC
Operando: -
Flag: -
Número de
palavras:
1
Número de ciclos: 2
RETURN
Antes da instrução: PC = x
TOS = x
Depois da instrução: PC = TOS
Exemplo:
TOS = TOS - 1

Curso de Programação PIC 44/44
RETLW Retorno de um subprograma com uma constante em W
Sintaxe: RETLW k
Descrição: A constante k de 8 bits, é guardada no registro W.
Operação:
(k) W; TOS PC
Operando:
0 ≤ k ≤ 255
Flag: -
Número de
palavras:
1
Número de ciclos: 2
RETLW 0x43
Antes da instrução: W = x
PC = x
TOS = x
Depois da instrução: W = 0x43
PC = TOS
Exemplo:
TOS = TOS - 1

RETFIE Retorno de uma rotina de interrupção
Sintaxe: RETLW k
Descrição: Retorno de uma subrotina de atendimento de interrupção. O
conteúdo do topo de pilha (TOS), é transferido para o contador
de programa (PC). Ao mesmo tempo, as interrupções são
habilitadas, pois o bit GIE de habilitação global das interrupções,
é posto a `1´.
Operação:
TOS PC ; 1 GIE
Operando: -
Flag: -
Número de
palavras:
1
Número de ciclos: 2
RETFIE
Antes da instrução: PC = x
GIE = 0
Depois da instrução: PC = TOS
Exemplo:
GIE = 1

NOP Nenhuma operação
Sintaxe: NOP
Descrição: Nenhuma operação é executada, nem qualquer flag é afectada.
Operação: -
Operando: -
Flag: -
Curso de Programação PIC 45/45
Número de
palavras:
1
Número de ciclos: 1
Exemplo: NOP

CLRWDT Iniciar o temporizador do watchdog
Sintaxe: CLRWDT
Descrição: O temporizador do watchdog é reposto a zero. O prescaler do
temporizador de Watchdog é também reposto a 0 e, também, os
bits do registro de estado e são postos a `um´.
0 WDT
0 prescaler de WDT
1
Operação:
1
Operando: -
Flag:
Número de
palavras:
1
Número de ciclos: 1
CLRWDT
Antes da instrução: Contador de WDT = x
Prescaler de WDT = 1:128
Depois da instrução: Contador do WDT = 0x00
Prescale do WDT = 0

Exemplo:


SLEEP Modo de repouso
Sintaxe: SLEEP
Descrição: O processador entra no modo de baixo consumo. O oscilador
pára. O bit (Power Down) do registro Status é reposto a `0´. O bit
(Timer Out) é posto a `1´. O temporizador de WDT (Watchdog) e
o respectivo prescaler são repostos a `0´.
0 WDT
0 prescaler do WDT
1 ΤΟ
Operação:
0 PD
Operando: -
Flag:
Número de
palavras:
1
Curso de Programação PIC 46/46
Número de ciclos: 1
SLEEP
Antes da instrução: Contador do WDT = x
Prescaler do WDT = x
Depois da instrução: Contador do WDT = 0x00
Prescaler do WDT = 0

Exemplo 1:









































Curso de Programação PIC 47/47
Apêndice 2 – Biblioteca de Rotinas

Conteúdo: 1- Introdução 2- O que é preciso 3- O que é preciso saber 4- Arquitetura ao PIC16F84 5- Conjunto de Instruções 6- Um programa simples para o PIC16F84 7- Usando MPLAB para depurar um programa 8- O Conjunto de Instruções Formato da Instrução O Registrador STATUS 8.1- Instruções Move MOVF f,d (Move f) MOVWF f (Move W para f) MOVLW k (Move literal para W) 8.2- Instruções Clear CLRF f (Limpa f) CLRW (Limpa W) 8.3- Instruções Aritméticas ADDWF f,d (Soma W & f) SUBWF f,d (Subtrai W de f) ADDLW k (Soma literal e W) SUBLW k (Subtrai W de literal) 8.4- Funções Lógicas ANDWF f,d (E W com f) IORWF f,d (Inclusive OU W com f) XORWF f,d (Exclusive OU W com f) ANDLW k (E literal com W) IORLW k (Inclusive OU literal com W) XORLW k (Exclusive OU literal com W) COMF f,d (Complemento f) 8.5- Decrementando & Incrementando DEC f,d (Decrementa f) INC f,d (Incrementa f) 8.6- Ligando e limpando Bit BCF f,b (Bit limpa f) BSF f,b (Bit liga f) 8.7- Controle do Programa GOTO k (Vai para endereço) CALL k (Chama sub-rotina) RETURN (Retorna de sub-rotina) RETLW k (Retorna com literal em W) RETFIE (Retorna de Interrupção)

Curso de Programação PIC

2/2

8.8- Instruções Skip DECFSZ f,d (Decrementa f, ignora se 0) INCFSZ f,d (Incrementa f, ignora se 0) BTFSC f,b (Bit testa f, ignora se limpo) BTFSS f,b (Bit testa f, ignora se ligado) 8.9- Rotações e Troca RRF f,d (Rotaciona f para a direita por transporte) RLF f,d (Rotaciona f para a esquerda por transporte) SWAPF f,d (Troca os meio-bytes em f) 8.10- Sleep & Timer Watchdog SLEEP (Sleep,) CLRWDT (Limpa o timer watchdog.) 8.11- Miscelânea NOP (Nenhuma operação) OPTION (Não recomendado) TRIS (N]ao recomendado) Pausa para refletir Interrupções no PIC16F84 O que é uma interrupção? Tipos de interrupção e o registrador INTCON Lidando com uma interrupção Timers no PIC16F84 A Idéia básica O módulo TIMER0 Usando overflow do timer Usando a memória de dados EEPROM 9- Interrupções no 84 9.1- Tipos de Interrupção e o registrador INTCON 9.2- Lidando com uma Interrupção 9.3- Timers no '84 9.4- O Módulo TIMER0 9.5- Usando o estouro do timer

Curso de Programação PIC

3/3

Ao se deparar na programação PIC 16F84, ao primeiro momento parece ser muito complexo. A folha de dados (Datasheet) do PIC16F84 da Microchip é um excelente documento técnico e o manual do MPASM é um guia de referência completo. Porém, utilizando somente deles são insuficientes para saber e entender a sua programação. Assim este trabalho é um tutorial para programar o PIC16F84, abrangendo o conjunto de instruções e algumas diretivas do MPASM. Pelo seu conteúdo ele cobre o próprio PIC16F84 em termos de registros, pinos e assim por diante. No final, é esperado do aluno que ele esteja bastante à vontade para dar início aos primeiros passos de sua programação deste dispositivo. Primeiro, é preciso ter em mãos alguma da documentação da Microchip. Como um mínimo, é necessária a folha de dados (Datasheet) do PIC16F84. Ela contém toda a informação real que necessário do próprio chip. Também deve se em mãos o Guia de usuário do MPASM. Ambos estes estão disponíveis no site da Microchip (http://www.microchip.com/). Faz-se necessário também o aplicativo MPLAB (for Windows) instalado no PC, pois o mesmo possui o Ambiente de Desenvolvimento Interativo (IDE) deles, e contém um editor, o assembler e um simulador. Aqui, você pode criar seu código fonte (editor), produzir o código executável (assembler) e executar no seu PC (simulador). No simulador, pode-se observar a execução do programa enquanto mantém a vista nos registros e pode-se até mesmo simular eventos como mudanças causadas por fatores externos nos pinos de I/O. É interessante realmente adquiri-lo, pois também está disponível como o manual do MPASM. Entendendo-se os apéctos básicos e funcionais destes aplicativos irá a facilitar muito o entendimento da maioria dos tópicos que está sendo abordado neste trabalho. O Simulador (Emulador) é muito bom para observar os registradores e executar um programa em um modo passo a passo, mas isso não resolve todos os problemas quando uma eventual falha ocorrer. O modo passo a passo não leva em conta o efeito de uma entrada em um programa e uma rotina de delay deve ser ignorada para se prevenir horas de espera para a execução do programa. Isso é tudo que é preciso, mas há muito mais coisas das quais pode ser apreciado. Não menos, um chip PIC16F84 e um programador. O programador GTP-Gravador Testador PIC apresentado no curso é o equipamento mais barato no mercado e vem com a vantagem da não necessidade retirar o microprocessador da placa para se efetuar os testes o que tornaria os processos de desenvolvimento ou estudo mais moroso e de certa forma evitaria assim erros ou acidentes durante o intercambio entre o gravador e a placa de testes, caso fossem utilizados separadamente. Para um trabalho mais complexo, as Notas de Aplicação da Microchip (ANs) também são de extrema ajuda. Estas notas cobrem todos os tipos de usos dos PIC’s, com muitas dicas úteis para uso no mundo real. As ANs estão em formato Adobe .pdf: Usando o Adobe Acrobat você pode procurar pelas ANs por situações como 'motor' ou 'serial' e ler as anotações destinadas às suas necessidades. Um das notas, AN585 sobre sistemas operacionais de tempo real para o PIC, refereCurso de Programação PIC 4/4

1- Introdução

2- O Quê é preciso

como bits. É de extremamente interessante que se tenha uma cópia pois é em tutorial fascinante sobre todo o assunto das interrupções. e a saída.Ele possui: Um processador. registradores. uma vez que qualquer processo consiste em 3 partes: a entrada para o processo.Tópicos Negligenciados. o dispositivo inclui quatro tipos de interrupção e 13 pinos de I/O. o acionamento de um botão poderia interromper o fluxo normal do programa e poderia executar alguma operação especial.O que é preciso saber Para uma maior facilidade de entendimento e conseqüentemente um melhor aproveitamento nas atividades deste trabalho proposto. Além disso. 3FFhex são 1023 em notação decimal. e isso é tudo que nós precisamos saber. controle de laço-fechado e similares. 3. por exemplo. Alguns têm funções especiais que é examinado neste trabalho. sendo assim há 1024 locais que incluem 000. PORTA. O PIC16F84 tem 64 bytes de memória de dados. Os 90 registradores são a área de armazenamento interno do processador. 68 são registradores de propósito gerais. Interrupções são uns meios de parar a execução do programa e atender a uma operação definida pela interrupção. O uso dessa memória EEPROM será analisado por último. A memória vai do endereço 000h até o 3FFh. Por exemplo. PORTA armazena os conteúdos de uma das portas de I/O. Dos 90 registradores. bytes & EEPROM e conceitos como binário e hexa. • • O PIC16F84 tem um processador de 8-bits.Arquitetura do PIC16F84 Um microcontrolador como o PIC16F84 é por sua natureza. 4. Estes têm nomes como (STATUS. valores para ajuste de dados recebidos do mundo externo. Por exemplo. e será usado mais adiante. O PIC16F84 tem 13 pinos configurados como 2 porta: porta A tem 5 pinos e a porta B tem 8. isto é a chamada porta A. o próprio processo. programa e memória de dados. um computador completo em um chip. O PIC16F84 tem uma memória de programa de 1k. chamados de memória de EEPROM a qual é usada para armazenamento de. É examinadas posteriormente as técnicas de interrupção do PIC16F84. seria interessante ter algum conhecimento prévio sobre algumas terminologias básicas dos computadores. (Unidade de Processador Central) que tem só o processador e registradores.se à Programação de Tempo Real . 5/5 • • • • Curso de Programação PIC . Isso significa que há 1024 locais para programa. Isto o faz diferente de uma CPU. e podem ser considerados como utilitários (ao contrário daqueles especiais do processador) pois podem ser usados como 'bloco de rascunho''. etc). O uso dos pinos de I/O é a chave para o uso de um dispositivo como os '84.

Assim. e será visto isto em muitas instruções. como por exemplo: PORTA é 05h. Será visto este mesmo layout em todas as instruções. que é na realidade o décimo sexto arquivo na memória. nós podemos entender que o comando ADDWF soma W ao arquivo F. Dependendo da exigência. a qual será visto posteriormente logo mais adiante. Basicamente. Curso de Programação PIC 6/6 . Alguns arquivos têm nomes. em lugar da função. é codificada a instrução: "some W ao arquivo 3C" como: ADDWF 3Ch.5. Se 'd' for 0. Mais tarde será utilizada cada uma dessas operações.d Bem. O registrador de trabalho é um registrador especial (acima de todos já mencionados). A letra minúscula "h" sempre é incluída para indicar que arquivo tem um valor hexadecimal. por exemplo. Não há nenhum arquivo chamado "F" ou "f". o resultado estará em W. conhecido como registrador W e é onde a unidade aritmética e lógica (ALU) faz os cálculos. o arquivo 0C é chamado "0C". Os outros registradores são conhecidos como arquivos e nós usamos a letra 'F' nos comandos para indicar que um arquivo está sendo acessado. Será focado mais no formato. Por enquanto. arquivo 10 é chamado "10" e arquivo 2F é chamado "2F”. Qualquer instrução com W no nome age em W. o resultado da instrução pode ser posto no registro de funcionamento (W) ou no próprio arquivo F. serão analisadas apenas para uma das instruções. como arquivo 10h. o opcode especifica o que fazer e o(s) operando(s) especificam como ou onde. Se 'd' for 1. Estas instruções são divididas em 3 grupos: orientadas por byte.d Onde ADDWF é o opcode e "f d" são os operandos. Por exemplo. As letras ADDWF são chamadas de um mnemônico. Mas o que é arquivo F? Para cada arquivo (diferente de W) é determinado um endereço hexadecimal. Isso é um símbolo para representar qualquer um dos arquivos. o resultado estará em F. A sintaxe desta instrução é: ADDWF f. Assim. orientadas a bit e literal & controle. não totalmente .Conjunto de instruções Há 35 instruções no conjunto de instruções do PIC16F84. Esta é uma abreviação que tanto o computador quanto os humanos podem entender. PORTB é 06h e TRISA é 85h. Foi escolhida a instrução ADDWF. O 'f' na instrução acima é o endereço atual do arquivo. consistindo em um opcode (código de operação) e operando(s).para que serve aquele 'd'? É o destino do resultado.

MyReg_1&2 movlw H'08' . já que .***************** setup *************************** processor 16F84 . apresenta também alguns conceitos do assembler e vai também mostrar algumas técnicas simples para o simulador. MyReg_1 e 10h são a mesma coisa. a resposta vai para w end Curso de Programação PIC 7/7 .asm é apresentado abaixo.coloca 32h no registrador W addwf MyReg_1.posição Meus Registradores na memória MyReg_2 equ H'15' . Simple. O programa. já que .move o conteúdo de w para MyReg_1 . isso é bem mais claro f equ 1 MyReg_1 equ H'10' .coloca 26h no acumulador W subwf MyReg_2.f .subtrai w de MyReg_2 .e introduzir algumas instruções e diretivas .asm .move o conteúdo de W para MyReg_2 .simple.1.0. movlw 32h .para instruções de byte.Nós vamos carregar o acumulador (reg w) com valores . Programa 1: Simple. em h'10' & H'15' .soma o conteúdo de w àquele em MyReg_1 .w .***************** programa ****************************** . nota – é o mesmo que movwf 15h.asm .tipo de processador org 0010h .coloca o valor H'08' no registrador w movwf MyReg_1 . devido ao f. MyReg_2 e 15h são a mesma coisa. Além de mostrar como usar alguns instruções.Um programa simples para o PIC'84 Este programa de exemplo serve para vários propósitos. use w & f . soma W ao arquivo 3C.origem do programa na memória w equ 0 .para demonstrar o aspecto de um programa .coloca o valor 92h no registrador w movwf MyReg_2 .A instrução pode ser seja qualquer um do seguinte: ADDWF 3Ch. resultado em W ADDWF 3Ch. resultado em 3C 6. nota – é o mesmo que movwf 10h. ao invés de 0 & 1. movlw 26h . movlw 92h . Eu lhe guiarei linha por linha. e efetuar algumas operações aritméticas em W utilizando . a resposta vai para MyReg_1. soma W ao arquivo 3C.

MOVWF f copia o conteúdo de W no registrador f.Usando MPLAB para depurar o programa Este é um processo de três passos: Editar o código fonte.f no lugar de ADDWF 10h. Ele mostra que arquivos têm endereços hexadecimais e de se esperar ler a instrução como MOVWF 10h por exemplo. Todo livro de programação recomenda a criação de comentários para explicar o que está acontecendo. MOVLW k faz o valor k (no exemplo 08h) ser colocado no registrador de trabalho.d respectivamente executam a adição e subtração aritmética nos conteúdos de W e f.1. "org" diz ao assembler aonde começar a colocar o código na memória de programa. Isto é mais fácil de se lembrar durante a codificação. Na parte chamada 'programa'. Notar que movwf é estritamente uma nomenclatura equivocada. ADDWF f. o código será preparado pelo assembler para o processador errado . e também substituir os valores permitidos de d (no exemplo 0 e1) por w e f respectivamente. é encontrada várias instruções do PIC16F84. Montar e executar esse programa. (W) (f) meios que o conteúdo de W se tornam o conteúdo de f." Simplesmente significa que os itens em qualquer lado de equ significam a mesma coisa.Observando-se este exemplo. já que na realidade ocorre uma cópia (W não é esvaziado). Igualando MyReg_1 a 10h. 7. montá-lo e então executá-o no simulador. e não uma movimentação (na qual W seria esvaziado). Você deve colocar seu código além de 004h para ficar claro o endereço para onde o processador deve ir quando uma interrupção é descoberta. Por último. nós encontramos três diretivas do assembler: "processador 16F84" informa ao assembler para qual chip o programa foi escrito.' é um comentário. Na seção chamada 'setup'. O ' f ' em MOVWF f refere-se a um arquivo. quer dizer que podem ser escritos MOVWF MyReg_1 com o mesmo resultado. Curso de Programação PIC 8/8 . Por exemplo. Notar também a convenção da Microchip de comparar movlw e movwf: descrevendo a operação os parênteses () significam 'o conteúdos de'. "equ" é uma equivalência ou "igual a. Podem ser referidos a MyReg_1 como antes. será mais fácil de fazê-lo através do seu nome mais significante e fácil de lembrar. Assim k (W) quer dizer que o valor k se torna o conteúdo de W.d e SUBWF f. certificar de entender o uso do conceito de equ com respeito a registradores. a instrução ADDWF espera um 0 ou 1 no lugar de 'd': igualando 'w' a 0' significa que podem ser utilizados 'w' na instrução em lugar de 0'. Podem ser conferidas as descrições completas que será objeto de estudo mais tarde. pode-se verificar o que irá ser encontrado depois de cada diretiva ou instrução. Analogamente. Qualquer coisa depois de um '. e para ler depois. Note o uso de equivalências aqui também. igualando MyReg_1 a 10h toda vez que ao se referir ao registrador. Conseqüentemente podem ser escritos ADDWF MyReg_1. Se isto estiver incorreto.

Com estas três janelas. executar o programa passo a passo (o ícone de pegada).e volta para azul no próximo passo (a menos que haja outra mudança). Myreg_1) e então clicar OK. Porém.isto é. Quando se escolher esta janela é mostrada uma caixa de seleção com uma seta para baixo.Com o exemplo. Tentar. Seria útil ter todas abertas simultaneamente para comparar as implementações: Janela > File Register Esta janela lista o conteúdo de todos os registradores de arquivos de 00 a 4F .ie. o que é excelente. Janela > Special Function Registers Aqui você pode ver os SFRs (Registradores de Função Especial) por nome ao invés de local. Usar qualquer uma delas. O conteúdo é mostrado em decimal. mas isso é tudo. À medida que se caminha pelo programa poderá ser visto o conteúdo hexadecimal dos registradores 10h e 15h mudando. ou simplesmente apertar a tecla insert (enquanto a janela está ativa). em neste exemplo. Os outros. como MyReg_1 e2. não mostra aqueles na região 80 a 8B. Porém não se pode esquecer que aquele W é um registrador: então agora há duas entradas de W na lista. e o editor sendo a única janela aberta no MPLAB. e uma lista de todos os registradores aparece: escolher qual irá quer (eg. entram das diretivas de equ em seu código. Agora se pode usar o registro de trabalho no monitoramento. Todas servem a propósitos semelhantes . re-montar e tentar novamente. eles ainda aparecem na lista de possibilidades que pode estar o problema de não se querer escolher. foi utilizado também w equ 0 e f equ 1 embora estes não são planejados como nomes de registro. Note que qualquer registrador cujo conteúdo mudou há pouco é mostrado em vermelho . Os SFRs são óbvios: o MPLAB sabe a respeito deles de qualquer maneira. o que significa que não se pode monitorar o registro de funcionamento se foi declarado um equ de W em seu código. Curso de Programação PIC 9/9 . Pode-se perguntar de onde veio a lista de nomes de registradores para selecionar. então comentando a linha com erro com um ‘. Para adicionar outros registradores pode-se clicar no ícone no canto esquerdo superior da janela e então escolher Add Watch. e é permitido selecionar quais registradores se quer monitorar. Não ajuda muito – pode ser visto cada linha do programa ser realçada à medida que é ativada. caminhar pelo seu programa: agora você tem alguma noção do que está acontecendo. Porém. ver o que está acontecendo nos registradores . pode-se começar a usar algumas das outras facilidades do simulador. e então carregá-las depois através da Janela> Load Watch Window. Será visto o conteúdo do registrador exibido na janela. causa um erro de símbolo não encontrado em sua tabela de observação. uma desde o princípio (o registro de funcionamento) e a que foi criada a outra com equ. Assim.mas todas executam diferentemente. Clicar na seta.'. hexa e binário. Você pode salvar as combinações usadas com mais freqüência como arquivos watch. Janela > New Watch Window Esta é sua janela personalizada para os registradores. Sugerese que seja aberta a seguinte janela no MPLAB. Todos os registradores estão disponíveis para serem escolhidos.asm montado com sucesso. que é o que mostra a janela anterior. SFRs e GPRs.

STATUS <1>. que nada fazem além de colocar coisas nos registradores. e também praticar o uso do simulador. e STATUS <4>. Elas se agrupam em 3 categorias. o resultado vai para W. tal qual é feito neste trabalho logo a seguir. Formato da instrução O agrupamento da Microchip mantém as instruções de formato semelhante juntas. Muitas instruções do '84 afetam certas partes do STATUS.ao bit à esquerda -bit 4). se d=0. MOVF f.d onde f é a designação do arquivo do registrador e d é o destino. um bit é escrito como FILE_REG <n>. e b é o bit dentro dele. Muitas instruções afetam STATUS <2>.b onde f é o arquivo do registrador.o bit Carry. 8. bem como nos registradores W e STATUS. Estas categorias são operações Orientadas a Byte. há uma explicação o que um Inclusive-OU de fato está em IORWF). bits são numerados da direita para a esquerda de 0 a 7.a flag Zero que é ligada se o resultado de uma operação for zero. o que não consideradas particularmente útil. mas permitem usar cada instrução. As instruções aparecem assim: byte_command f. tais como executar operações aritméticas.o bit Digit Carry. por exemplo INTCON <4> significa o bit número 4 no registrador intcon. é ativado se um transporte ocorrer no bit mais a esquerda no resultado.d (Move f) (f) (dest) Curso de Programação PIC 10/10 . é ativado se houver um transporte entre os dígitos hexadecimais (ie. O registrador STATUS O '84 têm o registrador STATUS em 03h. (Por exemplo. Z . o resultado vai para o registrador f. do meio-bit à -bit 3 . Talvez o mais importante ainda é os exercícios sugeridos para usar as instruções apresentadas que são bastante simples. Dois comandos afetam STATUS <3>. como a janela de monitoramento para ver o que está acontecendo a cada passo do seu programa: prestar atenção nos registradores que se decidiu usar. O registrador INTCON fica no local 0B.O Conjunto de Instruções A Microchip tem detalhes completos do conjunto de instruções. o bit Time Out TO. C . Para cada instrução.1: Instruções Move É encontrado algumas dessas instruções. No texto. é explicada a operação. bit_command f. Certas operações afetam os bits de transporte: STATUS <0>. Ele contém o estado aritmético da unidade de aritmética e lógica. o bit Power Down PD. DC . a Bit e a Literal/Controle. Lembrar de se usar os recursos. other_command k onde k é uma constante ou literal de 8-bit.8. Se d=1. O interessante seria em agrupar as instruções dentro daquilo que é utilizado para cada comando.

asm para mostrar como clrf & clrw funcionam .*********************************** setup processor 16F84 reg1 equ h'10' . Solução: Programa 2: Moves. pcl . CLRF f (Clear f) (f) 00h CLRW (Clear W) 00h (W) Exercício: Ampliar o programa anterior para limpar os registradores no final. depois colocar alguma outra coisa em W.*********************************** simulador .moves.restaura w end 8.carrega w movwf reg1 .move (w) para reg1 movlw h'82' . pcl .asm .MOVWF f (Move W to f) (w) (f) MOVLW k (Move literal to W) k (W) Exercício: Escrever um programa para usar estes comandos para (por exemplo) por algo em W. w.*********************************** programa start: movlw h'05' .*********************************** programa start: movlw h'05' .asm .asm . mover de lá para outro registrador.*********************************** setup *** processor 16F84 reg1 equ h'10' *** .carrega w movwf reg1 . MOVWF & MOVLW funcionam . e então mover a coisa original de volta para W.2: Instruções Clear Estes dois comandos limpam um registrador.watch window: reg1.*********************************** simulador *** .baseado em moves.altera w Curso de Programação PIC 11/11 . Solução: Program 3: Clears. w.0 .altera w movf reg1.move (w) para reg1 movlw h'82' .asm para mostrar como MOVF.watch window: reg1.clears.

soma w a reg1.adiciona d'05' a w sublw d'100' .subtrai w de reg2.status.watch window: reg1. A aritmética ocorre entre W e um registrador f: ADDWF f.************************************* programa loads: movlw d'20' . Curso de Programação PIC 12/12 .3: Instruções Aritméticas Executar operações aritméticas é muito importante.w.asm .subtrai w de d'100' addwf reg1.asm para mostrar o uso de ADDWF.0 .carrega w movwf reg1 . dentro de reg2 end Observação: Pode-se ver que a subtração é feita usando o método do segundo complemento.limpa w end 8.reg2.1 .************************************* simulador . Isto pode ser explicado com um exemplo.arith.carrega reg2 arith: addlw d'05' .restaura w clear: clrf reg1 . dentro de reg1 subwf reg2. SUBWF.d (Subtract W from f) (f)-(W) (dest) or between W and a literal: ADDLW k (Add literal & W) (W)+k (W) SUBLW k (Subtract W from literal) k-(W) (W) Exercício: Use estes e os comandos anteriores para carregar um registrador a partir de W e efetuar algumas adições e subtrações.limpa reg1 clrw . Este é o modo normal que a subtração acontece com binários.d (Add W & f) (W)+(f) (dest) SUBWF f.************************************* setup processor 16F84 reg1 equ h'10' reg2 equ h'12' . Preste atenção no bit Carry e no bit Zero no registrador STATUS.carrega w mais uma vez movwf reg2 . ADDLW.carrega reg1 movlw d'80' .1 . Solução: Program 4: Arith.movf reg1. O '84 pode apenas somar e subtrair.pcl . SUBLW .

8.4: Funções Lógicas Nesta fase. podem ser discutidas as funções lógicas em geral. . Por exemplo. Pode-se conferir. . Supondo-se que 2 fios são entradas. OR. desenhada na tabela 1 para as seguintes operações lógicas: AND. y complemento 0: 01011 O 1 entre parênteses é o transporte. x 20 Fazer o segundo complemento de y: somar 1: Somar x e z: (1) 00111 = 7 01100 . As relações que podem existir entre as 2 entradas e a saída são o resultado das combinações de entrada que são: 00. as entradas forem ambas 1 (i. não ambos 1 0 0 0 ou. . Descartar o transporte à esquerda. AND significa ambas as entradas enquanto OR significa qualquer uma ou ambas. O resultado é a resposta. . . e o resultado no terceiro fio dependa das entradas. antes de se examinar as funções lógicas providas pelo 84. O procedimento deve ser como se segue: Converter para binário: 27 11011 . A maioria das explicações a respeito disso. XOR. z + 11011 . Tabela 1 – Tabela Verdade das Funções AND. NOR. transportando à esquerda conforme necessário. que é descartado. somar 1 ao dígito à direita dígito. não ambos Curso de Programação PIC 13/13 .Primeiramente. .e: 11) ou se uma ou ambas as entradas forem 1 (i. XOR. . .e: 01. 11). . se expressa ambos os números em binário. Formar o segundo complemento do que está sendo subtraído assim: mudar todos os 0’s para 1’s e todos os 1’s para 0’s (este é o complemento). ambos ou. . 01. NAND.. Considerar um dispositivo eletrônico digital que apenas atenda em valores binários de 1 e 0 com 3 fios ligados. e somente se. subtrair 20 de 27 . se houver. . . resultam em uma TABELA da VERDADE. NAND e NOR Entradas A B 00 01 10 11 A AND B ambos 0 0 0 1 A OR B 0 1 1 1 A XOR B 0 1 1 0 A NAND B não ambos 1 1 1 0 A NOR B nem um. Deixar o número a partir do qual está se subtraindo inalterado. O fio 3 podem ser 1 se. As relações básicas são conhecidas como E e OU (AND e OR). OR. 10. e outras combinações. 10 e 11. x 10100 . O resultado obtido deve ser 7.. Agora acrescentar o resultado ao outro número inalterado.

isso significa que para realizar NAND deve-se primeiro efetuar AND e então: Curso de Programação PIC 14/14 . O resultado aí é 1. Ao contrário.considerar o ANDing dos números (5F)H equivalente a (95)10 ou (0101 1111)2 e (A3)H que é (163)10 ou (1010 0011)2. esses valores são comparados bit a bit. Por exemplo . OR significa que qualquer uma das entradas pode ser um 1 para a saída ser 1. a função OR (ao contrário da função de XOR) às vezes é conhecida como "Inclusive OR" (IOR).d (AND W with f) (W) AND (f) (dest) IORWF f. O PIC16F84 usa este termo.d (Inclusive OR W with f) (W) OR (f) (dest) XORWF f. A propósito. resultando em (03)H que é (3)10 ou (0000 0011)2. As instruções fornecidas pelo 'PIC16F84 são: A comparação ocorre entre os registradores W e f: ANDWF f. mas assim também será se ambas as entradas forem 1.d (Exclusive OR W with f) (W) XOR (f) (dest) ou entre W e uma literal: ANDLW k (AND literal with W) (W) AND k (W) IORLW k (Inclusive OR literal with W) (W) OR k (W) XORLW k (Exclusive OR literal with W) (W) XOR k (W) Pode-se notar que o '84 não suporta as funções NAND ou NOR. A função XOR quer dizer "eXclusive OR". e.A função AND significa que o resultado só será 1 quando ambas as entradas forem 1. só nas 2 posições mais à direita AND é satisfeito. ele provê meios de complementar (negar) um registrador. e 0 em qualquer outro lugar. NAND e NOR são as negações de AND e OR respectivamente: compare as colunas e você verá o que isso significa. Finalmente. 5F: A3: and: 0101 1111 1010 0011 0000 0011 Claramente. especificamente exclui a situação onde ambas as contribuições forem 1. e significa dizer que qualquer entrada sendo 1 fará o resultado na saída ser 1. O PIC16F84 provê várias operações lógicas que agem em dois valores de 8-bits.sem olhar para uma instrução do '84 .

usando a calculadora do Windows. o registrador em questão pode ser uma porta.COMF f.d (Decrementa f) (dest) (f)-1 INC f.Como exemplo.d (Incrementa f) (f)+1 (dest) Exercício: Em um programa. talvez aproveitando um dos anteriores nos quais foi realizado alguma aritmética ou alguma lógica.b (ativa Bit em f) 1 (f<b>) Foram lidas essas duas operações como 0 (ou 1) se tornando o conteúdo do bit ‘b’ no registrador ‘f’. assim: DEC f. A capacidade de ativar ou limpar qualquer bit. controlando algum equipamento externo.d (Complementa f) complemento de (f) (dest) Exercício: É sugerido aqui fazer duas coisas. verificar o funcionamento destes comandos. zerar: Este fato pode ser utilizado depois para se basear nos dois outros comandos. 2. Curso de Programação PIC 15/15 .5: Decrementando e Incrementando Duas instruções simples podem decrementar ou incrementar o conteúdo de um registrador. pode-se usar o fato de um bit estar ativado ou não para pular instruções no programa. carregando os registros apropriados e executando as operações e conferindo os resultados. verificar os resultados acima: isto irá assegurar que foi amplamente entendido o conceito. uma luz. 8. você pode ativar ou limpar qualquer bit “b” no registrador “f” por duas razões: 1.6: Ativando e limpando Bits Usando os dois comandos a seguir. ou o que quer que seja. 8. Primeiro. Exercício: Colocar esses comandos em qualquer um dos programas anteriores e observar as mudanças a bits individuais em sua janela de monitoramento. BCF f.b (limpa Bit em f) 0 (f<b>) BSF f. dá a habilidade para controlar esse processo. escrever para um programa em assembler para conferir as instruções do '84.Como é visto no item 8. que é ativada se qualquer comando fizer o registro em questão. Cada bit pode estar ativando um dispositivo diferente: um motor. Ficar atento à flag Zero. liga e desliga cada dispositivo. Então. Ativando e limpando cada bit.

A colocação do próximo endereço na Pilha diz ao microcontrolador aonde ir. o fluxo procede linearmente a partir do topo. Em lugar de se repetir este código em muitos lugares. É referido como popping para carregar a pilha. e a outra para trazê-lo de volta: CALL k (Call sub-rotina) (PC)+1 TOS.uma para enviar o microcontrolador à sub-rotina. O pedaço reutilizável é chamado de SUB-ROTINA. e faz isso carregando o endereço k dentro do contador do programa. o controle de um transportador que continuamente acrescenta ingredientes a um depósito. pode-se precisar efetuar laços por certas instruções: poderia se ter um sistema no qual um determinado processo seja contínuo como por exemplo. utilizando para isso um Label. A seqüência de dados devolve o controle ao ponto em que foi chamada quando terminar. pode ser uma parte do programa que será útil em muitas outras partes. separa-se esse pedaço do restante do código. é trabalho do Contador do programa (PC) saber onde o microcontrolador está. e um GOTO mais adiante. k (PC) Curso de Programação PIC 16/16 . A pilha . Segundo. Olhar para o contador do programa (PCL) na janela de monitoramento e conferir isso. O topo da pilha é abreviado por TOS (Top of stack). À medida que se anda pelo programa verá realçada a linha em que seu programa está fazendo o loop. há a necessidade de se controlar o fluxo através do programa. quando um depósito é realizado é voltado ao topo e passa-se novamente pelos mesmos passos somando mais depósitos a cada passagem. e freqüentemente isto não é adequado às necessidades. Pode-se examinar agora a seqüência de dados. Observando-se os laços (looping) primeiro: GOTO k (Vá para um endereço) k (PC) Esta instrução ‘vai para k’. Então se usa GOTO Label. Para usar GOTO deve-se primeiro informar para onde quer que o programa vá. A pilha só é acessível pelo topo: assim como uma pilha de pratos. isto é lendo o último valor e girando a pilha para cima. a qualquer tempo. Pode-se colocar um rótulo (label) perto do início. Primeiramente. Exercício: Modificar um dos programas que já foi escrito.8. À medida que cada instrução é executada. Aqui. PC. quando uma instrução CALL é encontrada.7: Controle de Programa Por muitas razões.que tem 8 níveis no PIC16F84 é o lugar onde o endereço da próxima instrução é colocado. É preciso entender o conceito de stack (pilha). então nós simplesmente chamamos isto tão freqüentemente quanto precisarmos. Há 2 instruções associadas com qualquer sub-rotina . Normalmente. depois que uma sub-rotina tenha acabado.

ignora se limpo) skip if (f<b>)=0 BTFSS f. ignora se 0) (f)+1 (dest). a ocorrência de uma interrupção incapacita interrupções adicionais: alguém não quer as interrupções sejam interrompidas. conseqüentemente RETFIE fixa GIE de volta a 1. RETFIE (Retorna de Interrupção) TOS (PC). ignora se 0) (f)-1 (dest). ignora se ativado) skip if (f<b>)=1 Curso de Programação PIC 17/17 . Conferir para ver se a instrução que segue o decfsz ou incfsz (provavelmente um GOTO. efetuando laços nesse bloco de código. ignora se o resultado for = 0 Os comandos acima são baseados nos comandos DECF e INCF vistos anteriormente. O que acontece é que a interrupção faz com que a flag de interrupção global. para causar laço) é ignorada ou não.8: Ignorando instruções Existem 4 instruções que permitem que se ignore a instrução seguinte. mas o endereço para voltar após a execução da sub-rotina está preservado na pilha para recuperação posterior. Isto resulta em um salto no fluxo do programa para a sub-rotina.b (Testa Bit f.b (Testa Bit f. o PC é empurrado para a pilha da mesma forma que acontece com uma chamada de sub-rotina. A instrução de retorno lê e remove o último dado da pilha e assim o programa retorna ao lugar certo. GIE (INTCON <7>) seja fixada em 0.d (Incrementa f. então RETFIE gira a pilha.' Então usar qualquer instrução para mudar esse valor. 1 GIE Quando uma interrupção acontece. Pensar na profundidade da pilha: significa que chamadas podem ser encadeadas. ignora se o resultado for = 0 INCFSZ f. A parte SZ significa ‘skip if zero' (ignora se for zero).A chamada CALL para uma sub-rotina empurra o PC+1 atual para o topo da pilha. Também.d (Decrementa f. e o fluxo estará correto contanto que cada chamada tenha um retorno correspondente. DECFSZ f. BTFSC f. 8. como apropriado. TOS (PC) Isto retorna com k (W) somado. RETURN (Retorna da sub-rotina) TOS (PC) RETURN é a última instrução da sub-rotina. então altera o PC para o endereço k. Exercício: Conferir essas 2 instruções carregando um valor inicial em um registrador chamado 'cont. RETLW k (Retorna com literal em W) k (W). Voltar de uma interrupção significa que devem ser permitidas interrupções adicionais.

já que foi chaveado o pino e assim o BTFSS deveria ter uma resposta diferente. por exemplo. Cada bit no registrador f é movido 1 para a esquerda. O que sai fora para a direita é movido para carry. ele deveria se comportar diferentemente. e pode se usar qualquer pino de 0 a 4 na PortaA. De qualquer modo. Deve-se ter outro GOTO exatamente no final para efetuar um loop mais externo para o começo. isto é. Pode-se escolher “pulsar”.d (Inverte os nibbles em f) (f<3:0) (dest<7:4>). duas deslizam os bits para a direita ou para a esquerda (através do bit de transporte). clicar com o botão esquerdo no botão “Stim” que se escolher. Agora clicar com o botão direito novamente no botão. o qual ainda é desconhecido na ligação da alimentação. Incluir um pouco mais de código. e carry é movido para a esquerda. que agora pode se saber que é RA3. RRF f. Colocar um BTFSS no final. Aqui vai ser escolhido chavear o pino. Curso de Programação PIC 18/18 . SWAPF f.9: Rotações e Trocas Três instruções permitem a manipulação os bits dentro de um registrador. Cada bit no registrador f é deslocado 1 para a direita. será visto o pino mudar de estado nos limites da próxima instrução). Caminhar pelo programa. Há um modo fácil de se fazer com que o pino mude de estado no simulador MPLAB.d (Rotaciona f à direita através do bit carry). Agora podem se efetuar os testes. Clicar com o botão direito em qualquer um. Poderá ser visto uma tabela de botões de Stim0 até Stim12. “HIGH” ou “chavear o pino”. (f<7:4>) (dest<3:0>) Exercício: Observar o efeito desses comandos no conteúdo de um registrador. RLF f. Ir em Debug> Simulatos stimulus> Asynchronous stimulus. seguido por um GOTO para retornar ao início. para propósitos de teste) A qualquer hora que quando quiser. talvez fosse RA3. “tornar LOW”. ele sempre voltará para o início a partir do final. O BTFSS precisará referir-se a uma das portas de I/O do PIC16F84 como f (05)H ou (06)H para PortA e B respectivamente). e clicar em Assign pin. Dar um duplo-clique no pino que foi escolhido para usar como sensor.Ler estas instruções como ‘testa bit f e ignora se ativado’. da próxima vez o programa chegar ao passo BTFSS. Stim7 então muda para RA3. Destas. (Se tiver a exibição das portas em uma janela de monitoramento. (No loop mais interno. O que sai fora pela esquerda é movido para dentro de carry. o programa fará o loop ou não. e carry circula para a direita. assim pode-se ver o loop do programa para ver o que acontece quando um pino de entrada sofre alteração. Dependendo do estado inicial do pino. 0 a 7 na PortaB. Stim7. 8. Exercício: Escrever um programa com um bloco de código com um loop.d (Rotaciona f à esquerda através do bit carry). e a terceira inverte os dois meio-bits (nibbles) do registrador.

ele deve ser restaurado. 1 TO. RB6 e RB7.8.Tipos de Interrupção e o registrador INTCON Curso de Programação PIC 19/19 . Para fazer uma linha entrada. mas todo o estado do sistema deve ser recuperado. RB5. 0 PD PD CLRWDT (Clear watchdog timer) 0 WDT. o controle tem que voltar para onde estava anteriormente. o bit correspondente no registro TRIS é definido como "1. Se qualquer registrador foi mudado durante o controle da interrupção. RA3 e RA4.1. que foi incluída para efeitos de compatibilidade. OPTION (Não recomendado) 9. RA2. RA1. RB1. pois nenhuma linha corresponde a esse bit. Há 5 linhas na porta A chamadas de RA0.Interrupções no '84 Interrupção é uma forma simples de atrair a atenção no computador. Não só isso. " Assim o valor 01 fará RA0 uma entrada e todas as outras linhas serão saídas. É o Registro de Controle de Direção (DCR). Isso é fácil de ser lembrado. 9. " Para fazer uma linha saída. O WDT (Watchdog Timer) é um dos caminhos para se despertar do comando sleep. Cada linha pode ser de entrada ou de saída. SLEEP (Sleep) 0 WDT. O valor 23 (0010 0011) fará RA0 e RA1 entradas e o bit5 não terá nenhum efeito. Não se deve usar a instrução a seguir. 1 8. Um “1” no registrador TRIS torna a linha uma Entrada. 1 TO. TRIS 05 Esta instrução controla a direção de cada linha da porta chamada Porta A. 0 WDT prescaler. pois “0” é similar a 0utput (saída) e “1” é similar a 1nput (entrada).10: Sleep e o Timer Watchdog Estes dois comandos estão relacionados. RB3. Ela é bastante útil para a criação de pequenos intervalos de atraso (1µs) para permitir que alguma coisa seja pré-ajustada antes que outra operação seja executada. 0 WDT prescaler. TRIS 06 Esta instrução controla a direção de cada linha na porta B. o bit correspondente é definido como "0. Uma vez uma interrupção tenha sido tratada. RB4. Um "0" no registrador TRIS torna a linha correspondente na porta B uma Saída. RB2. Existem 8 linhas na porta B. RB0.11: Miscelânea NOP (Nenhuma operação) Esta instrução não faz nada.

interrupção externa no pino 6: INTCON <4>. uma de gravação completa na EEPROM.mudança em quaisquer dos pinos 10-13: INTCON <3>. se uma interrupção acontecer. deve-se ter a certeza irá ser suprido o código necessário para tratar com cuidado do problema. No vetor. uma interrupção externa no pino 6. deve-se verificar o bit apropriado que diz que tipo de interrupção é. certos bits (conhecido como flags de interrupção) são ativados de forma que podem então se determinar a origem da interrupção: . como um todo. interrupções. também conhecido como: RB0 . Também. todas as interrupções são enviadas para 004h. as Curso de Programação PIC 20/20 .Lidando com uma Interrupção No PIC16F84. antes de ser corrigido a interrupção. então o GIE é zerado para prevenir a interrupção de ser suspensa. Notar que as flags de interrupção sempre são ativadas quando há uma interrupção. Para permitir interrupções. o bit RBIE . o bit INTF . e para determinar a sua origem. Para isso. Segundo: cada um dos tipos de interrupção deve ser habilitado com seu próprio bit em INTCON.2. o processador utiliza o registrador INTCON (0Bh). 9. podem ser habilitadas ou desabilitadas pelo bit INTCON <7>. Claramente. o bit EEIE Terceiro. o GIE (Habilitação de Interrupção Global).estouro do cronômetro: INTCON <5>. independente do estado do bit de habilitação correspondente.estouro do cronômetro: INTCON <2>. o bit T0IE . o bit INTE . um estouro no cronômetro . o bit T0IF Há a necessidade de se saber a origem dessa interrupção porque dependendo do seu tipo a ação que se deve entra deve ser de modo diferente.O PIC16F84 tem 4 tipos diferentes de interrupção: . Primeiramente. antes de poder ser utilizada: . o retorno da interrupção com a instrução RETFIE re-habilita as interrupções. e interrompe o trabalho de acordo com o seu valor (ativado ou não).gravação completa da EEPROM: INTCON <6>.interrupção externa no pino 6: INTCON <1>. uma mudança em qualquer dos pinos de 10 a 13.mudança em quaisquer dos pinos 10-13: INTCON <0>. o bit RBIF . Um ponto crucial é que pode haver a necessidade de se salvar o status da máquina como ele estava antes da interrupção. Esse ponto é o vetor de interrupção e o programa é orientado a dirigir-se para esse endereço. também chamados RB4 a RB7 . então nenhuma interrupção pode acontecer: Esse é o valor no power-up. quando interrupções acontecem. Se esse bit estiver zerado. Cada bit serve a um propósito específico.

Exercício: Começar lentamente com as interrupções. provavelmente W e STATUS.uma seção initialize onde.asynch stimulus: tenha um chaveamento em rb4 . Faz o que é necessário para restaurar o estado anterior à interrupção e retorna.inter1.********************************************* setup processor 16F84 movlw h'0' movwf h'0b' . nem determina o tipo de interrupção. Não será preciso preservar o estado da máquina. na verdade). Enquanto o programa estiver efetuando os loops na seção principal. Há 3 partes a um programa que devem controlar interrupções simples: . checa as flags de interrupção para determinar a origem.watch window: intcon. T0IF derivam para o correto 'o subhandler' para determinar o tipo de interrupção (embora nós fixamos apenas INTE).atividades empreendidas durante a correção poderiam mudar algumas coisas tais como os registradores W e STATUS. Initialize: ativa GIE . porque GIE foi sido zerado.veja o endereço de retorno ida e volta . . INTCON <4> para habilitar interrupções no pino 6. Isto pode se tornar bastante complexo. nem conferir o tipo de interrupção nesta fase. para que nosso outro trabalho possa continuar. chavear o pino novamente. sugere-se usar a interrupção de mudança na porta B.stack: mantenha aberta também.asm . a mudança no pino não causará uma interrupção.asm é um manipulador simples de interrupções. Para ver este programa funcionando corretamente no simulador. Handler: salva o estado da máquina. ou coisa alguma que não seja reabilitar as interrupções e retornar.limpa intcon Curso de Programação PIC 21/21 . RBIF. Solução: Program 5: Inter1. Usar um chaveamento do pino para provocar a mudança. e uma rotina principal que somente faça loops por algum código que espere por uma interrupção. O PIC16F84 só salva o Contador do programa na pilha (PC+1. em nosso caso. usando a técnica de estímulo assíncrona discutida anteriormente. É preciso se assegurar que estarão salva e que poderão ser recuperados qualquer outra coisa que eventualmente houver necessidade. Enquanto o programa estiver na ISR. pcl . Main: Efetua cálculos. nós habilitaremos as interrupções. ativa INTE.*********************************************simulador . INTF. INTCON <7> para habilitar interrupções. chavear o pino e verificar que a interrupção acontece quando se executa o próximo passo do programa. É preciso ter-los restabelecidos após ter controlado a interrupção. . Se tudo estiver funcionando. Escrever um programa para provocar a menor interrupção possível: habilitar e fazer uma rotina de serviço de interrupção (ISR – interrupt service routine) que faça bem pouca. ele não salva o estado da máquina .uma seção Main onde a maior parte do é utilizada (fazendo cálculos ou o que quer que seja) e a parte de manipulador (handler) onde a interrupção é tratada. por exemplo.

realize tarefas de payroll goto payrol nop nop end Exercício: Agora implementar esse programa para salvar o estado da máquina no momento da interrupção. nop .asynch stimulus: tenha um chaveamento em rb4 .salva w como em main movlw h'65' . ativa mudança em b int enable payrol nop .inter2. .watch window: intcon.limpa int em b antes de voltar Curso de Programação PIC 22/22 .interrupções sempre apontam para cá nop .**************************************************** setup processor 16F84 w_saved equ h'10' . deixa espaço bastante para a isr! bsf h'0b'.1 .**************************************************** isr isr org h'0004' . pcl.*********************************************** fim da isr .asm . loop aqui até interrução.salta sobre a isr .aqui nos lidamos de fato nop .agora.7 . "movfw". swap dentro de w bcf h'0b'..limpa int antes de retornar retfie . mas não determina o tipo de interrupção. w.então.veja o endereço de retorno ida e volta .salta sobre a isr no início .0 . e verificar se ele é restaurado corretamente. Solução: Program 6: Inter2.2 swapf's parece ser o caminho a seems to be .isto reativa o intcon gie .0 . w_saved . .alguma coisa para mudar w nop .asm salva o estado da máquina .mais operaçõas da isr . swap w_salvo nele próprio swapf w_saved.****************************************************simulador . seguir para faze-lo.primeiro.limpa intcon goto main . portb..stack: mantenha aberta também.goto main .********************************************** início da isr isr: org h'0004' . swapf w_saved. com a interrupção bcf h'0b'.interrupções sempre apontam para cá movwf w_saved .um lugar para manter w movlw h'0' movwf h'0b' . Testar e ter a certeza que foi carregado W na parte principal.*********************************************** início de main main org h'0020' . então alterar na ISR. ativa global int enable bsf h'0b'.3 .0 . restaurar w: não há .

3 . Neste caso será preciso determinar o tipo de interrupção. w .retfie .isto reativa intcon gie Curso de Programação PIC 23/23 .isto reativa intcon gie .************************************************* setup processor 16F84 w_saved equ h'10' .asynch stimulus tenha um chaveamento em rb4 (for rbi) e rb0(int) . deixe espaço para a isr! bsf h'0b'.***************************************************** final da isr .1 .é uma rbi? call _rbi .inter3. salta sobre a isr no início .agora.Um lugar para manter w movlw h'0' movwf h'0b' . w_saved.chame o 'sub-handler' rbi btfsc h'0b'. ativa global int enable bsf h'0b'. e determina o tipo de interrupção. swap em w bcf h'0b'.mudança em um dos pinos da porta B 4:7 bem como uma interrupção no pino RB0/INT.salva w como ele estava am Main .descobre qual o tipo de interrupção btfsc h'0b'. Solução: Program 7: Inter3. fazendo instruções em payroll movlw h'0f' .watch window: intcon. portb. e controlar isso adequadamente. simule um calculo carregando w goto payrol nop nop end Exercício: Finalmente.1 . payrol nop nop .0 .asm .0 . loop aqui até a interrupção.limpa intf antes de voltar retfie .*************************************************** isr isr org h'0004' . . ativa mudança em b int enable .limpa rbif antes de voltar bcf h'0b'.sim – chame o 'sub-handler' int .1 .termina aqui após os sub-handler . pcl.limpa intcon goto main .é int? call _int . swap em w_salvo dentro dele mesmo swapf w_saved.**************************************************simulator .interrupções sempre apontam para cá movwf w_saved .0 .asm salva o estado da máquina .então.primeiro.7 .veja o endereço de retorno ida e volta . permitir mais de um tipo de interrupção .sim . .stack:mantenha aberta também. restaura w swapf w_saved.****************************************************** Início de main main: org h'0020' .

************************************ processor 16F84 STATUS EQU H'03' OPTIO EQU H'81' tmr0 EQU H'01' BANK_ EQU H'05' T0CS EQU H'05' PSA EQU H'03' setup Curso de Programação PIC 24/24 . Isso poderá ser conferido e ainda ser introduzido uma característica bem útil do MPLAB ao mesmo tempo: o Cronômetro. entretanto.simule cálculo carregando w goto payrol nop nop end 9. O que há.asm . leave room for the isr! bsf h'0b'. nós tivemos 2 tipos de interrupção! payrol nop . Poderá ser visualizado uma janela simples contendo 3 informações importantes: o número de passos completos em um determinado tempo. ativa ext int no pin6 enable . por exemplo. é uma relação simples entre executar instruções e a velocidade em que o processador trabalha. Program 8: Time0. coincidentemente.time0. Abrir o cronômetro através de Janela >Cronômetro.asm para mostrar como timer0 funciona .7 .***************************************************** Final da isr . ativa mudança em b int enable bsf h'0b'.4 .faz algo diferente com w return . Observar se a freqüência está fixada agora em 4MHz. nop .**************************************************** Início de main main org h'0020' .3 . fazendo operações em payroll movlw h'0f' . loop aqui até interrupção. Uma instrução é completa em 1µs quando o chip está operando à 4MHz.) Assim. ativa global int enable bsf h'0b'. o que é uma instrução de 2 ciclos.3._rbi movlw h'65' .Timers no '84 A idéia básica é a utilização do PIC16F84 para cronometrar algo. Entrar em Timer0. pode-se vislumbrar um relógio comum. Cronometrar. quer dizer do modo como é utilizado um relógio normal. .faz algo para mudar w return _int movlw h'24' . um desvio no programa. clicar zero e executar um passo do programa uma vez. É só se saber quantos passos foram executados para se saber quanto tem se passou. (A menos que esse passo fosse. No MPLAB preparar para executar qualquer um dos programas que já foi escrito. Mas não há nenhum relógio nos 84: nenhum relógio no sentido de um relógio normal. Poderia acender a iluminação de um aquário. ou fechar as cortinas às 18h00 todas as noites. Deve ser visto que progrediu 1 ciclo em 1µs. e a freqüência.

como todos os registradores.O Módulo TIMER0 O cronômetro do PIC16F84. INTCON<5> para habilitar a interrupção do timer. Initialize: ativa GIE. sendo usado as técnicas de interrupção com initialize.clocked equ h'10' INTCON equ h'0B' T0IE equ h'05' GIE EQU H'07' goto top . OPTIOPN<3>.veja ativar PSA. INTCON<7> para habilitar interrupções. a cada 1µs se o clock for de 4MHz.************************************ programa top org h'0010' clrf tmr0 . Pode-se aproveitar com esta interrupção incrementar um registrador. Pode-se analisar passo a passo este processo observando simplesmente TIMER0 funcionando. Quando TIMER0 está correndo. para manter o prescaler fora disto. Mas TMR0. Projetar a sua mente até a discussão de interrupções. seu registrador (TMR0) é incrementado a cada ciclo. TIMER0. Então.2 retfie .PSA . vistas anteriormente. onde foi dito que um dos tipos de interrupção era uma interrupção de estouro de cronômetro: isso significa que o registrador TMR0 ultrapassou o limite de FF e retornou para 00.************************************ isr isr ORG h'0004' incf clocked .clocked é o ‘relógio comum’ BCF INTCON. handler e main. Isso significa que essa interrupção acontece a cada 256µS do tempo real. limpa T0CS.4. ativa T0IE. um certo intervalo de tempo decorreu.GIE bsf INTCON. o valor de TMR0 representa o 'tempo' em passos de 1µs.T0CS .alterna para page 1 bcf OPTIO. é um registrador de 8 bits e assim só pode contar até FF: isso significa que o tempo vai até 255µS o que não é muito tempo.limpa o registrador tmr0 clrf clocked mode bsf STATUS. Curso de Programação PIC 25/25 .vai do counter para o timer bsf OPTIO.T0IE loop nop nop goto loop END 9.BANK_ . trabalha numa base em que cada vez que acontece um ciclo de instrução.sem prescaler ainda bsf INTCON. OPTION<5> para habilitar o timer .

Conferir o programa no simulador. Main: tem um loop para manter o programa rodando. ao invés de Bank0. Para aqueles registradores que estão em ambos os bancos. nosso contador de overflow (estouro). tem-se o acesso não importa de onde se esteja. O que isto significa na prática. Agora. ou seja o timer vai estourar em 256. mas lembrar que o registrador tem 2 endereços diferentes: STATUS tem seus endereços conhecidos em h'03' e h'83'. Isto simplesmente significa que há a necessidade de ativar RP0 para ir para Bank1 e zerá-lo para retornar. se está chegando mais perto de um segundo na cronometragem. Exercício: Criar um programa para implementar o anterior.Handler: incremento 'cronometrado em função do clock'. Outros como STATUS está em ambos Bank0 e Bank1. tendo em mente que nós não se está fazendo nada com os estouros a não ser clicá-los. então isso significa que podem ser contados segundos de tempo-real incrementando um outro registrador. Até quanto é preciso contar no segundo arquivo para alcançar 1 segundo? Incrementar a cada . a cada 60 minutos para marcar as horas. Usando a memória de dados EEPROM Curso de Programação PIC 26/26 . Exercício: Escrever um programa para implementar o cronômetro simples acima. simplesmente é tratado com o estouro do registrador SECONDS para minutos a cada 60 segundos e o mesmo com um registrador de minutos. a cada 39 passos.Usando o estouro do timer Pode-se observar que o registrador o registrador fica se atualizando sempre que o cronômetro estoura e isto acontece a cada 256µs. com RP0 (STATUS <5>) fazendo o truque. Acessando registradores em Bank1: Pode se perceber que alguns registradores como OPTION estão naquilo que é referido como Bank1.0256 segundos significa que existem aproximadamente 39 incrementos em um Segundo. o que não é exatamente tão simples quanto acessar o STATUS. Existe a necessidade também em contar estes estouros em outro registrador (arquivo).5. 9. é que estes registradores do Bank1 normalmente não estão disponíveis. pelo menos até a parte do registrador SECONDS.0. será preciso entender como acessar o registrador de opção (OPTION). SECONDS por exemplo. Para conseguir minutos e horas. observando os registradores que devem ser monitorados e também o cronômetro. Foi utilizado o registrador de STATUS para alternar entre os bancos. porque nossa esfera de operações é o Bank0. Antes de começar. que é o objetivo que a ser perseguido.

/ 0 )* + 0 )* () 0 )* ) 1 0 )* ) 1 MOVWF Copiar W para f 2 % & % " 3 $ " $% % & % " W (f) 0 ≤ f ≤ 127 Curso de Programação PIC 27/27 . . . / $" " %.Apêndice 1 – Conjunto de Instruções • Instruções Aritméticas • Instruções de Movimentação de • Instruções Lógicas Dados • Instruções de atendimento a Rotinas • Instruções de controle de Bit e Teste de variáveis • Instruções de controle ao Processamento MOVLW Escrever constante no registro W ! " #" % $ % & % " ' k (W) 0 ≤ k ≤ 255 ( ( )* + $" " %. / " %. .

d ∈ [0. . . / 0 )* 5 2 % . . ' " 3 % & % " " 3 $ $ % & % %: %" " $% % " %. . $ %. - f (d) 0 ≤ f ≤ 127. . < 2 <& 7 % & % 9 " % & % " % & " 3& % . . 1] ( ( 9 ) " %. / 0 )* 5 2 $" 0 )* (6 % . . . / 4 0 )* ) 1 4 0 )* ) 1 0 )* ) 1 0 )* 5) " %. 7 7 %8" $7 " 9 . . / $" " %. / 0 )* )) $" 0) 9 ) " %. 3 * .)* 5 0 )* )) " %.)* 5 0 )* )) 0 )* (6 " %.)* 5 0 )* (6 MOVF Copiar f para d ! 2 $% "# 9 " 9 $. / 0 )* 5 0 )* 5 Curso de Programação PIC 28/28 . / 0 )* (6 0 )* 5 2 % .( ( 4 " %..

)* 5 0 )* )) CLRW Escrever 0 em W 2 8 % & " $ # 7% (' $% ) <& 7 % & % " 0 (W) ( ( " %.$" 2 0( " %. / 0 )* 5 0 )* )) % . . . . .)* 5 0 )* = = Curso de Programação PIC 29/29 . . . / 0 )* + + 0 )* )) CLRF Escrever 0 em f 2 8 % & % $ $ " % # 7% (' $% ) <& 7 % & % " 0 f 0 ≤ f ≤ 127 ( ( " %. / 2 $" " %. / $" 0( " %. . / $" 0( " %. / 0 )* 5 0 )* 5 " %. / - 0 )* )) 0 )* 5 % .

.)* 5 0 )* )) & ' ) ) ( * ! 1! > " " " " & < # " $ "@ ' "# % 9 " 9 % . 0 ≤ f ≤ 127. 7 % & % " 3& % . . ! 1! ? " " " " & < # " % & % " % & % " < % 9 8 f <0:3> d <4:7>. / $" " %. f <4:7> d <0:3>. 3& % . 7 3& % . / 0 )* = 0 )* = ADDLW Adicionar W a uma constante 2 . 9 3 "" % & % " A ' ! " % (W)+k 0 ≤ k ≤ 255 ( ( + ! ! ( ( W )* (+ " %. / 0 )* () Curso de Programação PIC 30/30 . . . 7 . / 0 )* = 0 )* = " %.2 0( % . . / $" 0 )* = 9 ( " %. 1] ( ( 9 ) " %. d ∈ [0.

9 . / 0 )* 6 = 0 )* (6 0 )* B 0 )* 5 0 )* (6 SUBLW Subtrair W a uma constante 2 % & % " 9 & % 3 . . . . / - ADDWF Adicionar W a f 9 "" % .$" " %. % & % " % & % " % & % " "# % 9 " 9 % (W) + ( f ) 0 ≤ f ≤ 127 ( ( + ! ! ( ( d. / 0 )* 5 2 $" 2 0 )* 5 % . 7 k-(W) 0 ≤ k ≤ 255 ( ( + ! ! ( W Curso de Programação PIC 31/31 . 7 2 3& % . 3& % . / 0 )* 5 $" " %. / - 0 )* 5+ 0 )* () 0 )* 6 1 0 )* 6 = $" " %. 1] 9 ) " %. . % C A 3 ! % & % " ' 9 % .)* 5 0 )* 5) % .)* 5 0 )* 5) " %. 7 . / " %. . / 9 ) " %. . d ∈ [0. .

. / " %. 7 . 7 . . / " %. 1] 9 ( " %. / D) " %. / . 7 $" . . / 0 )* )(9 0 * 0 * 9 0 )* )59 0 (9 0 ) 0 )* 9 0 * 0 * )= 9 0 )* ))9 0 (9 0 ( 0 )* 9 0 * 0 * )1 9 0 )* 9 0 )9 0 ) . . . / " %. / " %.(W) ( ( + ! ! ( ( d 0 ≤ f ≤ 127.( )* )= " %. . / " %. 7 3 . 7 0 )* () 0 )* 56 D) SUBWF Subtrair W a f 9 2 "# % 9 " 9 % % & % " . . ( f ) . / " %. d ∈ [0. % C ! % & % " % & % " 2 % & % " 3& % . . . . 7 E) 0 = 0 59 0 * 0 * 9 9 0 (9 0 59 0 (9 0 ) 0 59 0 59 0 * 0 * 9 0)9 0 59 0 (9 0 ( 0(9 0 59 0 * 0 * 9 0 )* 9 059 0 )9 0 ANDLW Fazer o “E” lógico de W com uma constante Curso de Programação PIC 32/32 . . / $" . 7 $" ) " %. / $" D) $" 0) $" E) " %. 3& % . . 7 " %. / . 7 . . / 0) " %. / 0 )* 6 = $" 0( " %. .

AND. 1] ( ( 9 ( " %. ( f ) d 0 ≤ f ≤ 127.AND. / J)* = K J)* 6K = 0 )* = 0 )* 6 = I I I ()() ))(( ))() ))(( )((( $" " %. / ))(( J)* K 5= 0 )* 5= ANDWF Fazer o “E” lógico de W com f 9 L G H7& :" "# % 9 " 9 % . 7 . 3& % . / ))(( J)* K )= " %. . . .F * . . . k 0 ≤ k ≤ 255 ( ( )* + W " %. % . / J)* (6K I J)* 5K $" J)* )5K " %. / 0 )* (69 9 ) 0 )* I )5 )))) ))() (()) ))() 0 )* (69 0 )* 5I )))( (((( Curso de Programação PIC 33/33 . 7 2 3& % . d ∈ [0. 2 % & % " ' % & % " 9 8 ( W ) . % & % " % & % " % & % " (W) . . 7 G H7& :" 3& % . / J)* K + 0 )* = I I )()( (((( ()() )))) ))(( J)* = K 0 )* I )= $" " %.

. G H7& :" ! " 9 % 2 3& % . / - 0 )* (69 0 )* 5I I )))( (()) )))) ))() 0 )* )59 0 )* 5I IORLW Fazer o “OU” lógico de W com uma constante F * . 2 % & " % & % " % & % " (W) . . .OR. 7 ( W ) . . 7 . k 0 ≤ k ≤ 255 ( ( )* + = W " %. / " %. / $" " %. / 0 )* 9 0 )* ( (= B 0 )* 9 0 )* = (= B Curso de Programação PIC 34/34 . / - 0 )* B 0 )* 0 )* B 0 )* B IORWF Fazer o “OU” lógico de W com f 9 L G H7& :" "# % 9 " 9 % . . % & % " 9 8 % & % " ' . . ( f ) d 0 ≤ f ≤ 127. . / 2 $" 0) 0 )* 6 = " %. 1] ( ( 9 ) " %. / $" 0 ) " %. / J)* (6K J)* 5K " %. 3& % .(((( ))() $" J)* )5K " %.OR. 7 3& % . d ∈ [0. .

/ $" 0) " %. 9 8 $% . 3& % . .XOR. % *7 " H . # . 2 % & % " % & % " % & % " (W) . . d ∈ [0. . . / J)* K 0 )* 0 )* 6 = I I I ()() (((( ))(( )((( ())( ())) J)* 6K = $" J)* K B 0) " %. 1] ( Curso de Programação PIC 35/35 . / 0 )* I ( " %. 2 % & % " % & % " . 7 H 3& % . / 0 )* B XORWF “OU-EXCLUSIVO” de W com f 9 L G "# % 9 " 9 % . .G . k 0 ≤ k ≤ 255 ( ( )* W " %. / J)* K 0 )* + I I ()() (((( ()(( )()( )))( ()() J)* + K $" J)* K ( " %. ( W ) .EXCLUSIVO” de W com uma constante F * .XOR. 7 3& % .0) 9 ( " %. . . / 0 )* 9 0 )* ( (= B 0 )* = 0 )* ( B9 B XORLW “OU. ( f ) d 0 ≤ f ≤ 127. 7 .

1] ( ( 9 ( " %. / J)* K ( 0 )* 9 0 )* ( I )))( " %. 7 3& % . . / 0 )* () 0 )* () " %. / 0 )* )) 0 )* DECF Decrementar f 9 Curso de Programação PIC 36/36 .( 9 ( (((( J)* + K $" ()() " %. / J)* K 0 )* 9 0 )* + I I ()() ()(( )()( 0 )* 9 0 )* + ( ))( " %. 9 2 % & % " % & % " % & % < " ' "# % 9 " 9 % (f)+1 d 0 ≤ f ≤ 127. ." . / J)* K ( 9 ) (((( J)* + K $" ()() " %. . . . . . / 0) $" 0( 9 ) " %. d ∈ [0. / J)* K 0 )* 9 0 )* +I I ()() ()(( )()( INCF Incrementar f 9 % 8 % . 7 . 8 . / 0* 0) $" 0 )* (( 0) " %. . 3& % .

. . 7 . d ∈ [0. d ∈ [0. % & % " % & % " ( f <n>) d<n+1>. 3& % . 7 3& % . 9 3& % . f<7> C. . 8 . % . 1] ( ( 9 ) " %. / 0* 0) $" 0 )* (5 0) " %. / 0) $" " %. 8 $. . C d<0>. / 0 )* (= 0 )* (= " %." . 9 2 % & % " % & % " % & % < " ' (f)-1 d 0 ≤ f ≤ 127. 7 3% %%M ' K . 1] ( ( 9 ( " %. 7 . / 0 ((() )(() 0 ((() )(() Curso de Programação PIC 37/37 . 0 ≤ f ≤ 127.$% . / 0 )* )) 0 )* )( RLF Rodar f para a esquerda através do Carry 9 2 % # 3 "# % 9 " 9 % % & % " J< & 7 . . . 3& % .% 8 "# % 9 " 9 % % . / 0) $" 0( 9 ) " %.

/ 0 )((( ))(( 0 ((() )(() " %. 7 . C d<7>. / 0 (()) (()) 0 ((() )(() RRF Rodar f para a direita através do Carry 9 2 % # 3 "# % 9 " 9 % % & % " J< & 7 . . () d 0 ≤ f ≤ 127. % & % " % & % " ( f <n>) d<n-1>. 7 . d ∈ [0. . 1] ( ( 9 ) " %. 3& % . 8 $.0 (()) (()) 0( 9 ( " %. . 7 3 8$ 8 7 % & % " % & % " ' 3& % . 1] Curso de Programação PIC 38/38 . 0 ≤ f ≤ 127. 3& % .$% ""9 % 3& % . f<0> C. / 0) $" 0) " %. / 0* 0) $" 0) 9 ( " %. / 0 ((() )(() 0 )((( ))(( 0 ((() )(() COMF Complementar f 9 2 "# % 9 " 9 % % & % " . / 0) $" 0( " %. . . . d ∈ [0. 7 3% %%M ' K .

.( ( 9 ) " %. . / 9 = " %. 0 ≤ b ≤ 7 Curso de Programação PIC 39/39 . / 0 )* (= 0 )* (= I )))( ))(( I 8$ 8 7 I ((() (()) J)* K (= % J)* K BCF Pôr a “0” o bit b de f 9 * " % J$ % 8$ N OK ! * )P 9 " % & % " 0 f<b> 0 ≤ f ≤ 127. / 0J 0 )* 5 K0 )* 0 )* 5 K0 )* + + " %. . 0 ≤ b ≤ 7 ( ( 9 6 " %. . . / 0 )* 5 2 $" % " %. . . / 2 $" 2 0J " %. / $" 0 )* 9 ( " %. / 8 J 0 )* (6 K0 )* 5 0 )* (6 0 )* 6 0 )* 6 1 I (()) )((( I )()) )((( J)* 6K J)* 6K 1 FSR = 0xC2 conteúdo do endereço em FSR (FSR) = 0x27 BSF Pôr a “1” o bit b de f 9 * N % O9 ! * (P " % & % " 1 f<b> 0 ≤ f ≤ 127. . / $" " %.

. / 8 J 0 )* (6 K0 )* 5 0 )* (6 0 )* )6 0 )* (6 I )))) )((( I ())) )((( J)* )6K J)* 6K BTFSC Testar o bit b de f. ' & % % " %. . . . saltar por cima se for = 1 9 * ! * " . / 0 )* 5 2 $" 2 0 )* 5 % 8 J K0 )* 5 % " %. " %. " %. % " L 3 * . 7 . . ! * <% . . " %. % * . 9 $ & 8 % % % & " % $ & 8 % % <% L % 9 4 ' )= ! ( " 3 8 % - BTFSS Testar o bit b de f. . 9 $ & 8 % % <% O8P . . % & % " <% ". J E*DK0 ) 0 ≤ f ≤ 127. % * . % % ! ( " 3 8 % ! * " ! ( " 7Q " 7Q " % & " <% ) $" 3 8 % - " %.. 9 Curso de Programação PIC 40/40 . 9 . . " % * . .( ( 9 6 " %. &" . * . .7 8 % 9 " "7 " %. &" . . 9 <L 8. . 9 " %. . 9 " %. / 9 = " %. .7 9 * .. ! * <% L % 9 . .5 4 )( 4 )5 4 )= %"%9 4 )(' $" % % & " 4 )5' ''''''''''' ''''''''''' <% ( $ # 7% 7& :" 9 (I % I & % % I * . . % " L 3 * . . " %. . & 89& &" ' . " 89 . . . saltar por cima se for = 0 9 * ! * " % & % " <% ". 9 8 #L 9 8 " %. " % % " %. 7 L % 9& % % " %. 0 ≤ b ≤ 7 ( ( . & " &" ' . &" . ... / $" " %.

7 0) 4 )( . . . " %. 7 . 8 " %. 9 $ & 8 % % <% L % 9 $ & 8 % % % & % " <% O8P . saltar por cima se der = 0 9 2 . 8 . . 7 3& % . ! . &" ." ' "# % 9 " 9 % . &" 3 . . 1] ( ( . 7 " % 8 <% 0 )9 " %. . ." 4 )5 ''''''''''' 4 )= ''''''''''' %"%9 %) 9 (I $" Curso de Programação PIC 41/41 . % * . 3& % . d ∈ [0. .7 J E*DK0 ( 0 ≤ f ≤ 127.5 $ % . " C $% . ' (f) + 1 d 0 ≤ f ≤ 127. .8 #L 8 % & % % 9 8 " %. % & % " % & % " ' ' % & % " 3" % 8 . % % ! ( " 3 8 % ! * " ! ( " 7Q " 7Q " % & % " <% ( $" 3 8 % - " %. " %. 9 % 4 ' )= ! ( " $ & 8 % % 3 8 % - INCFSZ Incrementar f. 9 " 89 " %.5 4 )( 4 )5 4 )= %"%9 4 )(' $" % % & % " 4 )5' ''''''''''' ''''''''''' <% ) $ # 7% 7& :" 9 (I % I & % % I * . . ' . . 7 % 8 I & % % I * . % * . 0 ≤ b ≤ 7 ( ( . 9 L < 8. . % % 2 7Q " 7Q " % .7 8 % 9 " "7 " %. . . . " "7 " %. 8 % . 9 " %.

7 % 8 <% 0 )9 " %. 9 0 4 )(' 2 % & % " $" 0 >( % " * . ' (f) . &" 3 .5 $ % . . . % 8 . . &" 9 . 9 % < 0 )9 $% %:. 7 0) 4 )( . 9 - $% . " %. ! . 8 " %. GOTO Saltar para o endereço 7 " "" 7 % $ % ' k PC<10:0>. .1 d 0 ≤ f ≤ 127. saltar por cima se der = 0 9 2 "# % 9 " 9 % % & % " . 0 % $ & 8 % % %R 9 %" " %. 4 )5' 2 % $% . 9 (I $" 0 % $ & 8 % % 4 )(' 2 % & % " $" % " * . . % % 7Q " 7Q " 2 % . 8 . . . 1] ( ( . 7 % 8 I & % % I * ." % & % " % & % " ' ' ' % . 9 L < " 8 8. 7 % 4 ' )= %R 9 %" % $ & 8 % % 3 8 % " %. % DECFSZ Decrementar f. . . . & " 9 . 3& % . 7 % 4 ' )= % $ & 8 % % 3 8 % S9 4 )5' " %. (PCLATH<4:3>) PC<12:11> 0 ≤ k ≤ 2048 ( 5 4 )) 4 )(I 7% $% 4 )( Curso de Programação PIC 42/42 ." 4 )5 ''''''''''' 4 )= ''''''''''' %"%9 %) 2 % ?( $ . . d ∈ [0. 7 3 3& % .7 8 % 9 " "7 " %. 8 . S9 . % * .% $ & 8 % % " %. " C $% . 7 . 9 % < 0 )9 $ & 8 % % $ $% %:.

Chamar a subrotina LAB_02 Antes da instrução: Depois da instrução: TOS = LAB_01 PC = endereço LAB_00 PC = endereço LAB_02 RETURN Retorno de um subprograma 2 $ & 8 ' % % $ % $7 3& % " Q . . / 0* $" 0 " %.. chama um subprograma. o endereço de retorno (PC+1) é guardado na pilha. $ & 8 % % % ( 5 " %.. correspondente ao endereço de início do subprograma. .. . . Primeiro. / ( 0 0* Curso de Programação PIC 43/43 .... / " %./ 4 )( $" '''''''''''' " %. PC+1 1 2 LAB_00 LAB_01 LAB_02 TOS = x Topo da pilha (TOS – Top Of Stack) 0 ≤ k ≤ 2048 CALL LAB_02 : : ... vai para o contador de programa (PC). a seguir. . / 0 0 % % 4 )) 4 )( CALL Chamar um programa [rótulo] CALL k Esta instrução.... o operando k de 11 bits.

/ 0* 0* $" 0 0 ?( " %. . . % < &3 < . / 0) $" 0( " %. / 0 )* = 1 0* RETFIE Retorno de uma rotina de interrupção . % & % " ' (k) W. . $@ . . 8 . / 0 0* NOP Nenhuma operação Q8 .& ! 7 " .3 * .% " ! " 8 " %%. 9 8 . . . 7 ' Curso de Programação PIC 44/44 . 1 GIE ( 5 " %. . .RETLW Retorno de um subprograma com uma constante em W ! 9 & % " 3 . $% . Q !7 " " 9 " ! $ " Q !7 . 2 $ $7 J " Q K3 % 9 <%" $ % % $ & 8 J K % % ' 8 8 8$ 9 " %%.' $. 7 " " %%. 7. TOS PC 0 ≤ k ≤ 255 ( 5 )* = 1 " %.9 $@ 3$ O' (P % TOS PC .

( ( CLRWDT Iniciar o temporizador do watchdog 8$ %" L % 8$ %" L % ! " % & % " T Q &3% $ L% ' $ % 7% Q &3 8! 8 % $ 3 ) 9 8! 89 3 . $ O8P . % $ O' )P " % 7 O' ! )P " Q & K 0 0 1 0 WDT prescaler do WDT ΤΟ PD ( Curso de Programação PIC 45/45 . . . ' 8 $% ' ! J T % R " T K % & % " . ' 0 0 1 1 WDT prescaler de WDT ( ( " %. 3% $ J " % . / % % 7% $" 7 0 (/ (5 " %. K3$ 8 O' (P 8$ %" L % J % $ " $ # % 7% . / 0) % 0 )* )) % 0* SLEEP Modo de repouso $ % % % 8 !" * .

. / 0) % 0 )* )) % 0* Curso de Programação PIC 46/46 . .( " %. / % % 7% $" 7% 0* " %.

Apêndice 2 – Biblioteca de Rotinas Curso de Programação PIC 47/47 .

Sign up to vote on this title
UsefulNot useful