Microcontrolador PIC 16F8X - Resumo da Arquitetura
MC404B - Nov 2001
- Prof. Célio Guimarães.
O que é um microcontrolador?
Ao contrário de um microprocessador que é
um chip contendo apenas a CPU e seus registradores,
um microcontrolador é um computador completo
(quase) num único chip. O PIC 16F8X é um microcontrolador
de 8 bits contendo:
-
1K de memória flash para instruções (program
memory) com 14 bits/palavra ( cada instrução do PIC16F8X
tem 14 bits! )
-
80 bytes (8bits) de memória ram implementada em registradores,
dos quais 12 especiais e 68 de propósito geral (file registers
). Existem na verdade dois bancos de memória ram (chaveados
através do bit 5 do registrador de estado)
-
64 bytes de memória EEPROM para guardar dados não voláteis
-
arquitetura Harvard com um barramento de 14 bits para
instruções e um barramento de 8 bits para dados,
independentes entre si, proporcionando maior desempenho sobre uma arquitetura
convencional "von Neumann", onde instruções e dados residem
na mesma memória e são acessados através do mesmo
barramento.
-
35 instruções, cada uma ocupando uma palavra de 14 bits e
executando em um único ciclo (como nas CPUs de arquitetura RISC)
(exceção: as instruções de chamada de rotina
e desvios executam em 2 ciclos)
-
pilha implementada por hardware com 8 níveis (até 8 chamadas
de rotinas aninhadas)
-
13 pinos bidirecionais de E/S (5 na porta A e 8 na
porta
B ) Obs: o PIC 16F8X tem apenas 18 pinos!
-
4 tipos de interrupções associadas a: 5 pinos
distintos da porta B, ao overflow do timer e à escrita na
EEPROM
-
timer/counter programável e um Watchdog Timer embutidos, este
com seu próprio oscilador, para aplicações de Tempo
Real críticas.
-
recursos de hardware para proteção de código, modo
de operação com baixo consumo de energia (sleep),
programação "in-circuit", alta corrente de saída para
LEDs (25 mA), power-on-reset, power-up timer, etc
Unidade Lógica e Aritmética (ULA)
A ULA do PIC possui 8 bits de largura e um único
acumulador denominado w (working register
). Ela faz operações aritméticas
de soma e subtração (em 2- complemento) e operações
lógicas como rotate, and or, xor etc.
Nas operações lógicas e aritméticas com
2 operandos, o acumuldador w é sempre um dos operandos
e qualquer um dos 80 registradores f pode
ser o 2º operando (ou uma constante de 8 bits ou literal,
codificada na própria instrução).
Instruções lógico/aritméticas com um só
operando ( por exemplo inc, dec, clr, com, bit set, etc)
tomam como operando ou o acumulador w ou um
registrador f .
As instruções lógicas e aritméticas podem
atualizar os bits Z (zero) , C (carry) e DC(digit
carry) do registrador de estado (f=03).
Uma característica interessante das instruções
com dois operandos envolvendo w e um registrador f
é que um bit na instrução permite escolher se o
resultado vai para o acumulador w (bit=
0) ou para o registrador f (bit = 1), permitindo algumas
operações pouco convencionais como: f - w =>
w.
Nos mnemônicos das instruções do PIC o destino
do resultado é designado genéricamente pela letra d
e
específicamente pelas letras f ou w
( é conveniente, portanto, definir nos programas em assembler duas
constantes w e f com as diretivas: w
equ 0 e f equ 1 ). Por exemplo: a instrução
movf f,w move o conteúdo de um registrador genérico
f para o acumulador w, a instrução
movwf
f move o conteúdo do acumulador w
para um registrador genérico f e a instrução
movlw
k move uma constante k para w .
Obs: achamos a notação para essas instruções
(que são muito usadas) confusa e assimétrica (isto é,
não ortogonal) , dificultando o aprendizado da programação
com o PIC. Existem na verdade dois paradigmas largamente utilizados para
codificação simbólica de instruções
com dois operandos: o paradigma da Intel, onde uma instrução
genérica do tipo:
opr
dest, source significa:
dest
<= dest opr source
(interprete o símbolo
<=
como
"recebe" e opr como a operação feita pela instrução)
e o paradigma do (venerável) minicomputador PDP11 da década
de 70 (e seus seguidores como os microprocessadores Motorola MCHC11 e MC68000),
onde uma instrução do tipo:
opr
source, dest significa: source
opr dest => dest ( interprete o símbolo =>
como "vai para" )
Ambos os paradigmas são aceitáveis e naturais, desde que
usados de forma ortogonal isto é, todas as instruções
com dois operandos deveriam usar um dos dois formatos acima.
O PIC 16F8X adota o paradigma do PDP11, porém
de forma não ortogonal como pode ser notado claramente nas
3 instruções vistas anteriormente. Por esta razão
desenvolvemos algumas macros simples para essas instruções
(e algumas outras) em mymacros.inc
e que podem facilitar a programação com o PIC.
Registradores f especiais (SFR - Special File Registers)
Os registradores f de número 0 a 0xb são especiais,
mas podem ser (na sua maioria) lidos/alterados por qualquer instrução
envolvendo um registrador f. Alguns refletem o estado da CPU e são
particularmente importantes para o programador assembler:
-
registrador de estado(03 - status register): os bits 0 (C)
, 1 (DC) e 2 (Z) armazenam respectivamente o Carry,DC
e Zero, já mencionados. (o bit DC tem a mesma função
do Carry Auxiliar do 8086 e do 8085). O bit 5 (RP0), quando 0
(default) seleciona o banco de registradores 0 e se mudado para 1,
o banco 1.
-
o registrador 2 (PCL) contém os 8 bits de mais baixa ordem
do Program Counter (que possui 13 bits).
-
o registrador 4 (FSR) é o único registrador do tipo
apontador
para memória do PIC: o seu conteúdo identifica um dos
80 file registers e é referenciado através
do registrador fictício 0 (INDF): por exemplo, se
FSR
contém
20h a insrução : movwf INDF move o conteúdo
de w para a posição 20h da memória ram. Ver um exemplo
completo em resumo
das instruções. Pode ser escrito para carregar o valor
de um apontador (e lido também)
-
o registrador 01 (TMR0) contém o valor corrente do
real time clock. Pode ser lido/escrito.
-
os registradores 05 (PORTA) e 06 (PORTB) representam
as portas de E/S do PIC (bits 0-4 de PORTA e bits 0-7 de
PORTB).
Podem ser lidos em operações de entrada de dados e escritos
em operações de saída de dados.
-
o registrador 0Bh (INTCON) contêm os bits que habilitam/registram
os vários tipos de interrupção do PIC:
-
bit 7 (GIE - Global Interrupt Enable): se 1, habilita
todas as interrupções não mascaradas
-
bit 6 (EEIE - EE Write Complete Interrupt Enable):
se 1, habilita a interrupção de fim de escrita na EEPROM
-
bit 5 (TOIE - TMR0 Overflow Interrupt Enable): se 1, habilita
a interrupção de overflow do Timer 0
-
bit 4 (INTE - RB0 Interrupt Enable): se 1 habilita a interrupção
no pino RB0
-
bit 3 (RBIE - RB Port Change Interrupt Enable): se
1, habilita interrupção por mudança de estado nos
pinos RB4-RB7
-
bit 2 (TOIF - TMR0 overflow inerrupt flag bit): se
1, indica que houve overflow do Timer 0 (passou de ff para 00)
-
bit 1 (INTF - RB0/INT Interrupt bit): se 1 indica
ocorrência de interrupção no bit RB0
-
bit 0 (RBIF - RB Port Change Interrupt bit): se 1,
indica que pelo menos um dos bits RB4-RB7 mudou de estado
Instruções lógico/aritméticas com dois operandos
(veja detalhes no resumo
das instruções )
soma: addwf
f, d
subtração: subwf f, d
and: andwf
f, d
ou:
iorwf f, d
ou exclusivo: xorwf f,d
soma literal a w: addlw k
subtrai literal - w: sublw k
idem para:
andwl k
iorwl k
xorwl k
Instruções lógico/aritméticas com um
operando (veja detalhes no resumo
das instruções )
Há instruções para zerar f (clrf f)
ou w (clrw) , incrementar f (incf f,d) decrementar
f (decf f,d) , complementar f(comf f,d) , rotacionar
f junto com Carry à esquerda (rlf f,d) ou à
direita (rrf f,d) zerar (bcf f,b) ou ligar
(bsf f,b) um bit específico b de um
registrador f.
Instruções de salto, chamadas de rotinas e desvio condicional
(skip)
A instrução goto end desvia o programa para
a instrução localizada no endereço end ( onde
end
é uma constante de 11 bits). Como o Program Counter (PC) do
PIC 16F8X possui 13 bits não é possível atingir diretamente
todo o espaço de endereçamento do processador, mas isto na
prática é irrelevante pois o PIC16F8X possui capacidade para
apenas 1K instruções, que podem ser endereçadas com
10 bits. Por esta razão vamos ignorar o truque para atingir todo
o espaço de endereçamento.
A instrução call end chama uma rotina localizada
no endereço end, empilhando o endereço de retorno
na pilha do sistema, que é inteiramente controlada
pelo hardware. A instrução return retira da
pilha o último endereço lá colocado passando-o para
o PC (não existem instruções do tipo push
e pop no PIC). Uma variante interessante e útil da
instrução return permite retornar de uma rotina
com um valor no registrador w: return k.
Existem quatro instruções que permitem condicionalmente
saltar a próxima instrução ( skip):
decfsz f, d e incfsz
f, d respectivamente decrementam / incrementam o valor
de um registrador f e se o resultado for zero, saltam a próxima
instrução. Elas são úteis para implementar
um laço através de um contador de iterações
armanenado num registrador f.
As instruções btfsc f,
b (leia: bit test and skip if clear
) e btfss f,b ( leia: bit
test and skip if set) permitem testar o valor de um dos
8 bits de um registrador f (codificado numa constante b de 3 bits)
e saltar a próxima instrução caso, respectivamente,
o bit seja 0 (clear) ou 1 (set).