Multipic4 16f628 Assembly Apostila
Multipic4 16f628 Assembly Apostila
Multipic4 16f628 Assembly Apostila
PIC by Example
5 - As interrupções
1. Interrupções
2. Exemplo prático de controle de uma interrupção
3. Exemplo prático de controle de mais de uma interrupção
IMPORTANTE
Os exemplos aqui descritos podem ser encontrados na pasta “\ASMs\” do CD que
acompanha o seu MultiPIC ou na internet: www.smartradio.com.br/multipic
IMPORTANTE
Para os exemplos descritos nesta lição, os Jumpers do MultiPIC devem ser:
Introdução ao PIC ®
Copyleft Smart Radio 2008-2012
-2-
MultiPIC
Lição 1 passo 1/6 O que é o PIC
O PIC é um circuito integrado produzido pela Microchip Technology Inc., que pertence da
categoria dos microcontroladores, ou seja, um componente integrado que em um único
dispositivo contem todos os circuitos necessários para realizar um completo sistema digital
programável. Como se pode ver nas figuras:
O PIC (neste caso um PIC16F628) pode ser visto externamente como um circuito integrado
TTL ou CMOS normal, mas internamente dispõe de todos os dispositivos típicos de um sistema
microprocessado, ou seja:
• Uma CPU (Central Processor Unit ou seja Unidade de Processamento Central) e sua
finalidade é interpretar as instruções de programa.
• Uma memória FLASH (Memória Reprogramável) na qual irá memorizar as instruções
do programa.
• Uma memória RAM (Random Access Memory ou Memória de Acesso Aleatório)
utilizada para memorizar as variáveis utilizadas pelo programa.
• Uma série de LINHAS de I/O para controlar dispositivos externos ou receber pulsos de
sensores, chaves, etc.
• Uma série de dispositivos auxiliares ao funcionamento, ou seja gerador de clock, bus,
contador, etc.
MultiPIC
A presença de todos estes dispositivos em um espaço extremamente pequeno, permite ao
projetista ampla gama de trabalho e enorme vantagem em usar um sistema microprocessado,
onde em pouco tempo e com poucos componentes externos podemos fazer o que seria oneroso
fazer com circuitos tradicionais.
O PIC esta disponível em uma ampla gama de modelos para melhor adaptar-se as exigências de
projetos específicos, diferenciando-se pelo número de linhas de I/O e pelo conteúdo do
dispositivo. Inicia-se com modelo pequeno identificado pela sigla PIC12Cxx dotado de 8 pinos,
até chegar a modelos maiores com sigla PIC16F87x dotados de 40 pinos.
Uma descrição detalhada da tipologia do PIC é disponível no site da Microchip:
www.microchip.com, onde conseguimos encontrar grandes e variadas quantidades de
informações técnicas, softwares de apoio, exemplos de aplicações e atualizações disponíveis.
Para o nosso curso usaremos um modelo intermediário de PIC o PIC16F628. Este é dotado de
18 pinos sendo 13 disponíveis diretamente para o I/O, ou seja, para serem ligados ao circuito e
de outros 3 disponíveis para I/O quando programados para tal; são estes: os 2 de ligação cristal
(pinos 15 & 16) e o de reset (pino 4) .
Em particular o PIC16F628 dispõe de uma memória para armazenar o programa, do tipo
FLASH que pode ser rescrita quantas vezes quisermos e que é ideal para nossos experimentos
tornando a conexão para a programação on-board, ou seja podemos colocar o programa dentro
do chip sem ter que removê-lo do circuito de testes.
-3-
MultiPIC
Tal característica é plenamente aproveitada no MultiPIC, descrito neste curso. Em alternativa é
possível utilizar um programador produzido pela Microchip ou outro programador produzido
por terceiros.
E agora chegou o momento de dar uma olhada no PIC16F628. Vejamos na figura a reprodução
da pinagem e nomenclatura de seus respectivos pinos:
Como é possível ver, ele é dotado de um total de 18 pinos dispostos em duas fileiras paralela de
9 pinos cada uma(dual in line). Os pinos contrastados representam as linhas de I/O disponíveis
para a nossa aplicação, o pino 14 e o 5 são os pinos de alimentação, e os 4, 15 e são reservados
ao funcionamento do PIC (MCLR para o reset e OSC1-2 para o clock) ou podem ser re-
configurados como I/Os no momento da programação.
Após termos visto brevemente o que é e, como é feito o PIC, faremos agora uma simples
aplicação prática.
Iremos fazer um circuito muito simples e seu propósito é fazer lampejar um LED. Vejamos
como se escreve um programa em assembler, como se compila e como se transfere para o
interior da EEPROM do PIC o programa e assim fazê-lo funcionar.
O circuito a ser realizado no MultiPIC, utiliza o LED conectado ao Port PB0, a alimentação,
sinais de clock e Reset já são providos pela própria placa.
-4-
MultiPIC
que representa exatamente o mesmo valor mas numa forma reduzida. A letra H, escrita no final
do valor 0100, indica o tipo de notação (Hexadecimal). O mesmo valor pode ser representado em
assembler com a notação 0x100 que é derivado da linguagem C ou H'0100'.
Este código, completamente sem sentido para nós humanos, é o que o PIC está preparado para
entender. Para facilitar a compreensão ao programador, se recorre a um instrumento e convenção
para tornar a instrução mais compreensível.
A primeira convenção é a que associa o opcode (um total de 35 para o 16F628) a uma sigla
mnemônica, ou seja, uma inicial que seja fácil de recordar o significado da instrução.
Voltando ao nosso exemplo o opcode 0100H corresponde a instrução mnemônica CLRW que é a
MultiPIC
forma abreviada da instrução CLEAR W REGISTER, ou seja zere o registro W (veremos
posteriormente o que significa).
Outra convenção consiste na definição, da variável, da constante, do label(rótulo) de referência ao
endereço de memória, etc. O propósito desta convenção é de facilitar a escrita de um programa
para o PIC e é chamada linguagem assembler. Um programa escrito em linguagem assembler
pode ser escrito em qualquer PC utilizando-se qualquer processador de texto que possa gerar
arquivos ASCII (Word, Notepad etc).Um arquivo de texto que contenha um programa em
assembler é denominado de source ou código assembler.
Dica: No CD do MultiPIC está disponível um ótimo editor Assembler o ASMED Lite, que
destaca opcodes, diretivas, constantes e outros com cores diferentes.
Uma vez preparado o nosso código assembler (veremos mais adiante), iremos precisar de um
programa para traduzir as instruções mnemônicas e todas as outras formas convencionais com que
escrevemos o nosso código em uma serie de números (o opcode) reconhecível diretamente pelo
PIC. Este programa se chama compilador assembler ou assemblador.
Na figura seguinte está esquematizado o fluxograma de operações e arquivos que deverá ser
realizado para passar um código assembler a um PIC a ser programado.
-5-
MultiPIC
Como já foi dito a primeira operação a ser efetuada é a escrita do código assembler e a sua
gravação em um arquivo de texto com a extensão .ASM. Para fazer isto havíamos dito para
recorrer a um editor ASCII, ou seja, um programa de escrita por exemplo, o NOTEPAD do
MultiPIC
Windows ou o EDIT.EXE do MS/DOS©. É possível gerar este arquivo com programas mais
sofisticados como o Word© ou Wordperfect© tendo somente que tomar o cuidado de mudá-los
para o formato texto e não em seu formato nativo. Isto para evitar que venhamos memorizar antes
o caractere de controle de formatação de texto que o compilador assembler não esta preparado
para reconhecer.
Dica: No CD do MultiPIC está disponível um ótimo editor Assembler o ASMED Lite,
que destaca opcodes, diretivas, constantes e outros com cores diferentes.
Na nossa primeira experiência prática utilizaremos o arquivo de nome LED.ASM que pode ser
encontrado no CD (pasta ASMs) ou no site do MultiPIC www.smartradio.com.br/multipic .
IMPORTANTE
Para os exemplos descritos nesta lição, os Jumpers do MultiPIC devem ser:
;**************************************************
; LED.ASM
; para multipic 3
;**************************************************
PROCESSOR 16F628
RADIX DEC
INCLUDE "P16F628.INC"
ERRORLEVEL -302 , -305
__CONFIG (_PWRTE_ON & _MCLRE_OFF & _WDT_OFF & _LVP_OFF &
_INTRC_OSC_NOCLKOUT)
LED EQU 0
;Reset Vector
;ponto de inicio do programa CPU
ORG 00H
bsf STATUS,RP0
bcf STATUS,RP0
CLRF PORTB ;RESETA TODOS PINOS DO PORTB
bsf PORTB,LED
MainLoop
call Delay ;CHAMA ROTINA DE ATRAZO
-6-
MultiPIC
bcf PORTB,LED;APAGA LED
call Delay ;CHAMA NOVAMENTE ROTINA DE ATRAZO
bsf PORTB,LED;ACENDE LED
goto MainLoop ;VOLTA ACIMA
; Subrotinas de CALL
Delay
clrf Count ;LIMPA CONTADOR
clrf Count+1 ;LIMPA REGISTRADOR ACIMA DO CONTADOR
DelayLoop
decfsz Count,f ;DECREMENTA O CONTADOR SE DER ZERO PULA LINHA
ABAIXO
goto DelayLoop ;VOLTA PRO ACIMA
decfsz Count+1,f ;DECREMENTA REGISTRADOR ACIMA DO CONTADOR SE ...
goto DelayLoop ;... DER ZERO PULA AQUI
return ;RETORNA PARA SUBROTINA QUE CHAMOU ESTA
END
;-----------------------------------------------------------
-7-
MultiPIC
Lição 1 passo 4/6 Analisando um código assembler
Analisaremos agora linha por linha o conteúdo do nosso código LED.ASM. Se você dispõe de
uma impressora é útil efetuar uma cópia do código para poder seguir melhor a nossa explicação.
Em alternativa é preferível que você visualize o código em uma janela separada de maneira a
poder seguir simultaneamente o código e a relativa explicação.
Partiremos da primeira linha de código:
PROCESSOR 16F628
PROCESSOR é uma diretiva do compilador assembler que indica a definição de qual
microprocessador esta escrito o nosso código. A diretiva não é uma instrução mnemônica que o
compilador traduz no respectivo opcode, mas sim uma simples indicação enviada ao compilador
para determinar o funcionamento durante a compilação. E neste caso informamos ao compilador
que a instrução que acabamos de colocar no nosso código é relativa a de um PIC16F628.
RADIX DEC
A diretiva RADIX serve para informar o compilador que o numero sem a notação, será
entendido como número decimal. Ou seja, se quisermos especificar, por exemplo o numero
hexadecimal 10 (16 decimal) não podemos escrever somente 10 porque ele será interpretado
como 10 decimal, neste caso ecrevemos10h ou 0x10 ou H'10'.
INCLUDE "P16F628.INC"
Veja uma outra diretiva. Desta vez indicamos ao compilador a nossa intenção de incluir no
código um segundo arquivo denominado P16F628.INC. O compilador se limitará a substituir a
linha contendo a diretiva INCLUDE com o conteúdo do arquivo indicado e vai efetuar a
compilação como se fosse ante disso parte do nosso código.
LED EQU 0
Mais uma diretiva! Mas quando veremos as instruções? Calma tenha um pouco de paciência.
A diretiva EQU é muito importante quando se trata de definir com ela uma constante simbólica
dentro do nosso código. Em particular a palavra LED daqui em diante no código será
equivalente ao valor 0. O ponto principal da existência da diretiva EQU é se não tornar o código
mais legível e podermos colocar um valor constante em um único ponto do código.
É importante notar que a palavra LED não identifica uma variável mas, simplesmente um nome
simbólico válido durante a compilação. Não será nunca possível inserir instruções do tipo LED
= 3 dentro do código quando a determinação dinâmica de um valor e de uma variável é uma
operação que recebe a intervenção da CPU do PIC e que sempre deve ser expressa com
instrução e não diretiva.
A diretiva faz sentido somente durante a compilação do código depois o PIC não poderá mais
seguir uma diretiva.
Vejamos agora a linha seguinte:
Count EQU 0x20
Count: neste caso estamos definindo uma área de dados dentro do PIC ou seja uma área em que
memorizaremos variável (com nome de Count). Esta área é exatamente a área de RAM do PIC
definida pela Microchip como FILE REGISTER.
O registrador de arquivo nada mais é do que uma locação na RAM disponível que começa a
partir do endereço 020H no caso do 16F628. Este endereço é fixo e não pode ser modificado
enquanto a locação anterior for usada para outro registro especial de uso interno.
-8-
MultiPIC
Analisemos agora a próxima linha:
ORG 00H
Esta segunda diretiva ORG faz referência a um endereço na área da memória de programa
(Flash no F628) antes da área de dados. Deste ponto em diante colocaremos de fato a instrução
mnemônica que o compilador devera converter no respectivo opcode do PIC.
O primeiro opcode visto pelo PIC após o Reset é aquele memorizado na posição 0, e daí o valor
00H inserido na ORG.
bsf STATUS,RP0
E finalmente a primeira instrução mnemônica de parâmetro, completa. O PIC tem uma CPU
interna do tipo RISC onde a instrução ocupa una só locação de memória, opcode e parâmetro
incluso. E neste caso a instrução mnemônica bsf que dizer BIT SET FILE REGISTER ou seja,
coloque em nível lógico 1 (condição lógica alta) um dos bits contidos na locação de memória
RAM especificada.
O parâmetro STATUS esta definido no arquivo P16F628.INC e o passa através de uma diretiva
EQU. O valor colocado neste arquivo é 03H e corresponde a um registrador de arquivo (ou seja,
uma locação na RAM na área de dados) reservado.
O próximo parâmetro RP0 é definido também no arquivo P16F628.INC com valor 05H e
corresponde ao numero do bit que se quer colocar em um. este registrador de arquivo tem 8 bits
e começa pelo numero 0 (bit menos significativo) e vai até o número 7 (bit mais significativo)
Esta instrução na prática coloca em 1 o quinto bit do registrador de arquivo STATUS. Esta
operação é necessária, como veremos na próxima lição, para acessar o registrador de arquivo
TRISA e TRISB.
movlw 11111111B ;PORTA INTEIRO COMO SAÍDA
Esta instrução significa: MOVE LITERAL TO W REGISTER (passar o literal para W) ou seja,
mover um valor constante para o acumulador W. Como veremos mais adiante, o acumulador, é
um registrador particular utilizado pela CPU em todas as situações em que se efetua uma
operação entre dois valores ou em operações de deslocamento entre locações da memória. Na
prática é um registro de apoio utilizado pela CPU para memorizar temporariamente um byte
toda vez que houver necessidade.
O valor constante para memorizar no acumulador é 11111111B ou seja, um valor binário de 8
bits onde o bit mais à direita representa o bit 0 ou o bit menos significativo.
Na próxima instrução temos:
movwf TRISA
O valor 11111111B esta memorizado no registro TRISA (como para o registro STATUS o
TRISA também é definido através de uma diretiva EQU) a sua função é definir o funcionamento
da linha de I/O do PORTA. Este bit é em particular um bit do registro TRISA e determina em
leitura (entrada) sua respectiva linha do PortA , se estivesse em 0 determinaria em escrita(saída).
Na tabela seguinte está descrita a configuração que assumirão os pinos do PIC quando executar
esta instrução:
-9-
MultiPIC
N.bit
N.bit registro TRISB Linha porta A N.Pino Valor Estado
0 RA0 17 1 Entrada
1 RA1 18 1 Entrada
2 RA2 1 1 Entrada
3 RA3 2 1 Entrada
4 RA4 3 1 Entrada
5 RA5* 4 0 -
6 RA6* 15 0 -
7 RA7* 16 0 -
N.bit registro
N.bit registro TRISB Linha porta B N.Pino Valor Estado
0 RB0 6 0 Saída
1 RB1 7 1 Entrada
2 RB2 8 1 Entrada
3
4 MultiPIC RB3
RB4
9
10
1
1
Entrada
Entrada
5 RB5 11 1 Entrada
6 RB6 12 1 Entrada
7 RB7 13 1 Entrada
TRISB
Note como o valor 0 no bit 0 do registro TRISB determina a configuração em escrita (saída) da
respectiva linha do PIC. Na nossa aplicação esta enfatizado que esta linha será usada para
controlar o LED e faze-lo lampejar.
Havíamos visto que a instrução movwf TRISB transferia o valor contido no acumulador
(inicializado anteriormente com a instrução movlw 000000000B) no registro TRISB. O
significado de movwf é MOVE W TO FILE REGISTER (passe o valor de W para o registrador
de arquivo).
bcf STATUS,RP0
Esta instrução é similar a bsf vista anteriormente, com a diferença de colocá-lo em zero. E(bcf)
significa neste caso BIT CLEAR FILE REGISTER.
Do ponto de vista funcional esta instrução permite o acesso ao registro interno do banco 0 ou
seja da qual faz parte o PortA e PortB, e banco 1 da qual faz parte TRISA e TRISB. Uma
descrição mais detalhada veremos mais adiante neste curso.
bsf PORTB,LED
Com esta instrução será efetuada a primeira operação na qual veremos o resultado do lado de
fora do PIC. Particularmente irá acender o led conectado a linha RA0. PORTA é uma constante
definida no P16F628.INC e faz referência ao registrador de arquivo correspondente a linha de
I/O do PortB onde LED é o numero da linha que ira a 1. Se bem recordas, no inicio do código a
constante LED esta definida em 0, quando a linha que interessa será RA0.
- 10 -
MultiPIC
MainLoop
Esta linha contém um label ou seja, uma referência simbólica a um endereço de memória. O
valor do label, como dito anteriormente, vem calculado na fase de compilação com base no
número de instrução, a diretiva ORG e a outra instrução alocam espaço na memória do PIC. E
neste caso, se tínhamos a instrução colocada a partir da ultima diretiva ORG podemos colocar o
valor que vira seguido a MainLoop ou seja 07H.
Na realidade o valor que o label assume não tem muita importância e o seu propósito é
justamente o de indicar a posição precisa do opcode na memória do PIC, ou seja, um modo de
referenciar uma determinada locação de memória.
E neste caso o label Mainloop será utilizado como ponto de entrada num ciclo (do inglês Loop)
de acender e apagar o led ou seja, uma parte do código que colocará o mesmo num ciclo
infinito. Encontraremos mais a frente uma referencia a este label.
call Delay
Esta instrução determina uma chamada (do inglês call) a uma subrotina que inicia em
correspondência com o label Delay.
A sub rotina é parte especial de um programa que efetua uma função especifica. Onde a
qualquer momento esta função pode ser chamada com uma só instrução, vejamos todas as
instruções necessárias para efetuá-la. Onde neste caso a subrotina insere um retardo para o
tempo de acender e apagar o Led.
A instrução que compõe a sub-rotina Delay foi inserida como se segue no código:
MainLoop
call Delay
bcf PORTB,LED
call Delay
bsf PORTB,LED MultiPIC
goto MainLoop
Acima então temos a sub-rotina que acende e apaga o led indefinidamente, da seguinte maneira:
1. Espera cerca de ½ segundo
2. apaga o LED
3. espera mais ½ segundo
4. acende o led
5. volta ao passo 1
A sub-rotina Delay
Como descrito anteriormente esta subrotina coloca um retardo de cerca de ½ segundo e pode ser
chamada através do programa com instrução call Delay.
Vejamos como funciona:
Delay
clrf Count
clrf Count+1
DelayLoop
decfsz Count,1
goto DelayLoop
decfsz Count+1,1
goto DelayLoop
retlw 0
END
- 11 -
MultiPIC
Delay e DelayLoop são dois label. Delay identifica o endereço de inicio da subrotina e será
utilizado pela chamada através do corpo do programa principal. DelayLoop será chamado
internamente pela subrotina e serve como ponto de entrada para o ciclo (do inglês loop) de
“retardo”.
Na prática o retardo é conseguido executando-se milhares de instruções que não fazem nada!
Este tipo de retardo se chama retardo software ou retardo de programa. É o tipo de retardo mais
simples de implementar e pode ser utilizado quando não se deseja que o PIC faça-o.
clrf Count
clrf Count+1
CLEAR FILE REGISTER zeramento de duas posições da memória RAM reservada
anteriormente com a instrução:
Count EQU 0x20
Estas duas locações são adjacentes a partir do endereço referenciado pelo label Count.
decfsz Count,f
A instrução DECREMENT FILE REGISTER, SKIP IF ZERO ou seja, decremente o conteúdo
do registro e pule a próxima instrução se for zero(e neste caso Count pula a próxima instrução se
o valor devolvido for zero). Se o valor devolvido for diferente de zero executará a próxima
instrução:
goto DelayLoop
Que manda a execução ao ciclo de retardo. Uma vez zero o contador Count irá a próxima
instrução:
decfsz Count+1,1
goto DelayLoop
Que decrementará o registro seguinte até que este chegue a zero. O registro Count+1 em
particular será decrementado de um até 256 decrementos de Count.
Quando então Count+1 chegar ao valor zero a instrução
return
que significa RETURN FROM SUBROUTINE determinará a saída da rotina de retardo e
retornará a execução da instrução imediatamente após call Delay.
MultiPIC
E por fim a diretiva END que indica ao compilador o final do código assembler.
No próximo passo compilaremos o código LED_1.ASM e programaremos o PIC com o código
gerado pelo compilador assembler da Microchip MPASM.
- 12 -
MultiPIC
Copiemos agora no nosso diretório de trabalho C:\MultiPIC ou aquele que você escolheu o
arquivo LED.ASM e P16F628.INC. Para fazer isto basta clicar, no CD, com o mouse sobre o
nome do arquivo que se quer salvar em nosso diretório de trabalho, repetindo a operação para
ambos os arquivos.
Instalemos agora o software necessário para compilar o nosso programa.
A Microchip coloca disponível na internet o assembler MPASM em dupla versão para sistemas
operacionais Microsoft Windows e para ambiente MS/DOS, O MPASM versão Windows pode
ser encontrado no CD no diretório “Assemblador_MPASM”. Em seguida faremos referência
a versão Windows .
Execute o assemblador MPAsm, (se instalou o CD estará no item MutliPIC do menu iniciar do
Windows) em seguida click no botão “Browse” e localize o arquivo desejado, neste caso o
LED.ASM localizado na pasta “MultiPIC\ASMs”; em seguida click no botão “Assembly”.
Atenção! O MPASM é um produto de propriedade da Microchip Technology inc., lembre-
se então de ler atentamente as condições de uso indicadas durante a fase de instalação.
Compilaremos o nosso código LED.ASM e o resultado que deveremos obter no vídeo é o
seguinte:
MultiPIC
Pressionamos uma tecla como requisita o MPASM e vamos ver que arquivo nos foi gerado. Se
tudo deu certo deveremos ver os seguintes novos arquivos:
LED.HEX
LED.LST
LED.ERR
LED.COD
O conteúdo dos arquivos já foi visto no passo 3 então prosseguiremos com programação do PIC
utilizando um só arquivo o LED.HEX que contem o arquivo compilado no formato “Intel Hex
8”.
- 13 -
MultiPIC
Lição 1 passo 6/6 Programando o PIC
Para programar o PIC nessa lição faremos uso do MultiPIC, caso necessite, refira-se ao manual
do mesmo para instruções detalhadas.
Abra no software de programação IC-PROG o arquivo LED.HEX E proceda a programação
normalmente.
Terminada a programação, retorne a chave para a posição “RUN” e deveremos ver o LED PB0
lampejar na placa MultiPIC, conforme escrito no programa. Importante: o jumper
LEDS/Displays deverá estar posicionado em “LEDs”.
Agora com tudo funcionando, experimente fazer alterações no programa, como por exemplo:
• Alterar os valores de Delay para mais e para menos
• Fazer sequenciar os outros LEDs da Placa
Não esquecendo que: ao alterar o código fonte (LED.ASM) o mesmo deverá ser
compilado e o PIC programado novamente.
- 14 -
MultiPIC
Par escrever, ler e cancelar estas locações é necessário um dispositivo externo chamado
programador. Um exemplo de programador é o nosso MultiPIC ou o PICSTART-16+©
produto da Microchip ou pode ser outro qualquer disponível no comércio.
A primeira locação de memória, o endereço 0000H, deve conter a primeira instrução que o PIC
deverá executar após o Reset e por isso é denominada Reset Vector.
Como devemos lembrar, no código LED.ASM apresentado na primeira lição onde esta inserida a
primeira diretiva:
ORG 00H MultiPIC
Para indicar o inicio do programa. Esta diretiva indica de fato que a execução do programa após
o Reset deve iniciar no endereço 0000H da área de programa.
A instrução que vem logo após a diretiva ORG 00H:
bsf STATUS,RP0
será então a primeira instrução a ser executada.
O REGISTER FILE é uma parte da locação de memória RAM denominada REGISTRO.
Diferente da memória EEPROM destinada a conter o programa, a área de memória RAM é
diretamente visível pelo resto do programa igualmente.
Onde podemos escrever, ler, ou modificar tranquilamente qualquer endereço do REGISTER
FILE no nosso programa a qualquer momento em que for necessário.
A única limitação consiste de que alguns desses registros desenvolvem funções especiais do PIC
e não podem ser utilizados para outra coisa a não ser para a função que estão reservados. Estes
registros encontram-se nas locações base da área de memória RAM segundo o que esta ilustrado
em seguida.
A locação de memória presente no REGISTER FILE são endereçadas diretamente em um
espaço de memória que vai de 00H a 7FH um total de 128 bytes, denominada Bank 0. um
- 15 -
MultiPIC
segundo espaço de endereçamento denominado Bank 1 vai de 80H a FFH. Para acessar esse
segundo espaço é necessário recorrer a dois bits auxiliares RP0 e RP1 segundo a modalidade
que iremos explicar mais adiante, o 16F628 tem mais dois bancos de memória denominados
Bank3 e Bank4, consulte o datasheet seção “Memory Organization” para detalhes.
As primeiras 32 locações do Bank0 (de 00H a 1FH) e do Bank 1 (de 80H a 9FH) são aquelas
reservadas as funções especiais para o funcionamento do PIC e, como já dito, não podem ser
utilizadas para outra coisa.
As 96 locações do Bank 0 podem ser endereçadas e podemos aqui utilizar livremente pelo
nosso programa para memorizar variáveis, contadores, etc.
No nosso exemplo LED.ASM a diretiva:
Cont EQU 0x20
Reserva o endereço 0x20 de início da área de dados para ser usado pelo nosso programa.
Reserva um espaço de duas locações, que o programa utilizará para memorizar o contador de
retardo da sub-rotina Delay.
Os registros especiais do PIC serão utilizados com muita frequência nos programas.
Por exemplo, se fizermos a cópia dos registros especiais TRISA e TRISB, para definir qual
linha de I/O será entrada e qual será saída. O mesmo estado lógico da linha de I/O depende do
valor de dois registros PORTA e PORTB.
Alguns registros reportarão o estado de funcionamento do dispositivo interno do PIC ou o
resultado de operações aritméticas e lógicas.
É necessário conhecer portanto, exatamente qual função desenvolve, cada um dos registros
especiais e qual efeito se obtém ao manipular seus conteúdos.
- 16 -
MultiPIC
Para facilitar as operações de seus registros especiais, no arquivo P16F628.INC (que como
recordamos estava incluído no código LED.ASM com a diretiva INCLUDE) a Microchip
inseriu uma lista de nomes que identificam, com nomes padronizados, qualquer registro especial
e a qual esta associado o endereço correspondente na área do REGISTER FILE.
Se, por exemplo, quisermos definir toda a linha do PORTB do PIC em escrita agindo sobre o
TRISB, podemos escolher e referenciar diretamente o registro com o seu endereço:
Movlw B'00000000'
Movwf 06H
ou então, referenciar o mesmo registro com o seu nome simbólico:
Movlw B'00000000'
Movwf TRISB
Tendo que ter a certeza de ter inserido a diretiva INCLUDE "P16F628.INC" no nosso código.
Iremos agora ilustrar outros dois componentes fundamentais na arquitetura do PIC, a ALU e o
registro W ou acumulador.
A ALU (siglas de Arithmetic and Logic Unit, ou seja, unidade aritmética e lógica) é a
componente mais complexa do PIC por conter todos os circuitos destinados a desenvolver as
funções de calculo e manipulação de dados durante a execução de um programa.
A ALU é uma componente presente em todos os microprocessadores e dessa depende
diretamente a capacidade de calculo do micro em si.
A ALU do PIC16F628 esta preparada para operar com 8 bits, ou seja valor numérico não maior
do que 255. Existem processadores com ALU de 16, 32, 64 bits e mais. A família Intel©
- 17 -
MultiPIC
80386©, 486© e Pentium© por exemplo, dispõe de uma ALU de 32 bits. A capacidade de
cálculo presente nesses micros é notavelmente superior em detrimento da complexidade dos
circuitos acessórios internos e consequentemente do espaço ocupado.
Diretamente conheço a ALU como registro W denominado antes de acumulador. Este registro
consiste de uma locação de memória destinada a conter um só valor de 8 bits.
A diferença entre o registro W e outras locações de memória consiste no fato de que, por
referenciar o registro W, a ALU não pode fornecer nenhum endereço, mas podemos acessá-los
diretamente.
O registro W será utilizado especificamente no programa pelo PIC.
Façamos um exemplo prático. Suponhamos querer colocar na locação de memória 0CH do
REGISTER FILE o valor 01H. Procurando entre as instruções do PIC veremos rápido que não
existe uma única instrução capaz de efetuar esta operação mas deveremos necessariamente
recorrer ao acumulador e usar duas instruções em sequência.
Vejamos porque:
Como dissemos anteriormente, o opcode de uma instrução não pode exceder aos 14 bits e assim
teremos:
8 bits para especificar o valor que queremos colocar na locação de memória,
7 bits para especificar em qual locação de memória queremos inserir o nosso valor,
6 bits para especificar qual instrução queremos usar.
Temos então um total de 8 + 7 + 6 = 21 bits.
Devemos então recorrer a duas instruções, ou seja:
Movlw 01H
Movwf 0CH
Que a primeira colocará no registro W o valor 01H com a instrução MOVe Literal to W e
depois "moveremos" para locação 0CH com a instrução MOVe W para F.
- 18 -
MultiPIC
Lição 2 3/4 O “Programm Counter” (PC) e o Stack
- 19 -
MultiPIC
No reset o PIC seguirá a instrução movlw 10 memorizada na locação 0000H que colocará no
acumulador o valor decimal 10. Onde então passa à executar a próxima GOTO Point1. Esta
instrução determinará um desvio incondicionado para locação de memória especificada pelo
label Point1, ou seja, de novo para locação 0000H.
O programa não fará outra coisa se não a de executar um ciclo infinito seguindo continuamente
as instruções especificadas.
Durante este ciclo, para determinar qual é a próxima instrução a ser seguida, o PIC utiliza um
registro especial denominado Program Counter, ou seja, contador de programa. Este terá
sempre o endereço da próxima instrução a ser executada. No reset este estará sempre zerado,
determinando o inicio da execução no endereço 0000H, e cada instrução terá um incremento de
um para poder passar para próxima instrução.
A instrução GOTO permite a colocação de um novo valor no Program Counter e
consequentemente desviar para uma locação qualquer da área de programa do PIC.
Uma outra instrução muito interessante é o call, ou seja, a chamada a subrotina.
Esta instrução funciona de maneira muito similar ao GOTO com a única diferença que, a
primeira, desvia para uma locação de memória especificada e continua a execução do programa,
enquanto o call desviara o programa para uma subrotina especificada e executara a mesma, e
retornará a execução da instrução imediatamente após a chamada call, o valor imediatamente
após a chamada call será armazenado em uma área particular da memória denominada Stack.
Vejamos melhor com um exemplo:
ORG 00H
Point1
movlw 10
call Point2
goto Point1
Point2
Movlw 11
return
Neste caso o PIC, após ter executado movlw 10 passa a executar o call Point2. Antes de desviar
memoriza no Stack o endereço 0002H, ou seja, a próxima locação ao call. Passa então a
executar a instrução movlw 11, memorizada em correspondência ao label Point2. E neste ponto
encontra uma nova instrução o return que, como podemos deduzir de seu nome, permite o
"RETORNO", ou seja, retorne a execução da instrução imediatamente após o call.
Esta operação é denominada de: "chamada a subrotina", ou seja, uma interrupção momentânea
do fluxo normal do programa para "chamar" a execução de uma serie de instruções, para depois
retornar a execução normal do programa.
Para poder retornar para onde havia interrompido, o PIC utiliza o ultimo valor armazenado no
Stack e o coloca de novo no Program Counter.
A palavra stack em inglês significa "cascata" e por esse fato é possível “cascatear” um
endereço sobre o outro para ser recuperado quando necessário. Este tipo de memorização era
antes denominado de LIFO do inglês Last In First Out, em que o ultimo elemento armazenado
(last in) deve necessariamente ser o primeiro a sair (last out).
- 20 -
MultiPIC
Graças ao Stack é possível efetuar vários call, um dentro do outro e manter sempre o retorno ao
fluxo do programa quando se encontra uma instrução return.
Vejamos um outro exemplo:
ORG 00H
Point1
movlw 10
call Point2
goto Point1
Point2
movlw 11
call Point3
return
Point3
movlw 12
return
No exemplo acima a rotina principal Point1 promove a chamada do primeiro call para subrotina
Point2, a subrotina Point2 chama outra subrotina no caso Point3, este ultimo por sua vez,
encontra um Return e retorna para Point2 que encontra o outro return e retorna para a
execução da rotina Point1 que no caso é a principal.
Os endereços a serem memorizados no stack são dois e quando vir a encontrar um segundo call
procurara pelo return correspondente ao primeiro e assim por diante.
O PIC16F628 dispõe de um stack de 8 níveis, ou seja um Stack que consegue armazenar no
Maximo 8 chamadas à subrotina.
É importante assegurar-se, durante a formulação de um programa que, se tenha sempre uma
instrução RETURN em correspondência a um CALL para evitar o perigo de desalinhamento do
stack que em execução pode gerar erros que dificilmente encontraremos.
Faremos agora uma re-elaboração do código LED.ASM apresentado na primeira lição fazendo-o
realizar um lampejador de quatro led's. E o novo código modificado se chamará SEQ.ASM.
IMPORTANTE
Para os exemplos descritos neste exemplo, os Jumpers do MultiPIC devem ser:
- 21 -
MultiPIC
As linha de I/O utilizadas serão PB0 à PB3 (PortB). Vamos configurar todas como SAÍDA logo
no início do programa trocando as instruções:
movlw 00000000B
movwf TRISB
em que os quatro bits menos significativos, correspondem as linhas RA0,1,2,3 foram colocados
a zero para definir estas linhas como saída.
Na área de memória do REGISTER FILE (à partir do endereço 0x20h) além dos dois bytes
referenciados pelo label Count, reservaremos mais um byte com o label Shift que utilizaremos
para determinar a sequência de funcionamento dos led's. A diretiva a ser inserida é:
Count EQU 0x20
Shift EQU 0x22
Antes de iniciar o ciclo principal (label MainLoop) vamos inicializar um novo registro Shift a
00000001B com a seguinte instrução:
movlw 00000001B
movwf Shift
Neste ponto, no ciclo principal do nosso programa, vamos tratar de transferir o valor
memorizado no registro Shift para o PortA obtendo então o início de funcionamento do
primeiro led, a instrução será a seguinte:
movf Shift,W
movwf PORTB
que então efetuará o giro para esquerda do valor contido no Shift de um bit, com a seguinte
instrução:
bcf STATUS,S
rlf Shift,F
A primeira instrução serve para zerar o bit CARRY do REGISTRO DE STATUS que vamos
analisar na próxima lição. RLF Rotate Left F through Carry (roda para esquerda o bit do carry)
desloca um bit para esquerda o valor memorizado no registro Shift inserindo na posição ocupada
pelo bit 0 o valor do bit do Carry (que como dissemos veremos em seguida). Para fazer com que
este bit seja sempre zero terá que ser executada antes da RLF a instrução BCF STATUS,C para
zerar este bit.
Neste ponto o registro Shift será 00000010B, onde, no próximo ciclo, uma vez transferido esse
valor para o PortA se obterá o apagamento do LED1 e o acendimento do LED2 e assim por
diante nos ciclos sucessivos.
Quando o bit 4 do Shift for a 1, então todos os quatro leds estiveram acesos pelo menos uma vez
e tornara a iniciar do led 1. Na instrução seguinte veremos este tipo de controle:
btfsc Shift,4
swapf Shift,F
A instrução btfsc Shift,4 controla exatamente até que o bit 4 do registro Shift vale 1. Depois
executa a próxima instrução swapf Shift,F, e continua.
A instrução swap (do inglês "troca") na prática troca o quarto bit mais significativo contido no
registro Shift, pelo quarto bit menos significativo. Do valor inicial do registro Shift igual a
00010000 obtido através do ciclo de repetição MainLoop se obtém o valor 0000001 que na
prática faz acender o primeiro Led.
- 22 -
MultiPIC
- 23 -
MultiPIC
A subdivisão da linha em duas portas diferentes é devido ao tipo de arquitetura interna do
PIC16F628 que prevê um controle de dados de no máximo 8 bits.
Para o controle da linha de I/O do programa, o PIC dispõe de dois registros internos que
controlam as portas e são chamados de TRISA e PORTA para a porta A e TRISB e PORTB
para a porta B.
Os registros TRIS A e B, determinarão o funcionamento em entrada ou em saída da mesma
linha, e o registro PORT A e B determinarão o status da linha em saída ou reportarão o status da
linha em entrada. MultiPIC
Todos os bits contidos nos registros mencionados correspondem respectivamente a uma linha de
I/O.
Por exemplo, o bit 0 do registro PORTA e do registro TRIS A correspondem a linha RA0 , o
bit 1 a linha RA1 e assim por diante.
Se o bit 0 do registro TRISA for colocado em zero, a linha RA0 estará configurada como linha
de saída, por isso o valor a que irá o bit 0 do registro PORTA determina o estado lógico de tal
linha (0 = 0volts, 1 = 5 volts).
Se o bit 0 do registro TRISA for colocado em um, a linha RA0 estará configurada como linha
de entrada, por isso o valor a que ira o bit 0 do registro PORTA determina o estado lógico de
tal linha (0 = 0volts, 1 = 5 volts).
Façamos um exemplo prático, imaginemos querer conectar um Led sobre a linha PB0 e uma
chave sobre a linha PA4, o código a se escrever será o seguinte:
movlw 00000000B
movwf trisb
movlw 00010000B
movwf trisa
onde aqui será colocado a 0 o bit 0 (linha PB0 em escrita (saída), e a 1 o bit 4 do PortA (linha
PA4) em entrada, recorde-se de tal propósito que na notação binária do assembler o bit mais a
direita corresponde com o bit menos significativo por isso o bit 0.
Para acender o led devemos escrever o seguinte código:
bsf PORTB,0
Para apaga-lo:
bcf PORTB,0
Para lermos o estado da chave conectada a linha PA4, o código será:
btfss PORTA,4
goto SwitchAMassa
goto SwitchAlPositivo
- 24 -
MultiPIC
Conhecendo melhor o funcionamento dos diversos status de escrita podemos desfrutar melhor
das características e otimizar melhor o nosso projeto.
Estado de escrita das linhas RA0, RA1, RA2 e RA3
Iniciaremos do grupo da linha RA0, RA1, RA2 e RA3 na qual representamos, na figura
seguinte, o esquema do estado de escrita extraído do datasheet da Microchip:
MultiPIC
Como dito no passo anterior, a configuração de uma linha como entrada ou saída depende do
estado do bit no registro TRIS (TRISA para o PORTA e TRISB para o PORTB).
Pegaremos como exemplo a linha RA0 e analisaremos o funcionamento do estado de saída seja
quando a mesma funciona em entrada ou quando em saída.
Funcionamento como entrada
Para configurar a linha RA0 em entrada, devemos colocar em 1 o bit 0 do registro TRISA com
a instrução:
bsf TRISA,0
Esta instrução determinará uma comutação a 1 do estado lógico do flip-flop do D-latch
MultiPIC
indicado no bloco com o nome TRIS latch. Para outra linha de I/O existe um destes flip-flop e
o estado lógico em que se trava depende estritamente do estado lógico do relativo bit no registro
TRIS (ou melhor, dizendo todos o bit's do registro TRIS são fisicamente implementados com
um TRIS latch).
A saída Q do TRIS latch é conectada a entrada de uma porta lógica do tipo OR. Isto significa
que, independente do valor presente a outra entrada, a saída da porta OR estará sempre em 1 em
quanto uma de suas entradas vale 1 (veja na tabela verdade). E nesta condição o transistor P
não conduz e mantém a linha RA0 desconectada do positivo da alimentação.
- 25 -
MultiPIC
Do mesmo modo a saída negativa Q do TRIS latch e conectada a entrada de uma porta AND
onde a saída desta estará sempre em 0 em quanto uma de suas entradas vale 0 (veja tabela
verdade). E nesta condição em que o transistor N não conduz mantendo a linha RA0
desconectada da massa. O estado lógico da linha RA0 dependerá exclusivamente do circuito
externo a que o conectarmos.
Aplicando 0 ou 5 volts ao pino RA0, será possível lermos o estado presente no circuito externo a
entrada do bloco representado por TTl input buffer e do latch de entrada.
Funcionamento como saída
Para configurar a linha de PA0 em saída, devemos colocar em 0 o bit 0 do registro TRISA com
a instrução:
bcf TRISA,0
Esta determina a comutação para 0 da saída Q do TRIS latch ( e para 1 a saída Q negativa). E
neste estado o valor da saída da porta OR e AND depende exclusivamente do estado de saída do
Q negativo do Data Latch. Como para o TRIS latch, em que o Data Latch depende do estado
de um bit em um registro, particularmente do registro PORTA. A sua saída negativa será
enviada para entrada das duas portas lógicas OR e AND e que estão diretamente sobre a base do
transistor P e N.
Se colocarmos em 0 o bit 0 do registro PORTA com a instrução:
bcf PORTA,0
Obteremos a condução do transistor N e portanto irá a 0 a linha RA0. Se ao invés colocarmos
em 1 o bit 0 com a instrução:
bsf PORTA,0
MultiPIC
Obteremos a condução do transistor P e, portanto irá a +5 volts a linha RA0. Nesta condição
será sempre possível rever o valor enviado sobre a linha através do circuito de entrada.
Estado de saída da linha RA4
Analisaremos agora o funcionamento do estado de saída da linha RA4 que é diferente de todas
as outras linhas de I/O enquanto compartilha o mesmo pino do PIC com o TOCKI o qual
iremos analisar no próximo passo.
Na figura seguinte esta descrito o esquema de blocos do estado de saída extraído do datasheet
Microchip:
- 26 -
MultiPIC
A lógica de comutação é substancialmente idêntica ao grupo das linha RA0 a 3 com exceção da
ausência da porta OR e do transistor P, ou seja de todos os circuitos que permitem a ligação ao
positivo, da linha RA4. Isto significa em termos práticos, que quando a linha RA4 está
programada em saída poderá assumir um nível que dependerá do circuito externo pois na
realidade não esta conectada ao positivo e sim desconectada. Este tipo de circuito de saída
chama-se "coletor aberto" e é útil para aplicações em que é necessário compartilhar uma
mesma ligação com mais pinos de saída ou que se tenha a necessidade de colocar em alta
impedância uma linha de saída e podendo assim reprograma-la como linha de entrada.
Se quisermos tornar seguro que a linha RA4 vá a 1 devemos conectar externamente um resistor
de pull-up, ou seja um resistor conectado ao positivo da alimentação.
Veremos em seguida a utilização da linha indicada no esquema acima TMR0 clock input.
Estado de saída das linhas RB0, RB1, RB2 e RB3
Onde que para este grupo de linhas permanece substancialmente sem mudar a lógica de
comutação. Estas dispõe de um circuito a mais, o weak pull-up conectado quando a linha for
programada em entrada.
A entrada de fato, como explicado anteriormente, a linha vem completamente desligada do PIC.
O estado da linha depende então exclusivamente do circuito externo. Se o circuito é do tipo de
coletor aberto ou simplesmente é constituído de uma simples chave que, quando pressionada,
conecta a massa a linha de I\O, é necessário inserir um resistor de pull-up vinda do positivo para
tornar seguro quando a chave for solta o nível voltar a uma condição lógica 1estavel sobre a
linha de entrada. O circuito de weak pull-up permite evitar o uso do resistor de pull-up e é
possível de ser ativado agindo sobre o bit RBPU do registro OPTION.
- 27 -
MultiPIC
Na figura seguinte está representado o esquema de blocos do estado de saída extraído do
datasheet Microchip:
Além disso, a linha RB0 sozinha, apresenta uma característica muito particular. Esta, quando for
configurada como linha de entrada, pode gerar, em correspondência a uma troca de estado
lógico, uma Interrupt, ou seja, uma interrupção imediata do programa em execução e uma
chamada a uma subrotina especial denominada interrupt handler. Mas disso falaremos em
seguida.
Estado de saída das linhas RB4, RB5, RB6 e RB7
MultiPIC
O circuito de comutação deste grupo de linhas é idêntico ao grupo RB0 a 3. Esta linha dispõe
também de um circuito de weak pull-up. E mais, com respeito a linha RB0 - 3 tem a vantagem
de poder revelar variações de estado sobre qualquer linha e gerar uma interrupção da qual
falaremos na próxima lição.
Na figura seguinte esta reproduzido o esquema de blocos do estado de saída extraído do
datasheet Microchip.
- 28 -
MultiPIC
Lição 3 Passo 3/3 Entrada de Teclas
Depois de ter realizado, no exemplo anterior, as luzes em sequência usando a linha de PB0 a
PB3 como linha de saída, vejamos agora como se pode realizar uma entrada com teclas
configurando a linha de PA0 a PA4 como linha de entrada.
Para isto usaremos as quatro chaves SW1, SW2, SW3 e SW4 disponíveis no MultiPIC 3.
Cada uma destas chaves conectadas ao GND das linhas de entrada normalmente mantidas em
+5V por um resistor. Se pressionarmos, por exemplo, a chave SW1 que está ligada ao pino 18
do PIC16F628, esta linha será mantida em 0 até que a chave seja solta quando a linha voltará
para 1 (5Volts).
Para exemplo, realizaremos um programa que acenderá qualquer um dos Leds de PB0, PB1,
PB2 e PB3 em correspondência com o pressionamento das teclas PA1 a PA4.
Nota: PA0 é o mesmo que RA0 e assim por diante.
O código do exemplo é descrito no arquivo INPUT.ASM.
Analisaremos agora o funcionamento.
A parte inicial do programa segue as mesmas funções efetuadas no exemplo anterior e, em
particular as instruções:
movlw 11111111B
movwf TRISA
Configurando a linha PB0 a PB7 em saída para conexão com os LEDs e as linhas PA1 a PA4
em entrada para a conexão com as quatro chaves (em uso somente PA1- 4).
MainLoop
clrf PORTB
btfss PORTA,SW3
bsf PORTB,LED3
btfss PORTA,SW4
MultiPIC
bsf PORTB,LED4
goto MainLoop
Efetua simplesmente um loop contínuo a qual será executada a instrução btfss (Bit Test File
Skip if Set , = teste o bit e “pule” se setado) que monitora o estado do bit da porta levando a
nível 1 (acendendo o LED) se a chave estiver pressionada (nível I/O da chave igual a zero).
- 29 -
MultiPIC
Lição 4 Introdução O contador TMR0 e o PRESCALER
MultiPIC
- 30 -
MultiPIC
movlw 10
movwf TMR0
loop
goto loop
o registro TMR0 será incrementado pelo hardware interno do PIC durante a execução do loop.
Uma vez atingido o valor 255 o registro TMR0 será zerado automaticamente retornando então a
contagem, mas não do valor originalmente imposto, mas do zero.
A freqüência é diretamente proporcional a freqüência de clock aplicada ao chip e pode ser
modificada programando-se oportunamente os seus bits de configuração.
Na figura seguinte esta representada a cadeia de blocos interno do PIC que determina o
funcionamento do registro TMR0.
O bloco Fosc/4 e T0CKI à direita na figura, representam as duas possíveis fontes de sinal para o
contador TMR0.
Fosc/4 é um sinal gerado internamente no PIC pelo circuito de clock e é par na frequência de
clock dividida por quatro.
T0CKI é um sinal gerado de um eventual circuito externo e aplicado ao pino T0CKI
correspondente ao pino 3 no PIC 16F628.
Os blocos T0CS e PSA na figura acima, são dois comutadores de sinal na qual estão
representando um dos dois tipos de sinal de entrada com base no valor dos bits TOCS e PSA do
registro OPTION.
O bloco PRESCALER é um divisor programável e que seu funcionamento será explicado na
próximo passo.
Vejamos na prática como é possível agir sobre este bloco para obter diferentes modalidades de
contagem pelo registro TMR0.
Iniciaremos programando o bit T0CS em 0 e PSA em 1. A configuração de funcionamento que
obteremos é a representada na figura abaixo:
- 31 -
MultiPIC
O caminho superior na figura com a onda quadrada, mostra-nos o percurso que efetua o sinal
antes de chegar ao contador TMR0.
Como já havíamos dito anteriormente, a frequência Fosc/4 é par e de um quarto da frequência de
clock. Utilizando-se um cristal de quartzo de 4Mhz teremos uma frequência par de 1 MHz. Tal
frequência será enviada diretamente ao registro TMR0 sem haver nenhuma modificação. A
cadência de contagem que se obtém e então par e de 1 milhão de incrementos por segundo do
valor presente no TMR0.
Imaginemos agora modificar o status do bit T0CS de 0 para 1 a configuração que obteremos é
seguinte:
Desta vez será o sinal aplicado ao pino TOCKI do PIC a ser enviado diretamente ao contador
TMR0 determinando a frequência de contagem. Aplicando-se, por exemplo, a este pino uma
frequência par de 100Hz obteremos uma de contagem par de cem incrementos por segundo.
A presença da porta lógica XOR (exclusive OR) na entrada TOCKI do PIC permite determinar
o caminho do bit TOSE do registro OPTION se o contador TMR0 deve ser incrementado na
decida do pulso (TOSE=1) ou na subida do pulso (TOSE=0) do sinal externo aplicado.
Na figura seguinte esta representada a correspondência entre a cadência do sinal externo e o
valor que assume o contador TMR0:
- 32 -
MultiPIC
MultiPIC
A primeira instrução inicializa o TMR0, a instrução seguinte memorizará em um registro de 8
bits (o nosso velho amigo Count) o valor de 16 de tal modo que, decrementará este registro de
um a cada passagem pelo zero do TMR0, até que se obtenha uma frequência de passagem pelo
zero do registro Count.
A instrução inserida no loop Delay_2 se encarrega de monitorar se o TMR0 já chegou a zero,
quando então reinicializara o bit T0IF e decrementará o valor contido em Count. Quando Count
alcançar o zero aí terá transcorrido o tempo desejado e a subrotina poderá retornar ao programa
que a chamou (MainLoop).
A interrupção é uma técnica particular do PIC que permite interceptar eventos externos ao
programa em execução, interrompe momentaneamente a operação do programa em andamento,
controla o evento com uma subrotina apropriada e retorna para a execução do programa.
- 34 -
MultiPIC
Seja para fazer um parágrafo mais ou menos explicativo, podemos dizer que a interrupção é para
o PIC, se não, o que para nós representaria uma chamada telefônica.
Para recebermos um telefonema não precisamos nos preocupar em ficar levantando
continuamente o monofone do gancho para ver se tem alguém querendo falar com nós, mas
podemos tranquilamente aguardar pelo toque da campainha quando alguém nos chama. Quando
então apenas levantamos o monofone do gancho e interrompemos momentaneamente o sistema
de chamada, respondemos ao telefone e , uma vez terminada a conversação, retornamos o
monofone no gancho ou seja, do ponto onde havíamos interrompido.
Transportando o termo deste parágrafo ao PIC veremos que::
• O nosso telefone corresponde ao programa em execução;
• a chamada de alguém corresponde ao evento de controle;
• o monofone corresponde a requisição de interrupção;
• a nossa reposta ao telefone corresponde a subrotina de controle da interrupção.
É evidente que assim como é extremamente mais eficaz se ter uma campainha conectada ao
telefone é extremamente mais eficaz controlar nosso evento com uma interrupção ao invés de
diretamente pelo programa.
MultiPIC
Tipos de eventos e bit's de habilitação
O PIC16F628 está preparado para controlar interrupções ao final de quatro eventos diferentes,
vejamos quais são:
1. A troca de estado sobre a linha RB0 (External interrupt RB0/INT pin).
2. Ao final da contagem do registro TMR0 (TMR0 overflow interrupt).
3. A troca de estado sobre uma das linhas de RB4 a RB7 (PORTB change interrupts).
4. Ao final da escrita sobre um endereço da EEPROM (EEPROM write complete
interrupt).
A interrupção de qualquer um destes eventos pode ser conseguida habilitando ou desabilitando
independentemente uns dos outros, agindo sobre os seguintes bits's do registro INTCON:
• INTE (bit 4) se este bit estiver em 1 habilitar a interrupção de troca de estado sobre a
linha RB0
• T0IE (bit 5) se este bit estiver em 1 habilitar a interrupção de final de contagem do
registro TMR0
• RBIE (bit 3) se este bit estiver em 1 habilitar a interrupção de mudança de estado sobre
uma das linhas de RB4 a RB7
• EEIE (bit 6) se este bit estiver em 1 habilitar a interrupção de final de escrita sobre um
endereço da EEPROM
Existe um outro bit de habilitação geral de interrupção que deve ser setado antes destes, ou seja,
o bit GIE (Global Interrupt Enable bit) e este é o bit 7 do registro INTCON.
Vetor de Interrupção e Controle de Interrupção
(Interrupt vector e Interrupt Handler)
Qualquer que seja o evento habilitado, ao se manifestar, o PIC interrompe a execução do
programa em andamento, memoriza automaticamente no STACK o valor corrente do
PROGRAM COUNTER e pula para a instrução presente no endereço de memória 0004H
denominada Interrupt vector (vetor de interrupção).
Deste ponto em diante devemos colocar a nossa subrotina de controle denominada Interrupt
Handler (controle de interrupção).
- 35 -
MultiPIC
Pode-se habilitar mais interrupções e, a primeira providência da Iinterrupt Handler é verificar
qual evento habilitado fez gerar a interrupção e a execução da parte do programa relativo
Este controle pode ser efetuado utilizando a Interrupt flag.
Interrupt flag (sinalizador de interrupção)
Dado que qualquer interrupção gera uma chamada do endereço 04H, no registro INTCON está
presente o flag que indica qual o evento que gerou a interrupção vejamos:
• INTF (bit 1) Se vale 1 a interrupção é um estado gerado na troca de estado na linha RB0.
• T0IF (bit 2) Se vale 1 a interrupção é um estado gerado no término da contagem do
timer TMR0.
• RBIF (bit 0) Se vale 1 a interrupção é um estado gerado da troca de estado de uma das
linhas de RB4 a RB7.
Como se pode ver a interrupção de final de escrita na EEPROM não tem previsto nenhum flag
de sinalização para que a interrupt handler deva considerar que a interrupção é um estado
gerado deste evento quando todos os três flags supra citados irão a 0.
Importante: Uma vez conhecido qual o flag esta ativa, a interrupt handler deve zera-lo, ou
então não mais gerará a interrupção correspondente.
Retorno de uma interrupt handler
Quando for gerada uma interrupção o PIC desabilita automaticamente o bit GIE (global
Interrupt Enable) do registro INTCON de modo a desabilitar todas as interrupções restantes.
Para poder retornar ao programa principal e reinicializar em 1este bit deve-se utilizar a
instrução:
RETFIE
Vejamos agora um exemplo prático de controle de interrupção. Pegaremos como base partida o
código LED.ASM usado na lição 1 para realizar um lampejador a Led.
Como recordamos este programa faz piscar o LED1 simplesmente, presente na placa MultiPIC,
num ciclo contínuo utilizando um retardo software introduzido da subrotina Delay
Vejamos agora como é possível fazer pressionando uma tecla acender o LED2 temporariamente
com a execução do programa principal.
O código de exemplo que iremos analisar está disponível no arquivo INTRB.ASM
IMPORTANTE
Para os exemplos descritos nesta lição, os Jumpers do MultiPIC devem ser:
LEDs /Displays PL80 em “LEDs”
Ativa Trimpot PR4 posicionado/ fechado
Programa 18 pinos (para 16F628)
- 36 -
MultiPIC
Uma vez carregado o programa INTRB.ASM na placa MultiPIC notaremos que os LEDs L3 e
L4 ficarão piscando alternadamente. Devemos agora pressionar as tecla SW4 (PA4) ou girar o
Trimpot RV2. Veremos que o LED L5 se acende imediatamente.
Na prática entre o loop principal, derivado do código LED.ASM, e faz lampejar os LEDs L3 e
L4 utilizando um retardo software introduzido da subrotina Delay, o PIC fará com que ao
pressionarmos SW4 ou girar o Trimpot RV2, imediatamente o LED L5 acenderá mostrando o
desvio do programa principal.
Analisaremos agora o código fonte deste programa.
Partindo da diretiva ORG 00H que, como vimos serve para posicionar o nosso programa a
partir da posição de Reset, ou seja, do endereço 0.
Notamos subitamente que a primeira instrução que o PIC encontra é um desvio incondicional
para o label Start:
ORG 00H
goto Start
Seguido de uma nova diretiva:
ORG 04H
e então do código da subrotina de controle da interrupção:
ACONTECEU_INTERRUPT
bsf PORTB,LED4 ;acende o led4
CALL Delay
bcf PORTB,LED4 ;APAGA o led4
BCF CMCON,0x06
BCF CMCON,0x07
BCF PIR1,CMIF ;flag DA INTURRUP DO COMPARATOR
Como havíamos dito na lição anterior, a Interrupt Handler (gerenciador de interrupção), neste
caso a subrotina “ACONTECEU_INTERRUPT” deve ficar necessariamente a partir do endereço
04H, para evitar que seja executada logo após o Reset devemos pulá-la com uma instrução de
salto incondicional, neste caso a linha: “goto Start” faz isto.
O código da Interrupt Handler (gerenciador de interrupção), neste caso, é muito simples e se
limita a acender o LED 4 e mantê-lo acesso enquanto a tecla estiver pressionada.
A instrução RETFIE permite ao PIC retornar a executar o programa à partir do ponto que foi
interrompido pela interrupção.
Mas porque é gerada uma interrupção quando pressionamos a tecla SW4 ou ao girar o
Trimpot?
Pois a interrupção é habilitada (veja detalhes do registrador INTCON no datasheet do PIC):
movlw 11000000B ;HABILITA A INTURRUP DO COMPARATOR
movwf INTCON
Onde na prática foi colocado a um o bit GIE (bit 7) que é a habilitação global das interrupções e
onde o bit PEIE (bit 6) que habilita, particularmente, a interrupção sobre troca de estado do
Módulo Comparador do PIC ( maiores detalhes deste módulo na seção 9.6 do datasheet).
- 37 -
MultiPIC
Na prática, monitorando a chave SW4 para simular a interrupção ou ao mudar de estado o
Módulo comparador do PIC (girando o Trimpot RV2) é gerada a interrupt.
No Loop principal, temos a execução de acender e apagar dos LEDs L3 e L4 alternadamente.
IMPORTANTE
Para os exemplos descritos nesta lição, os Jumpers do MultiPIC devem ser:
LEDs /Displays PL80 em “LEDs”
Ativa Trimpot PR4 posicionado/ fechado
Programa 18 pinos (para 16F628)
Compile e descarregue o programa DBLINT.ASM na placa MultiPIC e veremos que além dos
LEDs L2 & L3 que lampejam com a frequência anterior, e o LED L5 com uma frequência mais
elevada.
Pressionando-se a tecla SW4 (PA4) ou girando o Trimpot, obtemos a costumeira ascensão do
L4. O efeito final que obtemos é a execução de três tarefas a uma velocidade tal que se
assemelha com uma execução paralela.
Analisando agora o código DBLINT.ASM.
Ao modificar o anterior observe a Interrupt Handler no inicio do qual esta efetuado um controle
sobre qual evento havia gerado a interrupção. Com a instrução:
btfsc INTCON,T0IF ;ve qual interrupção o trouxe até aqui
goto IntT0IF
btfsc PIR1,CMIF
goto IntRBIF
retfie
Será controlado o flag T0IF e CMIF para ver respectivamente se o evento que
provocou a interrupção provem do registro TMR0 ou do comparador. E seguida será posta em
execução a relativa subrotina de controle a partir do label intT0IF e intRBIF.
- 38 -
MultiPIC
Lição 6 Introdução O Power Down Mode (Sleep)
- 39 -
MultiPIC
O "despertar" do PIC
Para despertar o PIC do seu sono podemos utilizar diversas técnicas:
1. Reset do PIC colocando em 0 o pino MCLR (pino 4)
2. Timeout do timer do Watchdog (se habilitado)
3. Verificação de uma situação de interrupção (interrupção do pino RB0/INT, troca de
estado sobre a porta B, termino da operação de escrita na EEPROM)
No caso 1 e 2 o PIC será resetado e a execução começará da posição 0. No caso 3 o PIC se
comporta como no atendimento de uma interrupção (veja lição 5) irá para a primeira Interrupt
Handler e então retornará para execução após a instrução SLLEP. Para que o PIC possa retornar
de uma interrupção devemos habilitar o flag do registro INTCON.
O bit TO e PD do registro STATUS podem ser utilizados para determinar se a causa do
despertar esta ligada a simples ascensão do PIC, o Reset ocorre na chegada de uma interrupção.
IMPORTANTE
Para os exemplos descritos nesta lição, os Jumpers do MultiPIC devem ser:
LEDs /Displays PL80 em “LEDs”
Ativa Trimpot PR4 posicionado/ fechado
Programa 18 pinos (para 16F628)
- 40 -
MultiPIC
- 41 -
MultiPIC
- 42 -
MultiPIC
Anotações:
Introdução ao PIC ®
Copyleft Smart Radio 2008-2012
- 43 -