Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Microcontrolador – 16F84A
Principais características :
Os circuitos de CLOCK :
O PIC pode operar com 4 modos diferentes de osciladores, a saber:
OBS.: também podemos um circuito de clock externo , gerado por um oscilador qualquer
que entrando por osc1 ira determinar a frequência de trabalho para um ou mais PIC .
O circuito de Reset :
a) O PIC pode ser resetado ao alimentar o mesmo, através do pino MCLR\ ligado em Vcc,
esta seria a forma mais básica :
b) Um circuito mais elaborado, seria com uma chave para reset manual, quando
necessário.
Nota : o pic possui ainda um sistema que gera 72 mS fixo, após o final do POR usado,
ficando por mais este tempo em reset.
Nota : quando utilizamos o modo XT, LP ou HS, o timer de partida do oscilador (OST) é
automaticamente acionado por 1024 períodos do oscilador, para sair do reset; isto garante a
estabilização do cristal ou resonador.
As memórias do PIC :
A família PIC possui em sua arquitetura, segmentos de memória separados para programas
e dados, e inclusive com palavras de tamanho diferentes.
O PC (programa counter) da família 16Cxxx tem 13 bits, permitindo memória de
programa de até 8Kbytes (2 exp.13).
O pic 16F84A possui apenas 1K (000 até 3FFh). Qualquer referência a outras
posições de memória serão deslocadas para este bloco de 1K. No reset do PC ele aponta
para o endereço 000 e ao atender uma interrupção o PC é carregado com o endereço 004h.
a) Memória de programa – devido a estrutura Havard ela pode ter palavras de 12,14ou 16
bits, no caso do 16F84 o tamanho da palavra manipulada na memória é de 14 bits; esta
área reservada do microcontrolador é onde será gravado o programa de controle do
mesmo ,em alguns modelos temos uma eprom, no CI em estudo a memória é do tipo
FLASH, o que nos permite gravar e apagar centenas de vezes esta memória, tornando-
se o ci mais indicado para desenvolvimento de sistemas.
b) Stack (pilha) : local separado da memória de programa para salvar endereços do PC,
para o qual o programa principal retornara após executar interrupções ou subrotinas que
forem chamadas. O stack salva só o endereço de retorno, as condições do
microcontrolador tem que serem tratadas pelo usuário. O stack do 16F84 tem 8 níveis ,
ou seja se passar deste número de interrupções ou subrotinas ele perdera a mais antiga.
c) Memória de dados : nada mais é do que uma área de RAM , utilizada para guardar as
variáveis e registradores usados pelo sistema microcontrolado, no PIC esta área é
separada em bancos de memória, no caso do 16F84 temos o banco 0 e banco 1, que são
selecionados pelos bits RP1 e RP0 do registro STATUS que veremos adiante.
d) SFR (special function registers – registros especiais de controle) : são usados pela CPU
e ou periféricos para controlar o funcionamento do chip conforme o desejado. Se
dividem em 2 tipos , controle e uso da CPU e controle e uso dos periféricos. São lidos e
escritos tanto pelo usuário como pelo hardware, ocupam espaço na RAM, e podem estar
em um ou em ambos os bancos de memória, e são acessados através de seu endereço.
f) EEPROM : alguns PIC possuem esta memória especial não volátil (o 16F84 possui uma
de 64 bytes), que podemos usar para escrever ou ler dados .
BANCO 0 BANCO 1
As interrupções do PIC :
a) STATUS : Configura a página de memória atual (banco 0 ou 1), flags da ULA e forma
do ültimo reset.
Nota : para assegurar uma taxa de 1:1 na frequência de contagem do timer0 direcionar o
prescaler para Watch dog .
TRISA
BIT 7 NC
BIT 6 NC
BIT 5 NC
BIT 4 RA4 Pino 3 0=saída 1=entrada
BIT 3 RA3 Pino 2 0=saída 1=entrada
BIT 2 RA2 Pino 1 0=saída 1=entrada
BIT 1 RA1 Pino 18 0=saída 1=entrada
BIT 0 RA0 Pino 17 0=saída 1=entrada
TRISB
PCL
PORTA
Nota : todos os pinos do PORTB possuem Pull-up interno, e para ser habilitado
globalmente o bit 7 (RPBU\) do OPTION deve ser zerado. Individualmente apenas os bits
de entrada terão pull-ups habilitados.
g) TIMER 0 : contador de 8 bits na memória que pode ser acessado para escrita ou leitura.
O seu incremento pode ser interno ( Fclock/4, logo T=1/(fclock/4)),o que em um clock
de 4Mhz será um pulso a cada 1uS . Também pode ser incrementado externamente pelo
pino RA4 (TOKI). Nosso TIMER 0 pode ser usado de duas formas, temporizador ou
contador.
BIT 7 ESCRITA/LEITURA
BIT 6 ESCRITA/LEITURA
BIT 5 ESCRITA/LEITURA
BIT 4 ESCRITA/LEITURA
BIT 3 ESCRITA/LEITURA
BIT 2 ESCRITA/LEITURA
BIT 1 ESCRITA/LEITURA
BIT 0 ESCRITA/LEITURA
Modo timer (sinal interno): ao ajustar TOCS=0 no OPTION, o timer será incrementado a
cada ciclo de máquina (4Mhz 1uS). E por lógica de programação , faremos o controle de
transbordo do contador através da interrupção (T0IE) ou através T0IF que quando igual a 1
ocorreu overflow e se igual a 0 não ocorreu.
Modo contador (sinal externo RA4) : o timer 0 incrementará sua contagem a cada pulso
presente no pino TOCKI. Para ser incrementado na borda de subida fazer TOSE=0 e na
borda de descida TOSE=1.
h) WATCH DOG (cão de guarda): timer especial que funciona com um clock RC interno
e independente do clock do uC. O tempo normal de transbordo do WDT é de 18 mS,
mas pode variar com a temperatura e a tensão de alimentação. Ele resetara o uC sempre
que ocorrer o overflow, isto impede que haja travamento no uso do uC em circuitos
críticos, pois o programador devera implementar uma subrotina para dar clear no WDT,
antes do transbordo de seu contador (instrução clrwdt) cujo o valor básico é FFh (pode
assumir outros valores com o uso do prescaler). O WDT é selecionado durante a
gravação do PIC para estar ativo ou não.
i) PRESCALER : um registro de 8 bits que pode dividir o sinal de clock , tando do timer 0
como do WDT por 256 , conforme tabela anexa ao registro OPTION.
Nota : quando queremos uma contagem de 1:1 no timer 0 devemos atribuir o prescaler ao
WDT que tem esta relação .
J) INDF e FSR : registro para endereçamento indireto; onde o INDF e o registro onde eu
darei os comandos, e no fsr o endereço que estes comandos irão atuar.
Exemplo : clrf indf - se no FSR eu estiver com o valor 18h, o clear dado no registro
indf ira zerar a posição 18h da RAM de uso geral.
k) EEPROM : já sabemos que o PIC 16F84 possui esta memória de 64 bytes, que pode ser
usada como memória de dados. Sua vantagem é que não perde as informações , mesmo sem
alimentação. Pode ser usado para gravar diversas informações em circuitos de controle
remoto, telefones, alarmes e etc. Possui 4 registros importantes para seu funcionamento, são
eles : EEADR, EEDATA, EECON1 e EECON2.
EEDATA tem duas funções, escrevemos o dado a ser gravado, no endereço escolhido, ou
teremos o dado lido da eeprom.
EECON2 é um registro que não sofre ajustes, é usado durante o processo de escrita da
eeprom, será visto nos modelos de programas adiante.
Nota 1 : o PIC 16F84 possui no endereço 2007 da memória de programa, 14 bits que os
gravadores preenchem, com informações determinadas pelo usuário.
ADDLW k Soma W e k 1
ANDLW k And entre W e k 1
CALL k Chama sub-rotina 2
CLRWDT Zera timer Watch dog 1
GOTO k Desvia p/label k 1
IORLW k OR entre W e k 1
MOVLW k W=k 1
RETFIE Retorna de interrup. 2
RETLW k Retorna c/ w = k 2
RETURN Retorna de sub-rotina 2
SLEEP Entra em modo sleep 1
SUBLW k Subtrai k de W 1
XORLW k Xor entre W e k 1
PROGRAMAS EXEMPLOS
b) Seqüencial de 4 LEDS .
Neste programa iremos aprender a fazer bases de tempo (temporização), usando ciclos de
máquina para obtermos o tempo desejado entre o ligar e desligar de cada LED da
seqüência. Usaremos o PORTB como saída, sendo definido em nosso programa o P0B até
o P3B os pinos que usaremos para acionamento de LED1 (D1) até LED4 (D4)
respectivamente. Vamos ao circuito :
O programa :
;------------------------------------------------------------------------------
; TABELA DE DEFINIÇÕES DE RAM E CONSTANTES (defino nomes associados a
; valores)
;------------------------------------------------------------------------------
x equ 0CH ; define variável auxiliar x na ram 0Ch (hexadecimal)
y equ 0DH ; define variável auxiliar y na ram 0Dh (hexadecimal)
STEMP equ 0EH ; define variável p/colocar vlrs.temporarios do status
l1 equ 7 ; define led1 ligado ao pino 7 do portB
; variáveis acima são exemplos do uso da diretriz EQU
;------------------------------------------------------------------------------
; TABELA DE MONTAGEM DO DISPLAY
;------------------------------------------------------------------------------
;
; a=RB0 define segmento do display ligado ao pino 0 do portB
; b=RB1 " " " " " " " 1 do portB
; c=RB2 " " " " " " " 2 do portB
; d=RB3 " " " " " " " 3 do portB
; e=RB4 " " " " " " " 4 do portB
; f=RB5 " " " " " " " 5 do portB
; g=RB6 " " " " " " " 6 do portB
;
; fica em binario: B'0gfedcba', para escrever n.7 ==> B'00000111' ou B'00000cba'
; , para escrever n.6 ==> B'01111101' ou B'0gfedc0a' , etc.
;
; a
; *******
; f* *b
; * g *
; ******* DISPLAY
; e* *c
; * *
; *******
; d
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; MEMÓRIA DE PROGRAMA
;------------------------------------------------------------------------------
org 0 ; define inicio do programa a partir do end. 0h
goto inicio ; desvia o progrma para o label (rótulo) início
;------------------------------------------------------------------------------
; INÍCIO DA ROTINA DE INTERRUPÇÃO
;------------------------------------------------------------------------------
org 4 ; sempre inicia no end.4h as interrup.no PIC
swapf STATUS,W
movwf STEMP ; stemp=w=status (c/nibles invertidos)
bsf PORTB,l1 ; ligo led1 pino 7 do portB
movlw 0x0F6 ; w=F6h
movwf TMR0 ; tmr0=w=F6h
call tempo
bcf PORTB,l1 ; desligo led1
swapf STEMP,W
movwf STATUS ; move vlrs.stemp p/status (inv.nibles/fica correto)
bcf INTCON,T0IF ; zera o indicador de overflow p/iniciar novam.
retfie ; comando de retorno de interrupção
;------------------------------------------------------------------------------
; INÍCIO DO PROGRAMA
;------------------------------------------------------------------------------
inicio:
; inicialização do uC
movlw B'10000000' ; w=10000000b
movwf INTCON ; INTCON=w , GIE esta habilitada
bsf STATUS,RP0 ; seleciono banco1
movlw B'11111000' ; w=11111000b
movwf OPTION_REG ; OPTION=w , T0CS=1 contagem por RA4 , externa
movlw B'11111111' ; w=FFh
movwf TRISA ; trisa=w , portA entrada
movlw B'00000000' ; w=0
movwf TRISB ; trisb=w , portB saídas
bcf STATUS,RP0 ; seleciono banco0
movwf PORTA ; portA=w=0
movwf PORTB ; portB=w=0
principal:
movlw 0x0F5 ; w=0F5h
movwf TMR0 ; timer0=w
bcf INTCON,T0IF ; reset no bit indicador de overflow
bsf INTCON,T0IE ; seto o bit de interrupção do timer0
loop:
movf TMR0,0 ; w=tmr0
call certo ; sub-rotina de conversão p/7 segmentos
movwf PORTB ; portB=w
nop
goto loop
certo:
andlw B'00001111' ; and w p/limitar em 4 bits vlr.contador
sublw 0x0E ; subtrai de 14 o vlr.w(vlr.do tmr0 acertado)
addwf PCL ; soma valor de w com pcl, saltando p/ instrução
; necessária p/escrita do número correto
;'0gfedcba' sequência dos segmentos
1) Pinagem padrão.
MÓDULO TIPO INST. TEMPO INST. TEMPO INST. TEMPO INST. TEMPO INST. TEMPO
3) Agora iremos descrever quais os pinos do uC iremos usar para gerar os sinais de
controle e transferência de dados para o LCD. Usaremos a porta A para gerar os sinais de
controle e a porta B para enviarmos dados e instruções.
;------------------------------------------------------------------------------
; FORMULÁRIO PADRÃO PARA USO EM PROGRAMAÇÃO COM
; MICROCONTROLADORES
; DA LINHA PIC ( MICROCHIP ). COM USO DO COMPILADOR MPASWIN.
;------------------------------------------------------------------------------
; ** Os registros da CPU serão escritas com letras maiúsculas, e a-
; pós " ; " os comentários não serão considerados pelo compilador.
;------------------------------------------------------------------------------
; PROJETO : Display-LCD DATA : 29/10/2002
;------------------------------------------------------------------------------
; AUTOR :Mauricio Madeira Oliveira
;------------------------------------------------------------------------------
list p=16F84 ;para qual processador o código será gerado
radix dec ;padrão decimal para valores sem identificação
include <p16f84a.inc> ;anexa arquivo def.16F84A
;------------------------------------------------------------------------------
; TABELA DE DEFINIÇÕES DE RAM E CONSTANTES (defino nomes associados a
valores)
;------------------------------------------------------------------------------
x equ 0Ch ; define variável auxiliar x na ram 0Ch (hexadecimal)
y equ 0Dh ; define variável auxiliar y na ram 0Dh (hexadecimal)
con0 equ 0h ; controle do sinal RS (LCD) através do PA.0
con1 equ 1h ; controle do sinal CS (LCD) através do PA.1
M equ 0x4D
I equ 0x49
;C equ 0x43
R equ 0x52
O equ 0x4F
N equ 0x4E
T equ 0x54
L equ 0x4C
A equ 0x41
D equ 0x44
U equ 0x55
S equ 0x53
E equ 0x45
# equ 0x23
;------------------------------------------------------------------------------
; MEMÓRIA DE PROGRAMA
;------------------------------------------------------------------------------
org 0 ; define inicio do programa a partir do end. 0h
goto início ; desvia o progrma para o label (rótulo) início
;------------------------------------------------------------------------------
; INÍCIO DA ROTINA DE INTERRUPÇÃO
;------------------------------------------------------------------------------
org 4 ; sempre inicia no end.4h as interrup.no PIC
; rotinas ...............................
retfie ; comando de retorno de interrupção
;------------------------------------------------------------------------------
; INÍCIO DO PROGRAMA
;------------------------------------------------------------------------------
início:
movlw B'00000000' ; w=0
movwf INTCON ; inticon=w int.desabilitadas
bsf STATUS,RP0 ; sel.banco1
movwf TRISB ; portB def.para saída
movlw B'11111100' ; w=11111100
movwf TRISA ; PA.0 e PA.1 def.saidas , demais input
movlw B'11011000' ; w=11011000b
movwf OPTION_REG ; option=w (verif.naa tabela as atribuições)
movlw B'00000000' ; w=o
bcf STATUS,RP0 ; sel.banco0
movwf PORTA ; portA=w
movwf PORTB ; portB=w
bcf PORTA,con0
movlw 0x80
movw f PORTB
call time
bsf PORTA,con0 ; portA P0=1, RS=1 , LCD recebe dados
movlw 0x43 ; letra C
movwf PORTB
call time
movlw U
movwf PORTB
call time
movlw R
movwf PORTB
call time
movlw S
movwf PORTB
call time
movlw O
movwf PORTB
call time
movlw #
movwf PORTB
call time
movlw D
movwf PORTB
call time
movlw E
movwf PORTB
call time
movlw #
movwf PORTB
call time
bcf PORTA,con0 ; porta P0=0, RS=0 , LCD recebe inst.
Movlw 0x0C0 ; w=C0h
Movwf PORTB ; cursor vai p/2.linha, 1.coluna do LCD
call time
bsf PORTA,con0
movlw M
movwf PORTB
call time
movlw I
movwf PORTB
call time
movlw 0x43
movwf PORTB
call time
movlw R
movwf PORTB
call time
movlw O
movwf PORTB
call time
movlw 0x43
movwf PORTB
call time
movlw O
movwf PORTB
call time
movlw N
movwf PORTB
call time
movlw T
movwf PORTB
call time
movlw R
movwf PORTB
call time
movlw O
movwf PORTB
call time
movlw L
movwf PORTB
call time
movlw A
movwf PORTB
call time
movlw D
movwf PORTB
call time
movlw O
movwf PORTB
call time
movlw R
movwf PORTB
call time
aqui: goto aqui
temp1:
movlw 18 ; 1uS
movwf y ; 1uS
temp2:
nop ; 1uS
decfsz y ; decrementa y de 1,se>0 exec.prox.inst.
goto temp2 ; se=0 salta prox.inst.
decfsz x ; 1uS
goto temp1 ; 1uS
return ; 1uS
;------------------------------------------------------------------------------
; FORMULÁRIO PADRÃO PARA USO EM PROGRAMAÇÃO COM
; MICROCONTROLADORES
; DA LINHA PIC ( MICROCHIP ). COM USO DO COMPILADOR MPASWIN.
;------------------------------------------------------------------------------
; ** Os registros da CPU serão escritas com letras maiúsculas, e a-
; pós " ; " os comentários não serão considerados pelo compilador.
;------------------------------------------------------------------------------
; PROJETO : Controle de motor de passo DATA : 09/11/2002
;------------------------------------------------------------------------------
; AUTOR :Mauricio Madeira Oliveira
;------------------------------------------------------------------------------
list p=16F84 ;para qual processador o código será gerado
radix dec ;padrão decimal para valores sem identificação
include <p16f84a.inc> ;anexa arquivo def.16F84A
;------------------------------------------------------------------------------
; TABELA DE DEFINIÇÕES DE RAM E CONSTANTES (defino nomes associados a
valores)
;------------------------------------------------------------------------------
x equ 0Ch ; define variável auxiliar x na ram 0Ch (hexadecimal)
y equ 0Dh ; define variável auxiliar y na ram 0Dh (hexadecimal)
n equ 0Eh ; define variável auxiliar n na ram 0Eh (hexadecimal)
; variáveis acima são exemplos do uso da diretriz EQU
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; MEMÓRIA DE PROGRAMA
;------------------------------------------------------------------------------
org 0 ; define inicio do programa a partir do end. 0h
goto início ; desvia o progrma para o label (rótulo) início
;------------------------------------------------------------------------------
; INÍCIO DA ROTINA DE INTERRUPÇÃO
;------------------------------------------------------------------------------
org 4 ; sempre inicia no end.4h as interrup.no PIC
; rotinas ...............................
retfie ; comando de retorno de interrupção
;------------------------------------------------------------------------------
; INÍCIO DO PROGRAMA
;------------------------------------------------------------------------------
início :
movlw B'00000000' ; w=0d
movwf INTCON ; desabilito todas as interrupções
movlw B'10001000' ; w=88h
movwf OPTION_REG ; option=w , verificar tabela
bsf STATUS,RP0 ; seleciono banco1
movlw B'00000000' ; w=0d
movwf TRISB ; portB=saida
movlw B'11111111' ; w=ffh
movwf TRISA ; portA=entrada
bcf STATUS,RP0 ; seleciono banco0
movlw B'00000000' ; w=0d
movwf PORTB ; portB=0d
movwf PORTA ; portA=0d
HORARIO:
Movlw 100 ; w=100d
Movwf n ; n=100d
HORA1:
Movlw B'00001000' ; w=8h
movwf PORTB
call TIME ; chama rotina de tempo
call CON1 ; chama rotina de controle1
movlw B'00000100' ; w=4d
movwf PORTB
call TIME
call CON1
movlw B'00000010' ; w=2d
movwf PORTB
call TIME
call CON1
movlw B'00000001' ; w=1d
movwf PORTB
call TIME
call CON1
goto HORA1
ANTIHORA:
movlw 100
movwf n
ANTI1:
Movlw B'00000001' ; w=1h
Movwf PORTB
call TIME ; chama rotina de tempo
call CON2 ; chama rotina de controle2
movlw B'00000010' ; w=2d
movwf PORTB
call TIME
call CON2
movlw B'00000100' ; w=4d
movwf PORTB
call TIME
call CON2
movlw B'00001000' ; w=8d
movwf PORTB
call TIME
call CON2
goto ANTI1
TIME:
movlw 100 ; w=100d
movwf x ; x=w
TIM1:
movlw 248 ; w=248d
movwf y ; y=w
TIM2:
nop
decfsz y ;dec.y,pula prox.inst.se =0
goto TIM2
decfsz x
goto TIM1
return
CON1:
decfsz n
return
goto ANTIHORA
CON2:
decfsz n
return
goto HORARIO
end
Memória EEPROM .
1) Escrevendo na EEPROM.
- Coloco o endereço de escrita no EEADR ( 0 a 63 ou 0 a 3Fh).
- O dado a ser escrito coloco em EEDATA.
- Desabilito as interrupções (GIE = 0).
- Habilito a escrita setando o bit WREN no registro EECON1.
- Carrego o registro EECON2 com os valores 0x55 e 0xAA nesta seqüência(obrigatório).
- A escrita deve ser iniciada setando o bit WR no registro EECON2.
- Devo resetar o bit WREN no registro EECON1 (isto ira proteger o processo de escrita).
- Agora aguardamos o bit WR ir para 0 , e após continuamos nossas rotinas ou usamos a
interrupção de escrita (bit EEIE no registro INTCON, associado ao bit EEIF do
EECON1), para controle do final de escrita.
- Caso algum erro de escrita ocorra no processo o bit WRERR do registro EECON1 será
setado.
Nota : o registro EECON1 e descrito em Registros de controle da CPU em páginas
anteriores.
escrita:
bcf STATUS,RP0 ; seleciono banco0
movlw 0x1 ; w=1h
movwf EEADR ; EEADR=w=1h
movlw 0x1C ; w=1Ch
movwf EEDATA ; EEDATA=w=1Ch
bsf STATUS,RP0 ; seleciono banco1 para EECON1
bcf INTCON,GIE ; desabilito as int.
bsf EECON1,WREN ; hab. escrita na EEPROM
movlw 55H ; w=55h
movwf EECON2 ; EECON2=55h
movlw 0AAH ; w0=AAh
movwf EECON2 ; EECON2=AAh
bsf EECON1,WR ; inicia processo de escrita
bcf EECON1,WREN ; desab. esc. EEPROM, não interfere na
; escrita(agora)
controle: ; escolho uma rotina de controle de fim de
; escrita , vamos implementar uma bem simples
; (como exemplo)
Nota : este exemplo não tem o controle de erros , o ideal e fazer uma rotina usando a
interrupção de fim de escrita e de erros.
2) Lendo na EEPROM.
Podemos ler os dados a qualquer momento, bastando seguir os passos abaixo.
Vamos a um trecho de programa onde iremos ler o dado contido no endereço 01h, o qual
escrevemos no trecho anterior (escrita), e colocar a informação lida (1C, no caso) no
endereço 10h na RAM de uso geral.
leitura:
bcf STATUS,RP0 ; seleciono banco0, onde esta EEADR
movlw 0x1C ; w=1Ch
movwf EEADR ; EEADR= w
bsf STATUS,RPO ; sel.banco1 onde esta EECON1
bsf EECON1,RD ; hab. leitura
bcf STATUS,RP0 ; volto ao banco0 onde esta EEDATA
movf EEDATA,0 ; w= EEDATA que é o dado lido
movwf 0x10 ; disponibilizo o dado no end.10h da
; RAM de uso geral, para uso qualquer
return
BIBLIOGRAFIA
Microcontroladores – PIC , Engenheiro Vidal Pereira da Silva Jr. , edição independ. 1997.
Sites :
www.microchip.com
www.mosaico-eng.com.br
www.vidal.com.br
www.ic-prog.com ( site com vários modelos de programadores e software gratuito).