MICROCONTROLADORES - PIC
16F84/16F84A/16F628/16F628A
Apresentação:
Eng. Antonio Carlos Lemos Júnior
acjunior@facthus.edu.br
Qual a diferença entre
Microcontrolador e Microprocessador?
Microcontrolador:
É um componente eletrônico, dotado de
uma inteligência programável internamente, utilizado no
controle de processos lógicos. Possui internamente recursos
como memória de programa (ROM/EEPROM), memória de
dados
(RAM),
comunicação
serial
(USART)
e
temporizadores (TIMER´S). Tudo isto em uma única
pastilha.
Microprocessador:
É um componente eletrônico, dotado de
uma inteligência não programável internamente. Depende
de hardware externo tais como: memória RAM, ROM,
Diagrama de Blocos do
Microcontrolador e Microprocessador
Para que servem os
Microcontroladores?
São utilizados em controle de processos controlando
periféricos tais como: led´s, botões, display de sete
segmentos, display de cristal liquido (LCD),
resistências, relês, sensores diversos (pressão,
temperatura, etc.)
Arquitetura HARVARD e Filosofia RISC
●
Os microcontroladores PIC apresentam arquitetura interna
tipo HARVARD enquanto que grande parte dos outros
microcontroladores apresentam arquitetura do tipo
VON-NEUMANN.
●
Na arquitetura tipo VON-NEUMANN existe apenas um
barramento(BUS – 8 Bits) tanto para dados quanto para
instruções.
●
Na arquitetura HARVARD existem dois barramentos
internos. Um para dados (BUS – 8 Bits) e outro para
instruções (BUS – 12, 14 ou 16 Bits)
Ciclos de Máquina
● O clock interno de um microcontrolador é divido por quatro.
Portanto um clock externo de 4 Mhz será de 1 Mhz internamente e por isso cada ciclo de máquina dura 1 μs.
● Portanto teremos quatro fases Q1, Q2, Q3 e Q4. No primeiro ciclo
ocorre automaticamente o incremento do contador de programa. No quarto ciclo ocorre a busca na memória da próxima instrução sendo armazenada no registrador de instruções.
Introdução ás Memórias
● A memória de programa dos PICs 16F84/F84A/F628/F628A são do tipo
Flash. Este tipo de memória permite que o microcontrolador seja regravado.
Vetor de RESET
● Primeiro endereço de memória que será executado quando o PIC
começar a rodar (Após alimentação ou RESET). O endereço é na forma hexadecimal 0x00.
Vetor de INTERRUPÇÃO
Introdução ás Memórias
Pilha (Stack)
● Local totalmente separado da memória de programação, em que serão
armazenados os endereços de retorno quando utilizarmos instruções de chamadas de rotinas. O tamanho da pilha varia de acordo com o modelo de PIC e isto irá determinar a quantidade de rotinas que poderão ser chamadas ao mesmo tempo.
Introdução ás Memórias
Memória de Dados
● Memória RAM utilizada para guardar todas as variáveis e registradores
utilizados nos programas.
● Armazena dados de 8 bits e é volátil, ou seja, quando o PIC é desligado
os dados contidos nesta memória serão perdidos.
● São agrupadas em bancos de memórias: BANK0, BANK1 ...
● Ainda podemos dividí-las em dois grupos: Registradores especiais e
Introdução ás Memórias
Registradores Especiais
● Os registradores especiais (SFR´s) são utilizados pelo processador para
execução do programa e processamento na Unidade Lógica Aritmética (ULA).
● Ocupam espaço na RAM e podem ser acessados como se fossem
variáveis.
● Podem ser lidos ou escritos tanto pelo usuário quanto pelo
HARDWARE.
Introdução ás Memórias
EEPROM
● Encontrada em alguns modelos de PIC está memória ao contrário da
memória RAM não perde a informação mesmo que o PIC seja desligado.
● Este tipo de memória é ideal para armazenar senhas ou qualquer outro
tipo de dado que deva ser utilizado no momento em que o PIC seja ligado.
● Nos modelos de PIC que não possuam memória EEPROM interna
Introdução ás Interrupções
O que são e como funcionam ?
● São ações tratadas imediatamente pelo hardware. Desta maneira
tornando-as muito rápidtornando-as.
● Servem para interromper imediatamente o programa e atendê-lo em outras
tarefas que sejam de importâncias imediata.
● Após o tratamento da interrupção o programa voltará ao ponto onde estava
quando a interrupção ocorreu.
Interrupções existentes no PIC
● As interrupções do PIC são: estouro de tempo, externa, mudança de estado,
Introdução ás Interrupções
Interrupção por estouro de tempo
● Normalmente utilizada para contagem de tempo. Toda vez que o contador
passar da contagem 255 (8 bits TIMER0) ocorrerá esta interrupção e o contador será zerado e iniciado nova contagem.
Interrupção externa
● Esta interrupção é gerada por um sinal externo ligado ao pino RB0. Pode
ser utilizada para realizar sincronismo entre periféricos, comunicação entre micros, reconhecimento de botão ou outro sinal sistema.
Introdução ás Interrupções
Interrupção por fim de escrita na EEPROM
● Serve para informar quando a escrita na memória EEPROM já terminou.
Isto deve-se ao fato de que a memória EEPROM é lenta para ser escrita desta maneira utilizamos esta interrupção para não termos que ficar aguardando a escrita da EEPROM.
Interrupção por USART
● Utilizado para informar quando os dados estão prontos para enviar e
quando os dados chegaram ao PIC. Também conhecida como comunicação serial.
O PIC 16F84/F84A
● Microcontrolador de 18 pinos
● 13 portas configuráveis como entrada ou saída
● 4 interrupções (TMR0, Externa, Mudança de estado e EEPROM) ● 1 Temporizador (8 Bits)
O PIC 16F628/F628A
● Microcontrolador de 18 pinos
● 16 portas configuráveis como entrada ou saída
● 10 Interrupções (TMR0, TMR1, TMR2, Externa, Mudança de estado,
EEPROM, USART – Transmissão e Recepção, Comparador, e Captura)
● 3 Temporizador (TMR0 de 8 Bits, TMR1 de 16 Bits, TMR2 de 8 Bits) ● 2 comparadores analógicos
● Memória tipo FLASH ● Memória tipo EEPROM
Nomenclaturas Utilizadas
● 2 Conjuntos de portas:
● PORTA: RA0, RA1, RA2, RA3, RA4 p/ 16F84/84A mais RA5, RA6 e RA7 p/
16F628/628A.
● PORTB: RB0, RB1, RB2, RB3, RB4, RB5, RB6 e RB7 ● O pino RA4 pode ser utilizado para incrementar o TMR0
● O pino RB0 pode ser utilizado para gerar uma interrupção externa
● Os pinos RB4, RB5, RB6 e RB7 são utilizados para gerar interrupções de mudança de
estado.
● Os pinos VDD (+5V) e VSS (GND) são os pinos de alimentação. ● O oscilador externo deve ser ligado em OSC1 e OSC2
Conhecendo os Registradores
Registrador STATUS
● Este registrador serve para mostrar o estado da ULA.
IRP: Seletor de banco de memória para endereçamento indireto: 0 = Banco 0 e 1 (00 h – FF h)
1 = Banco 2 e 3 (100 h – 1FF h)
Nos PIC´s 16F84/F84A é mantido sempre em zero.
RP1 e RP0: Seletor de banco de memória usado para endereçamento direto: 00 = Banco 0 (00 h – 7F h)
01 = Banco 1 (80 h – FF h) 10 = Banco 2 (100 h – 17F h) 11 = Banco 3 (180 h – 1FF h)
Conhecendo os Registradores
Registrador STATUS
● Este registrador serve para mostrar o estado da ULA.
/TO: Indicação de Time-Out
0 = Indica que ocorreu um estouro de Watch Dog (WDT)
1 = Indica que ocorreu um power-up ou foram executadas as intruções CLRWDT ou SLEEP
/PD: Indicação de Power-Down
0 = Indica que a instrução SLEEP foi executada.
1 = Indica que ocorreu um power-up ou foi executada a instrução CLRWDT
Conhecendo os Registradores
Registrador STATUS
● Este registrador serve para mostrar o estado da ULA.
DC: Digit Carry/Borrow
0 = A última operação da ULA não ocasionou um estou de digito.
1 = A última operação da ULA ocasionou um estouro (carry) entre o bit 3 e 4, isto é o resultado ultrapassou os 4 bits menos significativos.
Utilizando quando se trabalha com números de 4 bits.
C: Carry/Borrow
0 = A última operação da ULA não ocasionou um estouro (carry).
1 = A última operação da ULA ocasionou um estouro (carry) no bit mais significativo, isto é, o resultado ultrapassou os 8 bits disponíveis.
Conhecendo os Registradores
Registrador OPTION – Acessado como OPTION_REG
● Este registrador serve para configuração opções de funcionamento do microcontrolador
/RBPU: Habilitação dos pull-ups internos do PORTB
0 = Pull-ups habilitados para todos os pinos do PORTB configurados para entrada.
1 = Pull-ups desabilitados.
INTEDG: Configuração da borda que gerará a interrupção externa no RB0 0 = A interrupção ocorrerá na borda de descida.
1 = A interrupção ocorrerá na borda de subida.
T0CS: Configuração do incremento para o TMR0
Conhecendo os Registradores
Registrador OPTION – Acessado como OPTION_REG
● Este registrador serve para configuração opções de funcionamento do microcontrolador
T0SE: Configuração da borda que incrementará o TMR0 no pino RA4/T0CKI, quando T0CS = 1
0 = O incremento ocorrerá na borda de subida. 1 = O incremento ocorrerá na borda de descida.
PSA: Configuração de aplicação do prescaler: 0 = O prescaler será aplicado ao TMR0.
Conhecendo os Registradores
Registrador OPTION – Acessado como OPTION_REG
● Este registrador serve para configuração opções de funcionamento do microcontrolador
PS2, PS1 e PS0
Configuração de valor de prescaler:
Bits 2, 1, 0 TMR0 WDT 000 1:2 1:1 001 1:4 1:2 010 1:8 1:4 011 1:16 1:8 100 1:32 1:16 101 1:64 1:32
Conhecendo os Registradores
Registrador INTCON
● Este registrador serve para configurar e identificar as interrupções.
GIE: Habilitação geral das interrupções (Chave Geral) 0 = Nenhuma interrupção será tratada.
1 = As interrupções habilitadas serão tratadas individualmente.
EEIE: Habilitação da interrupção de final de escrita na EEPROM 0 = A interrupção não será tratada.
1 = A interrupção será tratada.
T0IE: Habilitação da interrupção de estouro do TMR0 0 = A interrupção não será tratada.
1 = A interrupção será tratada.
Conhecendo os Registradores
Registrador INTCON
● Este registrador serve para configurar e identificar as interrupções.
RBIE: Habilitação da interrupção por mudança de estado nos pinos RB4 a RB7 0 = A interrupção não será tratada.
1 = A interrupção será tratada.
T0IF: Identificação da interrupção de estouro do TMR0 0 = Esta interrupção não ocorreu.
1 = Esta interrupção ocorreu.
INTF: Identificação da interrupção externa no pino RB0 0 = Esta interrupção não ocorreu.
Conhecendo os Registradores
Registrador TRISA e TRISB
● Estes registradores servem para configurar o PORTA e o PORTB como entrada ou saída
● Quando os bits estiverem setados com o valor 1 o pino da porta comportará
como uma entrada (1 – INPUT) e quando estiver setado o valor 0 o pino da porta comportará como saída (0 - OUTPUT)
PIC16F84/F84A PIC16F628/F628A
Conhecendo os Registradores
Registrador PORTA e PORTB
● Estes registradores servem para acessar as portas A e B
● Os pic´s 16F84/F84A possuem a porta A e B. Na porta A somente 5 pinos estão
disponíveis. Na porta B estão disponíveis os 8 pinos.
● Os pic´s 16F628/F628A possuem a porta A e B. Na porta A estão disponíveis os
8 pinos assim como na porta B estão disponíveis os 8 pinos.
PIC16F84/F84A PIC16F628/F628A
Conhecendo os Registradores
Registrador TMR0, TMR1 e TMR2
● Estes registradores servem para fazer contagem
● Os pic´s 16F84/84A possuem somente 1 contador. Este contador é de 8 bits, ou
seja, pode contar até 255. Este contador pode ser incrementado automaticamente ou a partir da mudança no pino RA4.
● Os pic´s 16F628/F628A possuem três contadores: TMR0, TMR1, TMR2. Os
contadores são de: 8, 16 e 8 bits respectivamente. O contador TMR1 pode contar até 65535.
PIC16F84/F84A PIC16F628/F628A
Conhecendo os Registradores
Registrador WDT – Watchdog Timer
● Este registrador serve para ressetar o PIC caso este trave.
● O pic possui um RC interno somente para a operação do WDT. ● Seu tempo de incremento é automático e constante.
● O seu tempo padrão de estouro é de 18 ms
● O programador só pode zerá-lo utilizando o comando CLRWDT. ● Caso o WDT não for zerado e este estourar o PIC será resetado.
Conhecendo os Registradores
PRESCALER
● É um divisor configurável que aplica-se tanto no WDT ou no TMR0.
● É configurado através do registrador OPTION através dos bits PS2, PS1 e PS0 ● O bit PSA do registrador OPTION é utilizado para indicar em quem será
aplicado o divisor: WDT ou TMR0
● Um exemplo prático: Caso utilizemos um clock externo de 4 Mhz internamente
o clock é de 1 Mhz e terá instruções sendo rodadas a cada 1 μs. Desta forma se aplicarmos um divisor 1:4 o TMR0 será incrementado a cada 4 ciclos de máquina desta forma o seu estouro deixa de ocorrer em 256 μs e passa a ocorrer a cada 1024 μs.
● A mesma análise pode ser aplicada ao WDT. Caso seja aplicada um divisor de
1:4 ele deixa de estourar em 18 ms e passa a estourar em 72 ms
Conhecendo os Registradores
EEPROM - EEADR
● Registrador onde será especificado o endereço fazer a leitura ou escrita na EEPROM.
EEPROM - EEDATA
● Este registrador possui duas funções: Na operação de escrita ele guarda o dado a ser
gravado na EEPROM. Na operação de leitura ele guarda o dado lido da EEPROM.
● Para os PICs 16F628/F628A estes registradores são acessados pelos
Conhecendo os Registradores
EECONS – EECON1 e EECON2
● São os registradores utilizados para configurar a EEPROM
EECON1
● Este registrador é responsável pela leitura e escrita na EEPROM
● Para os PICs 16F628/F628A este registrador é acessado pelo endereço:
EEADR = 9B h e o EEDATA = 9C h. O bit EEIF é acessado no registrador PIE1 para verificar o fim de escrita na EEPROM.
● EEIF: Identificação de final da escrita na EEPROM
0 = Esta interrupção não ocorreu 1 = Esta interrupção ocorreu
Conhecendo os Registradores
● WRERR: Identificação de erro durante a escrita na EEPROM
0 = Não ocorreu erro, a escrita ocorreu sem problemas 1 = Um erro ocorreu por uma escrita não terminada.
● WREM: Habilitação de escrita na EEPROM (Bit de segurança)
0 = Não disponibilizar escrita na EEPROM 1 = Disponibilizar escrita na EEPROM
● WR: Ciclo de escrita na EEPROM
0 = Este bit só pode ser zerado pelo hardware , quando o ciclo de escrita termina.
1 = Inicia o ciclo de escrita.
Conhecendo o Set de Instruções
Work: Registrador temporário para operações da ULA. Conhecido no Assembler do PIC como W.
File: Referência a um registrador. Será adotado a letra F para sua representação.
Literal: Um número qualquer que pode ser escrito na forma decimal, binário ou hexadecimal. Utiliza-se a letra L para representação de instruções e a letra k para seus argumentos.
Destino: Local onde deve ser armazenado o resultado da operação. São possíveis dois locais para serem guardados os resultados: O próprio registrador passado como argumento ou no registrado W.
Bit: Refere-se a um bit específico de um Byte. Utiliza-se a letra B para sua representação nos nomes de instruções e a letra b para seus argumentos.
Conhecendo o Set de Instruções
Set: Refere-se ao ato de setar um bit, ou seja, torná-lo igual a 1 (um) .
Clear: Refere-se ao ato de ressetar um bit, ou seja, torná-lo igual a 0 (zero).
Zero: Algumas instruções podem gerar desvio caso o resultado da operação seja igual a zero.
ADD: Soma
AND: Lógica “E”
CLR: Limpar, zerar(Clear)
COM: Complemento
DEC: Decremento de uma unidade.
INC: Incremento de uma unidade.
IOR: Lógica “OU”.
MOV: Mover, transferir para algum lugar.
RL: Rotacionar 1 bit para a esquerda.
Conhecendo o Set de Instruções
SUB: Subtração.
SWAP: Inversão entre as partes alta e baixa de um registrador.
XOR: Lógica “Ou exclusivo”.
Construção dos nomes das Instruções:
Os nomes das instruções são feitas fazendo a junção dos termos vistos anteriormente. Por exemplo: Realizar a função de decrementar um registrador F.
Decrementar (DEC) um registrador(F) = DECF
A partir do nome de uma instrução saber o que será feito:
Considerações do Hardware
Alimentação:
O pic deve ser alimentado com uma fonte bem estabilizada, ou
seja, que não tenha tantos ruídos e nem ripples. O GND deve ser
ligado ao pino 5 enquanto que o o VCC deve ser ligado ao pino
14. A tensão nominal do PIC é de 5 VCC. Recomenda-se a
ligação de um capacitor cerâmico de desacoplamento entre os
estes pinos no valor de 100 pF a 100 nF.
Osciladores externos:
Basicamente existem quatro tipos de osciladores: RC,
RESSOADOR, CRISTAL e Híbrido ou Circuitos de Oscilação.
Considerações do Hardware
RC:
Este tipo de oscilador é o mais simples e portanto o menos
preciso, variando muito com a tolerância dos componentes e a
temperatura.
Neste caso somente será
utilizado o pic OSC1. Se
verificarmos o pino OSC2
terá freqüência quatro vezes
menor que OSC1.
Considerações do Hardware
RESSOADOR:
O ressoador cerâmico é outra opção. É bem mais estável que o
RC porém não é tão barato quanto o anterior. Existe dois tipos de
ressoadores, com 3 e 2 pinos, que devem ser montados conforme
o esquema:
Considerações do Hardware
CRISTAIS:
Os cristais são os osciladores mais precisos porém os mais
caros. Deve ser utilizado sempre que a precisão do sistema for
requerida.
Considerações do Hardware
HÍBRIDO OU CIRCUITOS DE OSCILAÇÃO:
Podem ser utilizados cristais híbridos ou circuitos próprios para oscilação os quais devem ser ligados diretamente ao pino OSC1, como no esquema mostrado para o RC.
POWER-ON RESET (POR) BÁSICO:
Além da alimentação e do oscilador, o PIC precisa de um POR. O sistema básico para isto é a ligação do VCC diretamente ao pino 4 (/MCLR).
Programando o PIC
●
Antes de começar a programar o PIC devemos ter em mente a
organização do programa. Isto facilitará futuras revisões ou
alterações no mesmo.
●
A utilização de comentário é outro ponto forte na ajuda de
possíveis reestruturações. Deve ser feita ao mesmo tempo em que
for sendo feita a programação
●
Os comentários são feitos utilizando um ; antes das frases que
serão comentadas. Caso necessite de dar espaços entre código e
variáveis utilize tabulação (TAB) .
Ex.:
; Isto é um comentário
Programando o PIC
●
As constantes e definições são declararadas da seguinte
maneira:
nome_da_variável
EQU
endereço_de_memória
ou
nome_da_constate
EQU
valor_da_constante
Para informarmos um número para o assembler do PIC
usamos as seguintes nomenclaturas:
Decimal:
D'número' ou
.número
Programando o PIC
Alguns exemplos de declaração:
STATUS
EQU
H'0003'
FSR
EQU
H'0004'
PORTA
EQU
H'0005'
PORTB
EQU
H'0006'
Além do
EQU
existe a diretriz
#DEFINE
que é muito mais
poderosa pois ela é utilizada para substituir uma expressão
inteira.
EX.:
Estruturação do Programa
; Programa ...: ACILED
; Programador .: Eng. Antonio Carlos Lemos Júnior ; Versão ...: 1.0
; Objetivo ...: O programa em questão deverá acionar um LED toda vez que o pino RB1 estiver em alto. ; Arquivos e definições
#INCLUDE <P16F84.INC> ; Página de memória
; Definição de comandos de usuário para alterar página de memória
#DEFINE BANK0 BCF STATUS,RP0 ; Seta banco zero de memória
#DEFINE BANK1 BSF STATUS,RP0 ; Seta banco um de memória ; Definição de variáveis
CBLOCK 0X0C ; Endereço inicial da memória de usuário
W_TEMP ; Registradores temporários para usar junto às interrupções STATUS_TEMP
FLAG
; Novas variáveis
ENDC
Estruturação do Programa
; Definição das entradas
#DEFINE ACENDE_APAGA_LED PORTB,0 ; 0 => O LED não será acesso ; 1=> O LED será acesso ; Definição das saídas
#DEFINE LED PORTB,1
; 0 => O LED ficará apagado ; 1 => O LED ficará acesso ; Vetor de RESET
ORG 0X00 ; Endereço inicial de processamento
GOTO CONFIGURACAO
; Inicio das interrupções – O primeiro procedimento é salvar o acumulador W e o registrador STATUS.
ORG 0X04
MOVWF W_TEMP
SWAPF STATUS, W
MOVWF STATUS_TEMP
; Comando de verificação de qual interrupção foi acionada
; Saída das interrupções – Os valores de W e STATUS devem ser recuperados.
Estruturação do Programa
SWAPF W_TEMP,W
RETIFIE
; Início das rotinas e sub-rotinas
SUB-ROTINA1
; CORPO DA ROTINA
RETURN
; Início da configuração
CONFIGURACAO
BANK1 ; Altera para banco 1 de memória
MOVLW B'00000000'
MOVWF TRISA ; Define as entradas e saídas da porta A
MOVLW B'00000000'
MOVWF TRISB ; Define as entradas e saídas da porta B
MOVLW '10000100'
MOVWF OPTION_REG ; Define as opções de operação
MOVLW '00000000'
MOVWF INTCON ; Define as opções de interrupção
Estruturação do Programa
; Rotina Principal
INICIO
; Corpo da rotina principal
GOTO INICIO ; Fim do Programa
END
Diretriz ORG
Utilizada para indicar a posição da memória de início do programa e de início do tratamento de interrupção.
Diretriz END
Utilizada para indicar o final do programa Diretriz CBLOCK e ENDC
Utilizada para reservar espaço para as variáveis de forma seqüencial no mapa de memória. O endereço inicial para os PICs 16F84/84A/628/628A são 0x0C
Trabalhando com Memória
Conhecendo os Bancos de Memória (BANK0 e BANK1):
Para trabalharmos com os bancos de memória devemos setar ou ressetar os bits RP0 e RP1 do registrador STATUS. Lembrando que para o PIC 16F84 só é necessário alterar o bit RP0. Ex.:
#DEFINE BANK0 BCF STATUS, RP0
#DEFINE BANK1 BSF STATUS, RP0
Lidando com Dados:
Basicamente os comandos utilizados no PIC para manipulação de dados são os seguintes:
MOVLW k Move um literal para o registrador W (Acumulador)
MOVWF f Move o valor de work (W) para um registrador (F)
Trabalhando com Memória
Existem também os comandos CLRF CLRW que são usados da
seguinte maneira:
CLRF
f Limpa o registrador
CLRW
Limpa o acumulador, mais afeta o registrador STATUS
Pode-se limpar o acumulador sem afetar o registrador STATUS a
maneira para se fazer isso é:
Vetor de Reset
Toda vez que o PIC é iniciado ou resetado este é o endereço inicial de programa. Este endereço é 0x00. Este endereço pode mudar em dispositivos mais antigos. A diretriz que identifica o vetor de reset é a seguinte:
ORG 0x00 GOTO INICIO INICIO BANK1 MOVLW B'00000000' MOVWF TRISB MOVLW B'00000001' MOVWF TRISA BANK0
Inicializando Variáveis
É muito importante que as variáveis sejam inicializadas, mesmo que o seu valor seja igualado a zero(0).
;---;- Inicialização das variáveis
;---CLRF PORTA
CLRF PORTB
MOVLW .10
Trabalhando com Rotinas
No PIC existem dois tipos de rotinas: rotinas de desvios e rotinas de chamadas. As rotinas de desvio são feitas utilizando o comando GOTO juntamente com um label que identificará para onde o programa deverá ser desviado. As rotinas de chamadas são acessadas através do comando CALL. Ao charmar este comando o endereço do programa PC+1 é guardado na pilha STACK, para que o sistema possa retornar a ele mais tarde utilizando o comando RETURN.
Trabalhando com Rotinas
Rotinas de Desvio
As rotinas de desvio são utilizadas para realizar desvios dentro do programa. A sintaxe do comando segui abaixo:
GOTO nome ; onde nome é o identificador do local onde se deseja pular
O identificador deve estar na primeira coluna do programa como segue abaixo: INICIO MOVLW .20 MOVWF TRISB MODIFICA MOVLW .10 MOVWF TRISA GOTO INICIO
Trabalhando com Rotinas
Rotinas de Desvio
Além disto existe a possibilidade de pularmos algumas linha utilizando o comando GOTO.
A sintaxe do comando segue abaixo:
GOTO $+3 ;Pula três linha para baixo GOTO $-2 ;Pula duas linhas para cima
OBS.: Não utilizar o comando para pulos muito grandes. Rotinas de Chamada
As rotinas de chamadas são simplesmente funções que devem ser executadas várias vezes dentro do programa. Desta maneira quando criamos
Trabalhando com Rotinas
Rotinas de chamada
A sintaxe do comando segue abaixo:
CALL funcao ;onde nome é a identificação da rotina
Quando chamamos uma função o endereço de programa posterior a linha onde a função foi chamada é guardada na pilha STACK. Devemos ficar atentos a quantidade de endereços, no STACK é de apenas 8 para os PIC's 16F84/84A, 16F628/628A.
Portanto esta função deve ser utilizada com o devido cuidado. As sintaxes de retorno são:
RETURN ;finaliza a rotina voltando ao último endereço da pilha.
RETLW k ;finaliza a rotina voltando ao último endereço da pilha com o ;valor k (literal) em W.
Tomando Decisões e Fazendo Desvios
A filosofia RISC tem a vantagem de ter poucas instruções a serem guardadas no entanto esta vantagem torna-se uma desvantagem principalmente quando é necessária algum comando que não esteja no set de instruções do ASSEMBLER do PIC. Desta maneira torna-se necessária a elaboração de alguns comandos utilizando os comandos básicos.
Testando BITS e FLAGS (BTFSC e BTFSS)
Os comandos utilizados para testar bits de portas ou de flags são: BTFSS e
BTFSC. A sintaxe do comando segue abaixo:
BTFSC f,b ;em que f é o registrador e b o bit a ser testado Linha1 ;passa por esta linha se o bit testado for 1
Tomando Decisões e Fazendo Desvios
Além das portas, registrador, flags pode-se utilizar a diretiva DEFINE para substituir diretamente um bit, como segue abaixo:
#DEFINE BOTAO PORTA,0 ;Define o botão no pino RA0
;0-> Liberado ;1->Pressionado
BTFSS BOTAO ;O botão está pressionado
GOTO BT_LIB ;Não, vai tratar botão liberado
GOTO BT_PRES ;Sim, vai trata botão pressionado Mudando BITS e FLAGS (BSF e BCF)
As instruções BSF e BCF são utilizadas para alterar o valor de um bit. A sintaxe de comando segue abaixo:
BSF f,b ;em que f é o registrador e b é o bit que será setado
Trabalhando com as Portas
É através das portas que iremos ser informados ou iremos informar as condições de trabalho do microcontrolador. Desta maneira a leitura e a escrita nas portas torna-se fundamental.
Lendo uma Porta
Caso tenhamos ligado um barramento de dados paralelo a porta B do microcontrolador e queiramos fazer a leitura completa dos dados que chegam a esta porta devemos proceder da seguinte maneira:
MOVF PORTB,W ;Move o conteúdo do portb para o acumulador
MOVWF DADOS ;Escreve o valor do acumulador para o registrador
Trabalhando com as Portas
Escrevendo em uma Porta
Da mesma forma que a leitura a escrita é um processo fundamental no trabalho com o PIC. É através da escrita que podemos comunicar com o mundo exterior. A escrita é feita utilizando a seguinte sintaxe:
BANK1 ;Muda para banco 1
BSF TRISB,0 ;Transforma RB0 em entrada
BANK0 ;Retorna para banco 0
;Outros comandos
BSF PORTB,0 ;Escreve 1 no Latch do RB0 (Que ainda é entrada)
BANK1 ;Muda para banco 1
BCF TRISB,0 ;Transforma RB0 em saída. Neste momento o pino ;será inicializado em 1 devido ao Latch
Trabalhando com as Portas
Escrevendo em uma Porta
Devido a esta estrutura interna não é recomendado a escrita e posteriormente a leitura em instruções seguintes. Desta maneira utiliza-se a instrução NOP. A instrução NOP desperdiça um ciclo de máquina sem fazer nada. A sintaxe utilizando o NOP fica da seguinte maneira:
MOVLW .10 ;Escreve 10 em W
MOVWF PORTB ;Transfere o valor de W (10) para o PORTB
NOP ;Perde um ciclo de máquina sem fazer nada
MOVF PORTB,W ;Lê o valor do PORTB e coloca em W
PRIMEIRO PROGRAMA
BOTÃO E LED
O hardware proposta acima deve funcionar da seguinte maneira: O led será usado para representar o estado do botão, isto é, aceso para botão pressionado e apagado para o botão liberado.
PRIMEIRO PROGRAMA
PRIMEIRO PROGRAMA
BOTÃO E LED
;Programa...: Aciona_LED
;Objetivo...: O software em questão será utilizado para demonstrar se um botão está ou não pressionado.
#INCLUDE <P16F84.INC>
#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK1 BSF STATUS,RP0
CBLOCK 0X0C W_TEMP
STATUS_TEMP
ENDC
#DEFINE BOTAO PORTA,2
#DEFINE LED PORTB,0
ORG 0X00 GOTO INICIO ORG 0X04 RETFIE INICIO BANK1 MOVLW B'00000100' MOVWF TRISA MOVLW B'00000000' MOVWF TRISB
PRIMEIRO PROGRAMA
BOTÃO E LED
MOVLW B'10000000' MOVWF OPTION_REG MOVLW B'00000000' MOVWF INTCON BANK0 CLRF PORTA CLRF PORTB MAIN BTFSS BOTAO GOTO BOTAO_LIB GOTO BOTAO_PRES BOTAO_LIB BCF LED GOTO MAIN BOTAO_PRES BSF LED GOTO MAIN ENDFAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
Todos os programas implementados microcontroladores necessitam de algum tipo de conta para que sua lógica funcione adequadamente. O PIC 16F84/84A/628/628A não tem instruções com pontos fortes em matemática. No entanto veremos que ele possui os recursos necessários para que possamos implementar nossas próprias funções para cálculo bem mais avançados.
SOMANDO (INCF, INCFSZ, ADDWF e ADDLW)
O PIC possui dois grupos de instruções para operação de adição sendo um usado para adições unitárias e o outro para adições diversas. Dentro desses grupos, possuímos as instruções que seguem abaixo:
INCF f,d ; em que f é o registrador e d o destino onde será guardado o resultado ; da conta (f + 1 -> d).
INCFZ f,d ; em que f é o registrador e d o destino onde será guardado o resultado ; da conta (f + 1 -> d).
ADDWF f,d ; em que f é o registrador e d o destino onde será guardado o resultado ; da conta (f + k -> d).
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
Exemplo da utilização das instruções:
INCF
CLRF CONTA ; zera o contador LOOP
CALL BIP ; chama a rotina BIP que emitirá um SOM
INCF CONTA,F ; incrementa o contador (CONTA = CONTA + 1)
BTFSS CONTA,3 ; testa o BIT número 3 do contador. Quando este BIT for ; igual a 1, significa que contador = 8.
GOTO LOOP ; contador ainda não é 8, retorna para LOOP. END ; contador igual 8, acabou o exemplo.
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
Exemplo da utilização das instruções:
INCFSZ
MOVLW .246 ; move 246 para o acumulador
MOVWF CONTA ; inicia o contador com 246 (256 - 10). LOOP
CALL BIP ; chama a rotina BIP que emitirá um som.
INCFSZ CONTA,F ; incrementa o contador (CONTA = CONTA + 1). ; resultado = 0 (estourou?).
GOTO LOOP ; não, retorna para LOOP pois não passou 10 vezes. END ; sim, acabou o exemplo pois já passou 10 vezes.
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
Exemplo da utilização das instruções:
ADD
MOVLW .10
MOVWF NUM_1 ; inicia NUM_1 com valor 10
MOLW .20
MOVWF NUM_2 ; inicia NUM_1 com valor 20
CLRF RESULTADO ; inicia RESULTADO com zero SOMA1 ; resposta = NUM_1 + 5
MOVF NUM_1,W ; coloca o NUM_1 dentro do acumulador(W)
ADDLW .5 ; soma 5 ao acumulador (W)
MOVWF RESULTADO ; coloca a resposta em resultado SOMA2 ; resposta = NUM_1 + NUM_2
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
As instruções anteriores afetam diretamente os flags relacionados a ULA. Os flags são: STATUS: C, DC e Z. Se desejarmos somar dois números quaisquer de 8 bits necessitaríamos de pelo menos 10 bits para guardarmos estes valores. Para sabermos que o resultado da soma necessita de pelo menos 10 bits utilizamos o bit de CARRY (STATUS, C) para verificarmos esta necessidade. O exemplo abaixo mostra a soma de três números guardando a resposta em dois bytes.
Suponha que NUM_1, NUM_2 e NUM_3 tenha valores quaisquer:
CLRF BYTE_BAIXO ;Inicia BYTE_BAIXO com zero
CLRF BYTE_ALTO ;Inicia BYTE_ALTO com zero
MOVF NUM_1,W ;Move NUM_1 para dentro do acumulador
ADDWF NUM_2,W ;Soma NUM_2 com o NUM_1 que está no acumulador
BTFSC STATUS,C ;Verifica se houve um estouro?
INCF BYTE_ALTO ;Se sim incrementa o BYTE_ALTO
MOVWF BYTE_BAIXO ;Move o acumulador para o BYTE_BAIXO
ADDWF NUM_3,W ;Soma NUM_3 ao acumulador
BTFSC STATUS,C ;Verifica se houve estouro?
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
SUBTRAINDO (DECF, DECFSZ, SUBWF e SUBLW)
As instruções de subtração do PIC seguem a mesma idéia das instruções de adição.
DECF f,d ; em que f é o registrador e d o destino onde será guardado o resultado da ; conta (f – 1 -> d).
DECFSZ f,d ; em que f é o registrador e d o destino onde será guardado o resultado ; da conta (f - 1 -> d).
SUBWF f,d ; em que f é o registrador e d o destino onde será guardado o resultado ; da conta (f - k -> d).
SUBLW k ; em que k é o número que será somado ao W o resultado é mantido ; em W (k - W -> W).
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
UTILIZANDO A INSTRUÇÃO DECFSZ
MOVLW .10 ; Inicia o contador com 10
MOVWF CONTA ; Move o valor 10 para a variável CONTA LOOP
CALL BIP ; Chama rotina de emissão de som
DECFSZ CONTA,F ; Decrementa a variável conta (CONTA = CONTA -1) ; Resultado é igual a zero (Acabou ?)
GOTO LOOP ; Não, continua até zerar END ; Sim, termina o programa
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
UTILIZANDO A SUBWF SUBLW
MOVLW .10
MOVWF NUM_1 ; Inicia NUM_1 com 10
MOVLW .20
MOVWF NUM_2 ; Inicia NUM_2 com 20
CLRF RESULTADO ; Inicia RESULTADO com zero SUB1
MOVF NUM_1,W ; Move o valor de NUM_1 para o acumulador
SUBLW .30 ; Subtrai de 30 o valor de W
MOVWF RESULTADO ; Guarda a resposta em RESULTADO SUB2
MOVF NUM_1,W ; Move o valor de NUM_1 para W
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
Diferentemente da adição a ordem da subtração afeta diretamente o resultado. Em somas o resultado pode ser zero ou positivo. Na subtração ele pode ser zero, positivo ou negativo. Por meio da análise do flag de carry podemos concluir qual o resultado correto da subtração:
Negativo: Sempre que o resultado da subtração for um número negativo, o carry será zero (0). Neste caso, o valor da resposta não será diretamente o número negativo, e sim sua diferença para 256.
Positivo: Sempre que o resultado for positivo o carry será 1
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
Supondo dois números NUM_1 e NUM_2
CLRF RESP ; Limpa registrador RESP
SUB1 ; Subtrai NUM_2 – NUM_1 = RESP
MOVF NUM_1,W ; Move NUM_1 para W
SUBWF NUM_2,W ; Subtrai NUM_2 - W
BTFSS STATUS,C ; Testa carry. Resultado negativo?
GOTO TRATA_NE ; Sim, pula para tratar número negativo ; Não, resultado positivo ou zero
MOVWF RESP ; Move diretamente para RESP
BCF NEG ; Limpa flag de número negativo
GOTO FIM ; Finaliza
TRATA_NEG ; Como resultado foi negativo, então RESP = 256 - W ; Como o número máximo para 8 bits é 255, então ; 256 -> 0
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
AS COMPARAÇÕES MAIOR QUE, MENOR QUE E IGUAL
As instruções SUB afetam diretamente o flag de carry, e desta forma podemos verificar se um número é positivo, negativo ou zero. Partindo deste principio podemos identificar também se um número é maior, menor ou igual a outro.
COMPARA1 MOVF NUM_1,W SUBWF NUM_2,W BTFSS STATUS,C GOTO RESP1 GOTO RESP2 END
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
MULTIPLICANDO
A instrução RLF, (Rotate Left File) é utilizada para fazer multiplicação utilizando potência de 2, ou seja somente podemos multiplicar o número por 2.
REGISTRADOR F BYTE INICIAL => 01011011
REGISTRADOR F BYTE FINAL => 10110111
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
MULTIPLICANDO
E se quisermos multiplicarmos fatores que sejam diferentes das potências de 2? Para isto devemos utilizar o método de somas sucessivas.
CLRF BYTE_BAIXO ; Limpa o registrador BYTE_BAIXO
CLRF BYTE_ALTO ; Limpa o registrador BYTE_ALTO MULT ; NUM_1 X NUM_2
MOVWF NUM_2,W ; Move o valor de NUM_2 para W
ADDWF BYTE_BAIXO,F ; Soma NUM_2 ao valor já existente
BTFSC STATUS,C ; Houve estouro?
INCF BYTE_ALTO,F ; Sim, incrementa o BYTE_ALTO ; Não
DECFSZ NUM_1,F ; Decrementa NUM_1. Acabou?
GOTO MULT ; Não, continua somando
; Sim, soma sucessiva terminada
FAZENDO OPERAÇÕES ARITMÉTICAS
BÁSICAS
DIVIDINDO
A instrução RRF, (Rotate Right File) é utilizada para fazer divisão utilizando potência de 2, ou seja somente podemos dividir o número por 2.
REGISTRADOR F BYTE INICIAL => 01011011
REGISTRADOR F BYTE FINAL => 10101101
Deslocamento de apenas um bit.
No caso da divisão, a parte inteira caberá em um único registrador de 8 bits, mas o resto da divisão poderá ser perdido por meio de carry.
SEGUNDO PROGRAMA
CONTADOR SIMPLIFICADO
O código que se segue é um contador simplificado onde a
contagem deve ser feita de um valor mínimo até um valor máximo.
Estes valores são duas constantes (MIN e MAX) as quais são
utilizadas para fazermos a checagem dos valores.
Será necessário a utilização das técnicas de comparação para
verificarmos se chegamos ao valor máximo. Além disso utilizaremos
um filtro para fazer a análise quando o botão foi pressionado. A
constante chama-se T_FILTRO e é ajustada para verificar a
quantidade de vezes em que o botão ficou pressionado.
Quando a contagem chegar ao valor máximo devemos fazer a
contagem regressiva até chegar ao valor mínimo.
O pino RA2 é responsável em fazer o incremento ou decremento
do contador. Além disto a contagem depende de um flag dentro do
sistema que diz se estamos subtraindo ou somando.
SEGUNDO PROGRAMA - CONTADOR
SEGUNDO PROGRAMA - CONTADOR
CRESCENTE-DECRESCENTE - PROGRAMA
;Programa...: Contador Crescente Decrescente
;Objetivo...: O software em questão será utilizado para fazer um contador que conte até um valor máximo e decremente este valor até um valor mínimo quando este chegar ao valor máximo. O funcionamento depende de RA2 e do flag de sentido.
#INCLUDE <P16F84.INC>
#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK1 BSF STATUS,RP0 CBLOCK W_TEMP STATUS_TEMP CONTATOR FLAGS FILTRO ENDC
#DEFINE SENTIDO FLAGS,0
#DEFINE BOTAO PORTA,2
MIN EQU .10
MAX EQU .30
T_FILTRO EQU .230 ORG 0X00 GOTO INICIO
SEGUNDO PROGRAMA - CONTADOR
CRESCENTE-DECRESCENTE - PROGRAMA
ORG 0X04 RETFIE INICIO BANK1 MOVLW B'00000100' MOVWF TRISA MOVLW B''00000000' MOVWF TRISB MOVLW B'10000000' MOVWF OPTION_REG MOVLW B'00000000' MOVWF INTCON BANK0 CLRF PORTA CLRF PORTB MOVLW MIN MOVWF CONTADOR MAINSEGUNDO PROGRAMA - CONTADOR
CRESCENTE-DECRESCENTE - PROGRAMA
DECFSZ FILTRO,F GOTO CHECA_BT TRATA_BT BTFSS SENTIDO GOTO SOMA SUBTRAI DECFCONTADOR,F MOVLW MIN SUBWF CONTADOR,W BTFSC STATUS,C GOTO ATUALIZA INCF CONTADOR,F BCF SENTIDO GOTO MAIN SOMA INCF CONTADOR,F MOVLW MAX SUBWF CONTADOR,W BTFSS STATUS,C GOTO ATUALIZA BSF SENTIDO GOTO MAINSEGUNDO PROGRAMA - CONTADOR
CRESCENTE-DECRESCENTE - PROGRAMA
BTFSC BOTAO GOTO $-1 GOTO MAIIN ENDTRABALHANDO DIRETAMENTE COM BYTES
AND (ANDWF e ANDLW)
A operação AND é uma operação lógica entre dois bytes. Cada bit da seqüência de um número é comparado a seqüência de bits do segundo. Esta operação ira resultar em um terceiro byte contendo a operação lógica AND entre os dois primeiros.
ANDWF e ANDLW
A operação ANDWF faz uma operação AND entre o acumulador (W) e o registrador informado.
ANDWF f,d ; f é o registrador e d é o destino onde será guardado o resultado da operação A operação ANDLW faz uma operação AND entre o literal (L) e o acumulador (W).
ANDLW K ; K é um número literal e o resultado é guardado no prório acumulador. OR (IORWF e IORLW)
A operação OR é uma operação lógica entre dois bytes. Cada bit da seqüência de um número é comparado a seqüência de bits do segundo. Esta operação ira resultar em um terceiro byte contendo a operação lógica OR entre os dois primeiros.
IORWF e IORLW
A operação IORWF faz uma operação OR entre o acumulador (W) e o registrador informado.
TRABALHANDO DIRETAMENTE COM BYTES
XOR (XORWF e XORLW)
A operação XOR é uma operação lógica entre dois bytes. Cada bit da seqüência de um número é comparado a seqüência de bits do segundo. Esta operação ira resultar em um terceiro byte contendo a operação lógica EXCLUSIVE OR entre os dois primeiros.
XORWF e XORLW
A operação XORWF faz uma operação OU EXCLUSIVO entre o acumulador (W) e o registrador informado.
XORWF f,d ; f é o registrador e d é o destino onde será guardado o resultado da operação A operação XORLW faz uma operação OU EXCLUSIVO entre o literal (L) e o acumulador (W).
XORLW K ; K é um número literal e o resultado é guardado no prório acumulador.
OBS.: XOR é muito utilizado na verificação de mudança de um BYTE. Verificando a o resultado da operação de subtração entre o registrador e ele mesmo através do registrador STATUS, Z.
COMPLEMENTO (COMF)
TRABALHANDO DIRETAMENTE COM BYTES
INVERSÃO (SWAPF)
A operação SWAPF serve para inverter o nibble superior com o nibble inferior de um byte.operação XOR é uma operação lógica entre dois bytes. Cada bit da seqüência de um número é comparado a seqüência de bits do segundo. Esta operação ira resultar em um terceiro byte contendo a operação lógica EXCLUSIVE OR entre os dois primeiros.
CONTANDO TEMPO E CRIANDO DELAYS
A contagem de tempo em um microcontrolador é muito preciso. Logicamente esta precisão irá depender da precisão do oscilador. Com esta precisão torna-se fácil mensurar o tempo que determinadas tarefas levam para serem executadas ao mesmo tempo em que se pode determinar o tempo em que um tarefa deve permanecer em execução.
O tempo no PIC pode ser contado basicamente de três formas:
● Contando os ciclos de máquina por meio de loops
● Contando os ciclos de máquina por intermédio do contador timer 0 (TMR0); ou ● Contando pulsos externos por meio da entrada T0CLK e do TMR0
As duas primeiras são mais utilizadas e dependem exclusivamente do sistema de oscilação. A terceira depende de estímulos externos e pode ser facilmente utilizada para medir tempo com base na rede de 60 Hz.
UTILIZANDO O TIMER PARA MARCAR TEMPO:
Para configurarmos o TMR0 primeiramente precisamos saber qual é a freqüência do oscilador. Para nosso exemplo vamos adotar a freqüência de 4 MHz. O ciclo de máquina do PIC é quatro vezes menor do que a freqüência do oscilador. Neste caso nossa freqüência interna é de 1 MHz e o tempo é 1/f ou seja 1 us . Para nosso exemplo vamos supor que queiramos um tempo de 1 ms. Para isso usaremos o TMR0 e o Prescaler na configuração de 1:4. A conta a ser feita segue abaixo:
CONTANDO TEMPO E CRIANDO DELAYS
Exemplo de contagem: DELAY CLRF TMR0 DL_1 MOVLW .250 SUBWF TMR0,W BTFSS STATUS,C GOTO DL_1 RETURNA rotina acima funciona porém a sua precisão ainda não é das melhores uma vez que a comparação é feita na forma de igualdade de estouro. Isto ocorre porque o TMR0 pode ser incrementado em qualquer uma destas linhas e a precisão acaba. UTILIZANDO REGISTROS TEMPORÁRIOS PARA CRIAR DELAYS:
Podemos criar estruturas para contagem de tempo utilizando registradores temporários. Desta maneira podemos liberar o TMR0 e o prescaler. A idéia básica é criar contadores dentro de outros contadores para contar corretamente a quantidade de ciclos de máquinas e conseqüentemente o tempo. OBS.: Instruções tais como: GOTO, CALL, BTFSS, BTFSC, DECFSZ e INCFSZ podem durar 2 cilcos de máquinas
Rotina para 1 ms: DELAY MOVLW .250 MOVWF TEMP1 DL_1 NOP DECFSZ TEMP1,F
TERCEIRO PROGRAMA – PISCA – PISCA
Neste exemplo será usado delays e inversão de estados utilizando a operação XOR. Será utilizado uma constante chamada DISPLAY para fazer a inversão. Os botões 1 e 2 (RA1 e RA2) serão utilizados para alterar o valor da variável CONTADOR, mudando com isso a freqüência do pisca pisca. As constantes MIN e MAX determinam o limite para o contador e conseqüentemente a freqüência.
TERCEIRO PROGRAMA – PISCA – PISCA
;Programa...: Pisca - Pisca;Objetivo...: O software destina-se a piscar 5 leds formando a letra H em um displasy de 7 segmentos formados por leds #INCLUDE <PIC16F84.INC>
#DEFINE BANK0 BCF STATUS,RP0 #DEFINE BANK1 BSF STATUS,RP0
CBLOCK 0X0C W_TEMP STATUS_TEMP CONTADOR FILTRO TEMPO1 TEMPO2 TEMPO3 ENC MIN EQU .10 MAX EQU .240 STEP EQU .5 MULTIPLOEQU .5 ; a ; *********
TERCEIRO PROGRAMA – PISCA – PISCA
DISPLAY EQU B'10101011' ; LETRA H #DEFINE BT1 PORTA,1 #DEFINE BT2 PORTA,2 ORG 0X00 GOTO INICIO ORG 0X04 RETFIE DELAY MOVWF TEMPO2 DL1 MOVLW .200 MOVWF TEMPO1 DL2 NOP NOP DECFSZ TEMPO1,F GOTO DL2 DECFSZ TEMPO2,F GOTO DL1 RETURN
TERCEIRO PROGRAMA – PISCA – PISCA
INICIO BANK1 MOVLW B'00000110' MOVWF TRISA MOVLW B'00000000' MOVWF TRISB MOVLW B'10000000' MOVWF OPTION_REG MOVLW B'00000000' MOVWF INTCON BANK0 CLRF PORTA MOVLW DISPLAY MOVWF PORTB MOVLW MIN MOVWF CONTADOR MAIN MOVLW MULTIPLO MOVWF TEMPO3 MAIN1 MOVF CONTADOR,W CALL DELAY BTFSS BT1TERCEIRO PROGRAMA – PISCA – PISCA
XORWF PORTB,F GOTO MAIN DECREMENTA MOVLW STEP SUBWF CONTADOR,F MOVLW MIN SUBWF CONTATOR,W BTFSC STATUS,C GOTO MAIN MOVLW MIN MOVWF CONTADOR BTFSS BT2 GOTO $-1 GOTO MAIN INCREMENTA MOVLW STEP ADDWF CONTATOR,F MOVLW MAX SUBWF CONTADOR,W BTFSS STATUS,C GOTO MAIN MOVLW MAX MOVWF CONTADOR BTFSS BT1 GOTO $-1 GOTO MAINUSANDO O PCL PARA ESCOLHER ENTRE
VÁRIAS ROTINAS
O PCL é um registrador de uso especial (SFR) que contém o endereço da memória de programa que será executado em seguida. Podemos utilizá-lo para retornar diferentes valores ou mesmo executar diferentes funções:
Um exemplo clássico seria o tratamento de funções que seriam executadas dependendo de um tecla específica. Imaginemos um teclado com 6 teclas com funções específicas. O número do botão pressionado é colocado na variável TECLA.
TRATA_TECLA MOVLW B'00000111' ANDWF TECLA,W ADDWF PCL,F GOTO SEM_TECLA GOTO TECLA1 GOTO TECLA2 GOTO TECLA3 GOTO TECLA4 GOTO TECLA5 GOTO TECLA6 GOTO ERRO
PROGRAMA 4 – CONTADOR MELHORADO
Este exemplo é um aperfeiçoamento do exemplo 2. Será utilizado dois botões para fazer o incremento e outro o decremento unitariamente. Outra diferença é que agora será mostrado no display o valor em hexadecimal e não mais em leds.
PROGRAMA 4 – CONTADOR MELHORADO
(FLUXOGRAMA)
PROGRAMA 4 – CONTADOR MELHORADO
(FLUXOGRAMA)
PROGRAMA 4 – CONTADOR MELHORADO
;Programa...: Contador Melhorado;Objetivo...: O software destina-se a mostrar uma contagem hexadecimal em um display de 7 segmentos
#INCLUDE <PIC16F84.INC>
#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK1 BSF STATUS,RP1
CBLOCK 0X0C W_TEMP STATUS_TEMP CONTADOR FLAGS FILTRO1 FILTRO2 ENDC #DEFINE ST_BT1 FLAGS,0 #DEFINE ST_BT2 FLAGS,1 MIN EQU .0 MAX EQU .15 T_FILTRO EQU .255
PROGRAMA 4 – CONTADOR MELHORADO
ORG 0X00 GOTO INICIO ORG 0X04 RETFIE ; a ; ********* ; f * * b ; * g * ; ********* ; e* * c ; * * ; ********* ; d CONVERTE MOVF CONTADOR,W ANDLW B'00001111' ADDWF PCL,F ; B'EDC.BAFG' RETLW B'11101110' RETLW B'00101000' RETLW B'11001101' RETLW B'01101101' RETLW B'00101011' RETLW B'01100111' RETLW B'11100111' RETLW B'00101100'PROGRAMA 4 – CONTADOR MELHORADO
RETLW B'11100011' RETLW B'11000110' RETLW B'11101001' RETLW B'11000111' RETLW B'10000111' INICIO BANK1 MOVLW B'00000110' MOVWF TRISA MOVLW B'00000000' MOVWF TRISB MOVLW B'10000000' MOVWF OPTION_REG MOVLW B'00000000' MOVWF INTCON BANK0 CLRF PORTA CLRF PORTB CLRF FLAGS MOVLW MIN MOVWF CONTADOR GOTO ATUALIZAPROGRAMA 4 – CONTADOR MELHORADO
CHECA_BT1 BTFSC BOTAO1 GOTO BT1_LIB DECFSZ FILTRO1,F GOTO CHECA_BT1 BTFSS ST_BT1 GOTO DEC GOTO CHECA_BT2 BT1_LIB BCF ST_BT1 CHECA_BT2 BTFSC BOTAO2 GOTO BT2_LIB DECFSZ FILTRO2,F GOTO CHECA_BT2 BTFSS ST_BT2 GOTO INC GOTO MAIN BT2_LIB BCF ST_BT2 GOTO MAIN DEC BSF ST_BT1 MOVF CONTADOR,WPROGRAMA 4 – CONTADOR MELHORADO
BTFSC STATUS,Z GOTO MAIN DECFCONTADOR,F GOTO ATUALIZA INC BSF ST_BT2 MOVF CONTADOR,W XORLW MAX BTFSC STATUS,Z GOTO MAIN INCF CONTADOR,F GOTO ATUALIZA ATUALIZA CALL CONVERTE MOVWF PORTB GOTO MAIN ENDEXPLORANDO AS INTERRUPÇÕES
O PIC possui algumas interrupções que são extremamente necessárias quando não queremos utilizar certos artifícios que param a execução do programa . Estas interrupções são usadas para contar tempo, informar o final de escrita na EEPROM, mudança de estado dos pinos por exemplo do PORTB entre outras.
LIGANDO AS CHAVES CORRETAS:
Primeiramente devemos habilitar o PIC para que o mesmo possa tratar tais interrupções. Basicamente temos duas chaves que devemos ficar atentos: A chave individual e a chave global.
Individual: São as chaves (BITS) que habilitam ou desabilitam cada interrupção individualmente. Global: É a chave (BIT) responsável em habilitar ou desabilitar todas as interrupções de uma só vez.
OBS.; Para podermos tratar um interrupção primeira a chave individual referente a ela deverá estar ligada assim como a chave global.
ESTRUTURA BÁSICA DA INTERRUPÇÃO:
Quando ocorre um interrupção o hardware do PIC desvia o programa automaticamente para o endereço 0x04. A partir deste momento podemos inserir os códigos de programas que trataram cada interrupção individualmente. A rotina de interrupção acaba quando o programa chega ao mnemônico RETFIE.
Exemplo:
ORG 0X04
MOVWF W_TEMP
SWAPF STATUS,W
MOVWF STATUS_TEMP
AQUI FICAM OS CÓDIGO DE PROGRAMA SAI_INTERRUPCAO
CHECANDO QUE INTERRUPÇÃO OCORREU
Agora com o conhecimento básico da estrutura do tratamento das interrupções como fazer para verificar qual interrupção ocorreu? Abaixo segue algoritmo executado pelo hardware do PIC quando uma interrupção ocorre.
TRATANDO A INTERRUPÇÃO DE TIMER
ROTINA DE INTERRUPÇÃO TESTE1
BTFSS INTCON,T0IF ;FOI INTERRUPÇÃO DE TIMER GOTO SAI_INT ; NÃO, FINALIZA
BCF INTCON,T0IF ;LIMPA FLAG DE INTERRUPÇÃO DECFSZ TEMPO1,F ;DECREMENTA TEMPO, ACABOU? GOTO SAI_INT ;NÃO, SAI DA INTERRUPÇÃO BTFSS LED ;LED, ESTÁ ACESO?
GOTO LED_ON ;NÃO, ENTÃO ACENDE LED_OFF
BCF LED ;APAGA LED
GOTO FIM_TMR0 ;VAI PARA FIM DA INTERRUPÇÃO LED_ON
BSF LED ;ACENDE O LED
FIM_TMR0
MOVLW .100
MOVWF TEMPO1 ;REINICIA BASE DE TEMPO GOTO SAI_INT ;FINALIZA A INTERRUPÇÃO
TRATANDO A INTERRUPÇÃO EXTERNA
A interrupção externa é uma das mais usadas. Ela é empregada na recepção de dados, sinais que precisam ser tratados imediatamente, sincronismo e muito mais. A interrupção pode ser tratada na borda de descida ou na borda de subida. Para configurarmos isto usamos o registrador OPTION e setar o bit INTEDG. 1 = Subida, 0 = Descida. Para habilitarmos a chave individual INTCON,INTIE deverá estar setada com nível 1. Para verificarmos se a interrupção ocorreu devemos utilizar o bit INTF do registrador INTCON.
TRATANDO A INTERRUPÇÃO DE MUDANÇA DE
ESTADO
Esta interrupção deve ser usada em sinais que devem ser tratados tanto na subida como na descida. Um sincronismo com a rede elétrica é um bom exemplo. Para habilitarmos setamos 1 no bit INTCON,RBIE. Para sabermos se a interrupção ocorreu devemos verificar o bit INTCON,RBIF
PROGRAMA 5 – TIMER SIMPLIFICADO
O seguinte exemplo é um temporizador usando a interrupção de estouro de tempo. O valor será decrementado a cada segundo da variável V_INICIO até zero. Um botão é usado para iniciar o timer e outro para pará-lo. Enquanto o timer estiver funcionanod o led deverá permanecer ligado. A base do prescaler (1:64), na inicialização do TMR0(256-125) e um contador auxiliar (TEMP1) que é inicializado com 125. A interrupção ocorrerá a cada 8 ms (64 us x 125). O contador auxiliar multiplicará este tempo por 125, resultando em 1 segundo (8 ms x 125 = 1s).
PROGRAMA 5 – TIMER SIMPLIFICADO
(FLUXOGRAMA)
PROGRAMA 5 – TIMER SIMPLIFICADO
(FLUXOGRAMA)
PROGRAMA 5 – TIMER SIMPLIFICADO
(FLUXOGRAMA)
PROGRAMA 5 – TIMER SIMPLIFICADO
;Programa...: Timer Simplificado
;Objetivo...: O software destina-se a contar tempo e mostrar a contagem em um display de 7 segmentos
#INCLUDE <P16F84.INC>
#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK0 BSF STATUS,RP1 CBLOCK 0X0C W_TEMP STATUS_TEMP TEMPO FLAGS TEMP1 TEMP2 FILTRO1 FILTRO2 ENDC
#DEFINE F_FIM FLAGS,0
#DEFINE ST_BT1 FLAGS,1
#DEFINE ST_BT2 FLAGS,2
V_INICIO EQU .9
T_FILTRO EQU .255
#DEFINE BOTAO1 PORTA,1
PROGRAMA 5 – TIMER SIMPLIFICADO
ORG 0X00 GOTO INICIO ORG 0X04 MOVWF W_TE,MP SWAPF STATUS,W MOVWF STATUS_TEMP BTFSS INTCON,T0IF GOTO SAI_INT BCF INTCON,T0IF MOVLW (.256-,125) MOVWF TMR0 DECFSZ TEMP1,F GOTO SAI_INT MOVLW .125 MOVWF TEMP1 BTFSC F_FIM GOTO SAI_INT BSF F_FIM SAI_INTPROGRAMA 5 – TIMER SIMPLIFICADO
; a ; ********* ; f * * b ; * g * ; ********* ; e* * c ; * * ; ********* ; d CONVERTE MOVF TEMPO,W ANDLW B'00001111' ADDWF PCL,F ; B'EDC.BAFG' RETLW B'11101110' RETLW B'00101000' RETLW B'11001101' RETLW B'01101101' RETLW B'00101011' RETLW B'01100111' RETLW B'11100111' RETLW B'00101100' RETLW B'11101111' RETLW B'01101111' RETLW B'10101111' RETLW B'11100011' RETLW B'11000110' RETLW B'11101001'PROGRAMA 5 – TIMER SIMPLIFICADO
ATUALIZA CALL CONVERTE MOVWF PORTB RETURN DESL_TIMER BCF INTCON,GIE BCF LED RETURN LIGA_TIMER BTFSC INTCON,GIE RETURN BCF INTCON,T0IF MOVLW .256-,125 MOVWF TMR0 MOVLW ,125 MOVWF TEMP1 BSF INTCON,GIE BSF LED RETURN INICIO BANK1 MOVLW B'00000110' MOVWF TRISAPROGRAMA 5 – TIMER SIMPLIFICADO
MOVLW B'00100000' MOVWF INTCON BANK0 CLRF PORTA CLRF PORTB CLRF FLAGS MOVLW V_INICIO MOVWF TEMPO CALL ATUALIZA MAIN BTFSC F_FIM CALL DESL_TIMER CALL ATUALIZA MOVLW T_FILTRO MOVWF FILTRO1 MOVWF FILTRO2 CHECA_BT1 BTFSC BOTAO1 GOTO BT1_LIB DECFSZ FILTRO1,F GOTO CHECA_BT1 BTFSS ST_BT1PROGRAMA 5 – TIMER SIMPLIFICADO
BT1_LIB BCF ST_BT1 CHECA_BT2 BTFSC BOTAO2 GOTO BT2_LIB DECFSZ FILTRO2,F GOTO CHECA_BT2 BTFSS ST_BT2 GOTO ACAO_BT2 GOTO MAIN ACAO_BT1 BSF ST_BT1 CALL LIGA_TIMER GOTO MAIN ACAO_BT2 BSF ST_BT2 CALL DESL_TIMER GOTO MAIN ENDUTILIZANDO A EEPROM
O PIC 16F84/84A/628/628A possui uma EEPROM interna. A quantidade desta memória varia de modelo para modelo. Esta memória é muito importante quando necessitamos de armazenar dados que não podem ser perdidos mesmo com o desligamento do sistema.
ESCREVENDO NA EEPROM
A escrita da EEPROM é mais complexa que a leitura. Isto deve-se ao fato da proteção em que esta está submetida. Isto torna o sistema muito mais robusto e seguro.
Procedimento para a escrita na EEPROM:
● O Endereço para a escrita deve ser colocado em EEADR. Como existem 64 bytes disponíveis,
esse endereço deve estar entre 0 e 63.
● O dado a ser gravado deve ser colocado na EEDATA. Só podemos escrever um byte de cada vez. ● As interrupções devem ser desligadas para evitarmos conflitos.
● A escrita deve ser habilitada por meio do bit EECON1,WREN(1).
● O registrador EECON2 deve ser carregado com os valores 0x55 e 0xAA, seqüencialmente Este
procedimento é obrigatório e utilizado para a proteção da escrita.
● A escrita deve ser iniciada setando o bit EECON1,WR(1) e limpando o bit EECON1,WREN(0). ● As interrupções podem ser novamente ligadas.
UTILIZANDO A EEPROM
Por isso, normalmente ficamos esperando que isso aconteça. No caso de não podermos ficar esperando pelo fim de escrita, podemos ligar a interrupção de escrita na EEPROM por meio do bit INTCON,EEIE, e esperamos que ela aconteça para considerarmos finalizada a escrita.
● Caso algum erro ocorra durante a operação de escrita, o bit EECON1,WRERR será
setado (1). No caso de sucesso na operação, esse bit será mantido em zero(0).
ROTINA DE ESCRITA NA EEPROM; ESCR_E2PROM MOVWF EEDATA BCF INTCON,GIE BANK1 BSF EECON1,WREN MOVLW 0X55 MOVWF EECON2 MOVLW 0XAA MOVWF EECON2 BSF EECON1,WR BCF EECON1,WREN BTFSC EECON 1,WERR GOTO ESCR_E2PROM+1 BTFSC EECON1,WR GOTO $-3
TRATANDO INTERRUPÇÃO FINAL DE
ESCRITA NA EEPROM
Esta interrupção é utilizada em sistemas que não podem ficar parados esperando o final da escrita na EEPROM.
Para ativar esta interrupção o bit INTCON,EEIE deve estar setado em nível lógico alto.
Para verificar se a interrupção ocorreu devemos utilizar o bit EECON1,EEIF
LENDO DA EEPROM
Após a escrita da EEPROM o normal é que queiramos ler a informação que outrora fora escrita. O procedimento é mais simples do que a escrita.
O roteiro para leitura segue abaixo:
● O endereço para leitura deve ser colocado em EEADR. Como existem 64 bytes
disponíveis, este endereço deve estar entre 0 e 63.
● A leitura deve ser ligada por meio do bit EECON1,RD (1). A leitura terminará quando
este bit voltar automaticamente para zero, o que acontece quase que imediatamente.
● O dado lido será colocado em EEDATA.
Segue abaixo a rotina: LE_E3PROM
BANK1
PROGRAMA 6 – CONTADOR FINAL
O contador final consiste em armazenar o valor atual na memória EEPROM. Caso ocorra uma queda de energia o valor não será perdido.
PROGRAMA 6 – CONTADOR FINAL
;Programa...: Contador Final
;Objetivo...: O software em questão destina-se a fazer uma contagem e armazená-la na EEPROM desta maneira caso haja uma queda de energia a contagem não será perdida.
#INCLUDE <P16F84.INC>
#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BANK0 BSF STATUS,RP1 CBLOCK 0X0C W_TEMP STATUS_TEMP CONTADOR FLAGS FILTRO1 FILTRO2 ENDC #DEFINE ST_BT1 FLAGS,0 #DEFINE ST_BT2 FLAGS,1 MIN EQU .0 MAX EQU .15 T_FILTRO EQU .255 POS_MEM EQU .0