Aula de Microcontrolador

Página 1







Prof. Ms. Alcinei Moura Nunes





Curso: Pós-Graduação em Mecatrônica






Apostila
de
Microcontroladores

PIC16F877A









Aula de Microcontrolador
Página 2
Metodologia

- 3 primeiras aulas → Expositivas e Práticas
- 2 últimas → Apresentação dos Trabalhos

OBS.: O Aluno terá que despertar interesse para alguma aplicação do Microcontrolador
estudado e deverá ao longo do curso (4 primeiras aulas) tirar as dúvidas com o professor.
Na última aula, fará uma apresentação de seu desenvolvimento. Sua nota final será
composta pela participação (presença) e apresentação do projeto.


Material de Apoio

- Livros sobre microcontroladores da Linha PIC (pesquisar pelo Google)
- site: www.microchip.com (datasheet e application note)
- Gravadores (internet): ATM (mercado livre) e Labtools (Mcflash ou ICD2BR)


Aula 1
Conhecendo o Processador

Tópicos:

• Características Gerais do PIC16F877A
• Periféricos
• Arquitetura
• Organização da Memória
• Registrador STATUS
• Pinagem
• Ambiente de Desenvolvimento (MPLAB)
• Organização de um Programa
• Clock do PIC (ciclo de máquina)
• Primeiro Programa: Acionamento de um Motor de Passo


Características Gerais do PIC16F877A

- Arquitetura RISC (set de instruções reduzidas);
- 35 instruções apenas;
- Velocidade de Operação: até 20MHz;
- Memória de Programa (Flash): 8K x 14 words;
- Memória de Dados (RAM): 368 x 8 bytes;
- Memória EEPROM: 256 x 8 bytes;
- 8 níveis de STACK;
- 14 tipos de interrupções;
- WDT (WatchDogTimer);
Aula de Microcontrolador
Página 3
- Proteção do Código;
- In-Circuit Serial Programming (ICSP) através de 2 pinos;
- Opção de selecionar o oscilador;
- Ampla faixa de tensão de Operação: 2,0V à 5,5V;
- Capacidade de corrente por pino: 25mA.



Periféricos

• Timer0: 8-bit timer/counter
• Timer1: 16-bit timer/counter
• Timer2: 8-bit timer/counter
• Modo PWM (10-bit de resolução)
• 8 canais analógicos (10-bit de resolução)
• Modo SSP (Synchronous Serial Port) com protocolos SPI e I2C
• Modo de Comunicação USART (Universal Synchronous Asynchronous Receiver
Transmitter)
• Comunicação Paralela (Parallel Slave Port – PSP).



Arquitetura

Página 6 do Datasheet PIC16F87X





















Aula de Microcontrolador
Página 4
Organização da Memória

Memória de Programa














Aula de Microcontrolador
Página 5
Memória de Dados




Aula de Microcontrolador
Página 6



Registrador STATUS




Aula de Microcontrolador
Página 7
Pinagem




















Aula de Microcontrolador
Página 8
Ambiente de Desenvolvimento (MPLAB)


Gerenciador de projeto MPLAB






Um compilador converte o código fonte em instruções de máquina.




Liguagem C,
Assembly ou
Pascal.
Linguagem
de Máquina
Aula de Microcontrolador
Página 9
Todos os Projetos terão os seguintes passos básicos:

• Seleção do Dispositivo
• Criação do Projeto
• Seleção da Ferramenta de Linguagem
• Criação do Código-Fonte
• Construção do Projeto (Montagem e Ligação)
• Teste do Código com Simulador







Ambiente de Trabalho










Aula de Microcontrolador
Página 10


Configure> Select Device

Seleção do Dispositivo


As “luzes” indicam quais componentes o MPLAB IDE suporta para este dispositivo.

Verde: indica suporte completo
Amarelo: indica suporte parcial
Vermelho: indica nenhum suporte para esse dispositivo.












Aula de Microcontrolador
Página 11
Project > Project Wizard

Criando um Novo projeto


Seleção do PIC

Aula de Microcontrolador
Página 12

Seleção da Linguagem




Nome do Projeto
Aula de Microcontrolador
Página 13


Adição de arquivos existentes para seu projeto


Resumo da criação do projeto

Aula de Microcontrolador
Página 14
Caso não tenha adicionado nenhum arquivo, então clique no File>New para escrever o
código fonte.


Janela para escrever o programa






Programa

Aula de Microcontrolador
Página 15
Project>Build All

Assembler do Programa



Neste passo, criamos os arquivos de saída (.HEX, .LST e .ERR) a partir do arquivo .ASM.
Quando aparecer a mensagem “BUILD SUCCEEDED” no final da compilação, significa que os
arquivo de saída foram gerados corretamente, ou seja, as instruções do programa foram
compreendidas e convertidas em sistema binário. Caso apareça a mensagem “BUILD FAILED”,
deve-se dar duplo clique sobre o erro na janela de saída para o erro ser apontado na janela do
código-fonte.


Se o “Construído com Sucesso” foi alcançado, pode-se realizar a simulação do
programa, funcionando no MPLAB como se estivesse gravado na memória do CHIP.
















Aula de Microcontrolador
Página 16
Debugger>Select Tool>MPLAB SIM

Simulação

Na simulação podemos verificar como deverá ser a execução do programa quando este
estiver gravado na memória FLASH do PIC. Para verificarmos os valores que são lidos ou
escritos na memória de dados ou outros componentes do microcontrolador clicamos no menu
View.

View>Watch

Verificação dos valores dos registradores
Aula de Microcontrolador
Página 17
Com o Watch é possível verificar alguns valores de alguns registradores específicos.


Organização de um programa

;***************************************************************
#include<P16F877A> ;região para inclusão de bibliotecas e macros.
;***************************************************************
__CONFIG ;região de habilitação/desabilitação dos fusíveis.
;***************************************************************
#define BANK1 BSF Status,RP0 ;região para definição de mini-macros.
;***************************************************************
CBLOCK 0x20 ;região para definição de variáveis
Tempo1 ;os registradores de propósito geral
Tempo2 ;começam do endereço 0x20 da RAM.
Endc
;***************************************************************
tempo1_value EQU .10 ;região para associação de valores à nomes
tempo2_value EQU .50
;***************************************************************
ORG 0x0000 ;início da memória de programa
Goto INICIO
;***************************************************************
ORG 0X0004 ;início da região de interrupção
Goto INT
;***************************************************************
DELAY_LCD ;região de sub-rotinas chamadas pela
.... ;instrução CALL
RETURN

ATUALIZA_LCD
....
RETURN

MULTIPLICACAO
....
RETURN
;***************************************************************
Inicio ;início do programa
BANK1
MOVLW B’00000001’ ;região para carregamento dos registradores
MOVWF TRISA ;especiais conforme aplicação prática
MOVLW B’00000000’
MOVWF TRISB
BANK0

....
Aula de Microcontrolador
Página 18


Principal ;região lógica do programa
;atuação dos registradores de
.... ;entrada e saída


Goto Principal
;***************************************************************
END ;Final do Programa
;***************************************************************


Clock do PIC (ciclo de máquina)

O Pic16F877A possui dois osciladores internos do tipo RC de 4MHz, com precisões
de ±1 e ±5, as quais dependem das condições de tensão e temperatura do sistema. Estes
osciladores não são tão precisos, mas dispensam a utilização de osciladores externos,
liberando 2 pinos de I/Os.
De um modo geral, osciladores externos são utilizados, e sua escolha dependerá
da precisão e custos envolvidos; dentre eles podemos destacar: circuito RC, ressoador,
cristal e circuitos de oscilação. Abaixo temos a ligação de um oscilador à cristal.



Aula de Microcontrolador
Página 19




Nos microcontroladores da família PIC, o clock é internamente dividido por quatro.
Sendo assim, para um cristal de 4MHz, teremos um clock interno de 1MHz, ou seja, o
tempo de execução de cada instrução será de 1us (micro-segundo). Este tempo é
chamado de ciclo de máquina e é menor quanto maior for o cristal externo utilizado.
Em cada período de 1us (para o caso de um cristal de 4MHz), uma nova
informação é buscada na memória de programa enquanto a informação anterior é
executada. Essa característica de buscar a informação em um ciclo de máquina e
executá-la no próximo é conhecida como PIPELINE.
De um modo geral, as instruções são executadas no período de 1 ciclo de máquina;
apenas as instruções que indicam salto, tais como: CALL, RETURN e GOTO, perdem 2
ciclos de máquina.


Primeiro Programa: Acionamento de um Motor de Passo

Aprendizado

- Estrutura de um Programa
- Declaração de variáveis
- Estrutura de Decisão (botões)
- Carregamento de Registradores
- Delay
- Deboucing (filtro para botões)


Aula de Microcontrolador
Página 20
Funcionamento do Motor de Passo

O motor de passo se difere dos demais motores devido a duas características
principais: precisão (sem a necessidade sensores de final de curso) e modo de
acionamento.

A maioria dos motores de passo são acionados através de sinais seqüenciais e
independentes para cada uma de suas 4 bobinas. Sua velocidade é dada através do delay
entre um sinal e outro.

O ângulo do motor de passo pode variar de motor para motor, mas no geral é de
1,8º por passo. Dependendo do modo de acionamento é possível reduzir este valor pela
metade.

Abaixo mostramos o modo de acionamento, considerando um sinal de 1 byte (8
bits) para um motor de 4 bobinas.

Sinal Bobinas
00000001 Bobina 1
00000010 Bobina 2
00000100 Bobina 3
00001000 Bobina 4

Em cada instante, apenas uma bobina está acionada. O sinal deve ser seqüencial
para que o motor gire para o mesmo sentido. Se a seqüência correta não for alcançado o
motor girará um passo para um sentido e outro para o sentido contrário, ou seja, ele
vibrará, mas não sairá do lugar.

Identificação do Comum do Motor de passo

Normalmente os motores de passo possuem seis fios, sendo que dois deles devem
ser conectados no mesmo ponto. Estes dois devem ser identificados e são chamados de
“comum”. Quando temos a configuração a cinco fios, quer dizer que os dois fios já estão
conectados juntos no interior do motor e, portanto, temos um fio comum.


Aula de Microcontrolador
Página 21

Para identificação dos comuns, devemos medir os fios de dois em dois na escala de
resistência. Quando estivermos com o fio comum em uma das pontas de prova do
multímetro a resistência deverá ser lida pela metade (vide figura abaixo).

Motor de 5 fios Motor de 6 fios


Analisando o caso do motor a cinco fios acima, temos que a medida entre
quaisquer dois fios excluindo o fio 1, resultará sempre o dobro da medida entre o fio 1 e
qualquer outro fio (2, 3, 4 e 5).
O mesmo vale para o motor a seis fios, apenas que o comum, neste caso, é
formado pela conexão dos fios 1 e 2.

Identificação da seqüência das Bobinas


Tendo já descoberto o fio comum, para identificarmos a seqüência das bobinas
devemos aplicar 12 volts em seus terminas. O positivo da fonte deve ser conectado ao
comum do motor, e o negativo deve ser triscado em cada uma das quatro bobinas até
alcançar uma combinação que resulte no giro do motor para um mesmo sentido.
















Aula de Microcontrolador
Página 22
Drivers para acionamento do Motor de Passo



ULN2803














Aula de Microcontrolador
Página 23




TIP31C



















Aula de Microcontrolador
Página 24
Esquema de Ligação utilizando Transistores (TIP122 ou TIP31C)



Hardware do Botão






Programa


#INCLUDE<P16F877A.INC>

__CONFIG _CP_OFF & _CPD_OFF & _DEBUG_OFF & _LVP_OFF & _WRT_OFF
& _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

Aula de Microcontrolador
Página 25
#DEFINE BANK1 BSF STATUS,RP0
#DEFINE BANK0 BCF STATUS,RP0
#DEFINE BT_HOR PORTB,7
#DEFINE BT_ANTIHOR PORTB,6

CBLOCK 0X20
T1
T2
T3
FILTRO1
FILTRO2
ENDC

FILTRO1_VALUE EQU .180
FILTRO2_VALUE EQU .20

ORG 0X0000
GOTO CONFIGURA

ORG 0X0004
GOTO CONFIGURA

;********************************************
DELAY
MOVLW .255
MOVWF T1
MOVLW .255
MOVWF T2
MOVLW .8
MOVWF T3

DELAYAUX
DECFSZ T1
GOTO DELAYAUX
DECFSZ T2
GOTO DELAYAUX
DECFSZ T3
GOTO DELAYAUX

RETURN
;********************************************

CONFIGURA
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
Aula de Microcontrolador
Página 26
CLRF PORTE

BANK1
MOVLW B'00000000'
MOVWF TRISA
MOVLW B'11110000'
MOVWF TRISB
MOVLW B'00000000'
MOVWF TRISC
MOVLW B'00000000'
MOVWF TRISD
MOVLW B'00000000'
MOVWF TRISE

MOVLW B'10000100'
MOVWF OPTION_REG
MOVLW B'00000111'
MOVWF ADCON1

BANK0
MOVLW B'00000000'
MOVWF INTCON

HORARIO
BTFSS BT_ANTIHOR
GOTO FILTRO_ANTIHOR

BSF PORTC,7
CALL DELAY
BCF PORTC,7
BSF PORTC,6
CALL DELAY
BCF PORTC,6
BSF PORTC,5
CALL DELAY
BCF PORTC,5
BSF PORTC,4
CALL DELAY
BCF PORTC,4

MOVLW FILTRO1_VALUE
MOVWF FILTRO1
MOVLW FILTRO2_VALUE
MOVWF FILTRO2

GOTO HORARIO

Aula de Microcontrolador
Página 27
FILTRO_ANTIHOR
DECFSZ FILTRO1
GOTO HORARIO

MOVLW FILTRO1_VALUE
MOVWF FILTRO1

DECFSZ FILTRO2
GOTO HORARIO

MOVLW FILTRO2_VALUE
MOVWF FILTRO2

GOTO ANTI_HORARIO



ANTI_HORARIO
BTFSS BT_HOR
GOTO FILTRO_HOR

BSF PORTC,4
CALL DELAY
BCF PORTC,4
BSF PORTC,5
CALL DELAY
BCF PORTC,5
BSF PORTC,6
CALL DELAY
BCF PORTC,6
BSF PORTC,7
CALL DELAY
BCF PORTC,7

MOVLW FILTRO1_VALUE
MOVWF FILTRO1
MOVLW FILTRO2_VALUE
MOVWF FILTRO2

GOTO ANTI_HORARIO

FILTRO_HOR
DECFSZ FILTRO1
GOTO ANTI_HORARIO

MOVLW FILTRO1_VALUE
MOVWF FILTRO1
Aula de Microcontrolador
Página 28

DECFSZ FILTRO2
GOTO ANTI_HORARIO

MOVLW FILTRO2_VALUE
MOVWF FILTRO2

GOTO HORARIO

END

*********************************************FIM AULA 1********************************************



Aula 2
Interrupções do PIC16F877A



Tópicos:

• Interrupções
• Timers (temporizadores)
• Temporização de 1 segundo (TIMER1)
• Display de Cristal Líquido (LCD 2x16)
• Segundo Programa: Relógio Digital



Interrupções


Interrupção é uma poderosa ferramenta dos microcontroladores. Os registradores
responsáveis pela interrupção do PIC16F877A são: INTCON, PIE1, PIE2, PIR1 e PIR2. O
principal Registrador é o INTCON, pois os bits 6 (PEIE) e 7 (GIE) deste registrador são
responsáveis pela habilitação da interrupção.
Para este microcontrolador específico, todas interrupções são apontadas para o
endereço 0x0004 da Memória de Programa (FLASH). Portanto, quando uma interrupção
ocorrer o contador de programa (PCLATH:PCL) apontará para a posição 0x0004, ficando
por conta do programador a escolha das prioridades.





Aula de Microcontrolador
Página 29
REGISTRADOR INTCON
7 6 5 4 3 2 1 0
R/W R/W R/W R/W R/W R/W R/W R/W
GIE PEIE T0IE INTE RBIE T0IF INTF RBIF







GIE = Habilitação geral das interrupções.
PEIE = Habilita/Desabilita interrupção por periféricos.
T0IE = Habilita/Desabilita interrupção por Timer 0.
INTE = Habilita/Desabilita interrupção pelo pino RB0/INT.
RBIE = Habilita/Desabilita interrupção por mudança de estado.
T0IF = Sinalizador de estouro do TMR0.
INTF = Sinalizador de interrupção pelo pino RB0/INT.
RBIF = Sinalizador de interrupção por mudança de estado.




REGISTRADOR PIE1
7 6 5 4 3 2 1 0
R/W R/W R/W R/W R/W R/W R/W R/W
PSPIE ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE


PSPIE = Habilita interrupção por Escrita/Leitura da Porta Paralela.
ADIE = Habilita interrupção por término da conversão A/D.
RCIE = Habilita interrupção por dado recebido (USART)
TXIE = Habilita interrupção por dado transmitido(USART).
SSPIE = Habilita interrupção por dado recebido/transmitido por Porta Serial Síncrona
CCP1IE = Habilita interrupção do módulo CCP1.
TMR2IE = Habilita interrupção por estouro do Timer 2.
TMR1IE = Habilita interrupção por estouro do Timer 1.









{
Chave Geral para interrupção de periféricos
Porta Paralela, Conversor A/D,
USART (recepção e transmissão),
CCP1, CCP2, SSP (SPI ou I2C), Timer
1 (TMR1) e Timer 2 (TMR2).
Aula de Microcontrolador
Página 30

REGISTRADOR PIE2
7 6 5 4 3 2 1 0
R/W R/W R/W R/W R/W R/W R/W R/W
EEIE BCLIE CCP2IE


EEIE = Habilita interrupção por Escrita/Leitura na EEPROM.
BCLIE = Habilita interrupção por Colisão no Barramento.
CCP1IE = Habilita interrupção do módulo CCP2.




REGISTRADOR PIR1
7 6 5 4 3 2 1 0
R/W R/W R/W R/W R/W R/W R/W R/W
PSPIF ADIF RCIF TXIF SSPIF CCP1IF TMR2IF TMR1IF


PSPIF = Sinalizador de término de Escrita/Leitura na Porta Paralela.
ADIF = Sinalizador de término da conversão A/D.
RCIF = Sinalizador de dado recebido (USART)
TXIF = Sinalizador de dado transmitido(USART).
SSPIF = Sinalizador de dado recebido/transmitido por Porta Serial Síncrona
CCP1IF = Sinalizador da interrupção do módulo CCP1.
TMR2IF = Sinalizador de estouro do Timer 2.
TMR1IF = Sinalizador de estouro do Timer 1.


REGISTRADOR PIR2
7 6 5 4 3 2 1 0
R/W R/W R/W R/W R/W R/W R/W R/W
EEIF BCLIF CCP2IF

EEIF = Sinalizador de término de Escrita/Leitura na EEPROM.
BCLIF = Sinalizador de Colisão no Barramento.
CCP1IF = Sinalizador de interrupção do módulo CCP2.


TIMERS (Temporizadores)

Cada um dos Timers possui uma capacidade de temporização que se diferem uns
dos outros conforme a quantidade de bits, os registradores de controle e o PRESCALER
(divisor de freqüência). O Prescaler é um divisor de freqüência que torna possível um
aumento no tempo de incremento do registrador (contador).
Aula de Microcontrolador
Página 31
Os registradores dos TIMERS podem ser incrementados de duas maneiras: através
do clock interno (ciclo de máquina) ou através da borda de subida ou descida de um sinal
de entrada externo.
O tempo é obtido através da multiplicação entre: a contagem dos incrementos no
registrador (da inicialização até o estouro), o Prescaler, e, o clico de máquina ou o tempo
do pulso externo.


TMR0

O TMR0 é um contador automático de 8bits (256 valores); seu registrador de
controle é o OPTION_REG. O TMR0 é incrementado em cada ciclo de máquina quando o
T0CS=0, ou incrementado em cada pulso externo pelo pino RA4/T0CKI quando T0CS=1
(T0CS é configurado no registrador OPTION, onde também é configurado se o incremento
será na borda de subida, “0”, ou descida, “1”, através de T0SE).
Se a interrupção por estouro de TMR0 estiver habilitada no INTCON (T0IE=1), ao
final da contagem (255) o contador de programa (PCLATH:PCL) apontará para a posição
0x0004.
Através do PRESCALER, também configurado no OPTION, é possível aumentar o
tempo de estouro do TMR0 dividindo a freqüência, isto é, quanto menor a freqüência,
maior o tempo. A tabela do PRESCALER é mostrada abaixo.


PS 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
110 1:128 1:64
111 1:256 1:128



Por exemplo, se utilizarmos a configuração 111, para os bits PS2, PS1 e PS0, o
TMR0 será incrementado a cada 256µs. Importante lembrar que, o bit 3 (PSA) do OPTION
seleciona o PRESCALER para WDT (PSA=1) ou para TMR0 (PSA=0). O registrador
OPTION é mostrado abaixo.







Aula de Microcontrolador
Página 32
REGISTRADOR OPTION
7 6 5 4 3 2 1 0
R/W R/W R/W R/W R/W R/W R/W R/W
RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0

RBPU = Ativação dos resistores de pull-ups internos do PORTB.
0: Resistores de pull-ups ativados (apenas para os pinos configurados como
entrada)
1: Resistores de pull-ups desativados

INTEDG = Configuração da borda que gerará a interrupção externa no RB0.
0: Interrupção ocorrerá na borda de descida.
1: Interrupção ocorrerá na borda de subida.

T0CS = Configuração do incremento para o TMR0.
0: TMR0 será incrementado internamente pelo clock de máquina.
1: TMR0 será incrementado externamente pelo pino RA4/T0CKI.

T0SE = Configuração da borda que incrementará o TMR0 no pino RA4/T0CK, quando
T0CS=1.
0: borda de subida
1: borda de descida

PSA = Configuração de aplicação do Pre-Scale
0: O Pre-Scale será aplicado ao TMR0.
1: O Pre-Scale será aplicado ao WDT.

PS2:PS0 = Configuração do valor do Pre-Scale (a tabela já foi mostrada acima)



TMR1

O TMR1 é um contador automático de 16 bits; seu registrador de controle é o
T1CON. No TMR1 são utilizados dois registradores (TMR1L e TMR1H) para armazenar o
valor de inicialização da contagem. Assim como no Timer 0, o TMR1 pode trabalhar com o
incremento pelo clock interno ou externo, e também possui um prescaler independente,
configurado no registrador T1CON (T1CKPS1:T1CKPS0), o qual é mostrado abaixo.









Aula de Microcontrolador
Página 33
REGISTRADOR T1CON
7 6 5 4 3 2 1 0
U U R/W R/W R/W R/W R/W R/W
- - T1CKPS1 T1CKPS0 T1OSCEN /T1SYNC TMR1CS TMR1ON


T1CKPS1:T1CKPS0 = Ajuste do prescaler do Timer 1 (tabela abaixo).


PS1 / 0 TMR1
00 1:1
01 1:2
10 1:4
11 1:8


T1OSCEN = Habilitação de um oscilador externo para os pinos T1OSO e T1OSI (12 e 13).
0: Oscilador desabilitado.
1: Oscilador externo habilitado.

/T1SYNC = Controle de sincronismo interno. Quando TMR1CS=0 este bit é ignorado.
0: Sincronismo ligado.
1: Sincronismo desligado (modo assíncrono).

TMR1CS = Seleção da origem do clock para Timer 1.
0: Clock interno
1: Clock externo no pino T1OSO/T1CKI

TMR1ON = Habilitação do Timer 1.
0: Timer 1 desabilitado. Paralisa o contador do Timer 1.
1: Timer 1 habilitado.


Temporização de 1 segundo (TIMER1)

Os registradores que devem ser carregados com o valor inicial da contagem são:
TMR1L e TMR1H.

Para podermos obter um tempo de 1 segundo apresentaremos uma maneira das
várias possibilidades possíveis, isto depende dos valores iniciais de TMR1L e TMR1H, e
do Prescaler do Timer 1, configurado através do T1CON.

Temporização de 1 segundo:

TMR1_HIGH EQU HIGH (.65536-.62500) ;parte alta do valor do temporizador
TMR1_LOW EQU LOW (.65536-.62500) ;parte baixa do valor do temporizador
Aula de Microcontrolador
Página 34

MOVLW B’00110000’ ;Prescaler 1:8
MOVWF T1CON

Efetuando a configuração acima temos um tempo de 0,5 segundo, por isto é preciso
um registrador auxiliar carregado com o valor 2 para que somente na segunda interrupção
esta rotina seja executada. Isto é obtido através das instruções abaixo.

DECFSZ Divisor_TMR1
Goto SAI_INT_TMR1

INT_TMR1 ;rotina de interrupção por TMR1

.....


SAI_INT_TMR1
BCF PIR1,TMR1IF

RETFIE


Display de Cristal Líquido (LCD 2x16)





O modelo de display que estaremos utilizando é
um de duas linhas com 16 caracteres cada uma.
Sua pinagem é mostrada abaixo:


Pino Função Pino Função
1 V
SS
9 DB2
2 V
DD
10 DB3
3 V
0
11 DB4
4 RS 12 DB5
5 R/W 13 DB6
6 E 14 DB7
7 DB0 15 A
8 DB1 16 K


V
SS
e V
DD
: alimentação do componente (5V)
V
o
: potenciômetro de 10K (controle de contraste)
Aula de Microcontrolador
Página 35
RS: Tipo de informação (0=comando; 1=dado)
R/W: Leitura (“0”) / Escrita (“1”) - comando ou dado e verificação do término de uma
operação
E: habilita leitura da informação no barramento de dados
DB0 a DB7: barramento de dados paralelo
A e K: usados para ligação do Backlight (iluminação de fundo)


Existem basicamente duas maneiras para se trabalhar com o LCD: uma é a
detecção do instante exato no qual a operação já foi executada, onde fazemos a leitura do
BUSY FLAG utilizando o pino RW como leitura, através da operação READ STATUS, e a
outra é a utilização de rotinas de atraso que garante o término das operações internas do
módulo LCD.
Apesar de o barramento ser de 8 vias, é possível trabalhar com o módulo com
comunicação de 4 vias, o que valoriza sua utilização principalmente nos PIC’s com
quantidade pequena de pinos (18 pinos).
Para enviarmos uma informação ao LCD precisamos primeiramente ajustar RS para
informar se é um comando ou um dado. Em seguida, devemos escrever a informação no
barramento de dados, e depois setar o pino E.


Inicialização do LCD

Toda vez que a alimentação for ligada, deve ser executado o procedimento de
inicialização do LCD.

1. Aguardar 15ms
2. Com RS em “0”, enviar 0x30 para o display (inicialização)
3. Aguardar pelo menos 4ms.
4. Com RS em “0”, enviar 0x30 para o display (inicialização)
5. Aguardar pelo menos 100µs.
6. Com RS em “0”, enviar 0x30 para o display (inicialização)
7. Aguardar pelo menos 40µs.
8. Com RS em “0”, enviar B’00111000’ (comunicação por 8 vias)
9. Aguardar pelo menos 40µs.
10. Com RS em “0”, enviar B’00000001’ (limpar display e posicionar o cursor na
1ªlinha/1ªcoluna)
11. Aguardar pelo menos 1,8ms.
12. Com RS em “0”, enviar B’00001100’ (liga o display sem cursor)
13. Aguardar pelo menos 40µs.
14. Com RS em “0”, enviar B’00000110’ (deslocamento automático do cursor para a
direita)
15. Aguardar pelo menos 40µs.



Aula de Microcontrolador
Página 36
Lista de Comandos do LCD

Tabela. Comandos do LCD.
RS RW D7 D6 D5 D4 D3 D2 D1 D0 Instrução/Descrição
4 5 14 13 12 11 10 9 8 7 Pinos

0

0

0

0

0

0

0

0

0

1
Limpa Display e retorna a 1ª
posição

0

0

0

0

0

0

0

0

1

*
Retorna Cursor a 1ª posição

0

0

0

0

0

0

0

1

ID

S
Estabelece sentido de
deslocamento

0

0

0

0

0

0

1

D

C

B
Ativa/Desativa display,
ativa/desativa cursor,
ativa/desativa cursor piscante.
0 0 0 0 0 1 SC RL * * Move Cursor/Desloca Display

0

0

0

0

1

DL

N

F

*

*
Estabelece o nº de bits da
interface, estabelece o nº de
linhas, e tipo de informação dos
caracteres.
0 0 0 1 A A A A A A Endereça a CGRAM

0

0

1

A

A

A

A

A

A

A

Endereça a DDRAM

0

1

BF

*

*

*

*

*

*

*
Lê o conteúdo do contador de
endereços, e a Busy Flag.

1

0

D

D

D

D

D

D

D

D
Escreve dados na CG ou
DDRAM.

1

1

D

D

D

D

D

D

D

D

Lê dados da CG ou DDRAM.


ID→ 0: o cursor desloca-se automaticamente para a esquerda (decremento) após uma
operação de escrita ou leitura.
1: o cursor desloca-se automaticamente para a direita (incremento) após uma
operação de escrita ou leitura.

S→ 0: desliga o deslocamento da mensagem.
1: Liga o deslocamento da mensagem. Serve para implementar as funções de insert
e backspace.

D→ 0: Inibe a visualização dos caracteres no display. A memória interna do LCD
permanece inalterada.
1: Habilita a visualização dos caracteres no display, conforme os dados existentes
na memória interna.

C→ 0: o cursor não é visível.
Aula de Microcontrolador
Página 37
1: o crusor é visível como uma linha embaixo do caractere (oitava linha da matriz),
como se fosse um sublinhado.

B→ 0: desativa o cursor piscante.
1: ativa o cursor piscante.

SC e RL→00: o cursor desloca-se para a esquerda. Decrementa o endereço da memória
interna DDRAM.
01: o cursor desloca-se para a direita. Incrementa o endereço da memória interna
DDRAM.
10: desloca-se a mensagem e o cursor para a esquerda, em relação à posição
atual do cursor. Função Insert.
11: desloca-se a mensagem e o cursor para a direita, em relação à posição atual
do cursor. Função Backspace.

DL→ 0: comunicação feita pelas 8 vias de dados, de DB0 à DB7.
1: comunicação feita em 4 vias de dados, de DB4 à DB7. Inicialmente deve ser
enviado, a parte alta do byte e, em seguida, a parte baixa.

N e F→ 00: 1 linha com matriz de 7x5 + cursor
01: 1 linha com matriz de 10x5 + cursor
1-: 2 linhas com matriz de 7x5 + cursor

Escrevendo Caracteres no Display

Posicionamento do Cursor na DDRAM:

RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 1 A A A A A A A

O valor acima é enviado com RS em “0”.
Para isto, basta posicionar corretamente o cursor antes da operação de escrita do
dado. Abaixo, mostramos a tabela com os 32 caracteres do display e seus endereços
absolutos (em hexadecimal).

Coluna 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Linha0 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
Linha1 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF

Com o cursor na posição correta, basta enviar a letra (código ASCII) que se deseja
escrever para o display. Lembrando que neste caso, RS deve ser igual a “1”.

RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
1 D D D D D D D D

Aula de Microcontrolador
Página 38
Não se pode esquecer também do pulso em E (utilizado para efetivar a leitura da
informação escrita no barramento de dados).



Segundo Programa: Relógio Digital


#include<p16f877a.inc>

__CONFIG _CP_OFF & _CPD_OFF & _DEBUG_OFF & _LVP_OFF & _WRT_OFF
& _BODEN_OFF & _WDT_ON & _PWRTE_ON & _XT_OSC

ERRORLEVEL -302
ERRORLEVEL -305

#DEFINE BANK1 BSF STATUS,RP0 ;definições de bancos
#DEFINE BANK0 BCF STATUS,RP0

#DEFINE BT_UP PORTB,0 ;incremento do contador do Display
#DEFINE BT_DOWN PORTB,1 ; decremento do contador do Display
#DEFINE BT_ZERO PORTB,2 ;botão para zerar relógio
#DEFINE BT_LIGA_DESLIGA PORTB,3 ;botão para inicar relógio e parar relógio

#DEFINE DISP_LCD PORTD ;define LCD
#DEFINE RS PORTE,0 ;RS=0 - comando, RS=1 - dado
#DEFINE ENABLE PORTE,1 ;habilita o LCD para pegar os dados

#DEFINE FLAG_TMR1 PORTA,0 ;aciona LED quando o relógio liga

CBLOCK 0X20
UNI_SEG
DEZ_SEG
UNI_MIN
DEZ_MIN
HORAS
FILTRO_BOTOES
TEMPO_TURBO
DIVISOR_TMR1 ;variável auxiliar para contagem de 1 segundo exato
CONV_DEZ_HORAS
CONV_UNI_HORAS
TEMPO0 ;delay do LCD
TEMPO1 ;delay do LCD
AUX ;variável auxiliar usada na conv binário para decimal
DISP_LCD_TEMP ;variável temporária que conterá o valor do dado ou
;comando que será enviado ao LCD
ENDC
Aula de Microcontrolador
Página 39

FILTRO_TECLA EQU .200 ;filtro para evitar ruídos dos botões
TURBO_TECLA EQU .25

TMR1_HIGH EQU HIGH (.65536-.62500) ;parte alta do valor do temporizador
TMR1_LOW EQU LOW (.65536-.62500) ;parte baixa do valor do temporizador

ORG 0x00
GOTO CONFIG

ORG 0X04

INT_TMR1 ;interrupção por TMR1
MOVLW TMR1_HIGH ;atualiza contadores alto e baixo referente ao
MOVWF TMR1H ;tempo do TMR1.
MOVLW TMR1_LOW
MOVWF TMR1L

DECFSZ DIVISOR_TMR1,F ;variável auxiliar (DIVISOR_TMR1) para dar
;1 segundo exato.
;DIVISOR_TMR1 = 0 ?
GOTO SAI_INT_TMR1 ;NÃO
;SIM

MOVLW .2 ;atualiza variável auxiliar do TMR1
MOVWF DIVISOR_TMR1

CALL INCREMENTA_TIMER ;chama rotina para incrementar contador

CALL ATUALIZA_HORARIO

SAI_INT_TMR1 ;nome da rotina
BCF PIR1,TMR1IF ;Limpa flag para ocorrer interrupção por TMR1.
RETFIE

INCREMENTA_TIMER ;rotina para incrementar displays
INCF UNI_SEG,F ;incrementa o display referente à unidade

MOVLW .10 ;teste para ver se chegou à 10.
XORWF UNI_SEG,W ;UNIDADE=10?
BTFSS STATUS,Z
RETURN ;NÃO

CLRF UNI_SEG ;SIM
INCF DEZ_SEG,F ;incrementa o display referente à dezena


Aula de Microcontrolador
Página 40
MOVLW .6 ;teste para ver se chegou à 10.
XORWF DEZ_SEG,W ;DEZENA=10?
BTFSS STATUS,Z
RETURN ;NÃO

CLRF DEZ_SEG ;SIM
INCF UNI_MIN,F ;incrementa o display referente à centena

MOVLW .10
XORWF UNI_MIN,W
BTFSS STATUS,Z
RETURN

CLRF UNI_MIN
INCF DEZ_MIN,F ;incrementa o display referente à milhar

MOVLW .6
XORWF DEZ_MIN,W
BTFSS STATUS,Z
RETURN

CLRF DEZ_MIN
INCF HORAS,F ;incrementa o display referente à milhar

MOVLW .24
XORWF HORAS,W
BTFSC STATUS,Z
CLRF HORAS
RETURN

DECREMENTA_TIMER ;rotina para decrementar contador

DECF UNI_SEG,F ;decrementa variável UNI_SEG e guarda o valor nela mesma
;daqui para baixo, é preciso saber se o último valor foi 0x00.
;Se foi 0x00, então UNI_SEG vale 0xFF, onde fazendo a
;máscara (XORWF) teremos,
;0x00 como resultado em W_REG, setando o bit Z do STATUS.
;Com isto, o valor da UNI_SEG deve ser atualizado novamente
;para 0x09.
MOVLW 0XFF ;teste para ver se UNIDADE já chegou ao 0xFF
XORWF UNI_SEG,W ;mascaramento.
BTFSS STATUS,Z ;bit Z do STATUS é igual a 1 ?
RETURN ;NÃO
;SIM
MOVLW .9 ;atualiza UNIDADE para começar do 0x09.
MOVWF UNI_SEG

Aula de Microcontrolador
Página 41
DECF DEZ_SEG,F ;decrementa variável DEZENA e guarda o valor
;nela mesma
MOVLW 0XFF ;teste para ver se DEZENA já chegou ao 0xFF
XORWF DEZ_SEG,W ;mascaramento.
BTFSS STATUS,Z ;bit Z do STATUS é igual a 1 ?
RETURN ;NÃO
;SIM
MOVLW .5 ;atualiza DEZENA para começar do 0x09.
MOVWF DEZ_SEG

DECF UNI_MIN,F ;decrementa variável CENTENA e guarda o valor
;nela mesma
MOVLW 0XFF
XORWF UNI_MIN,W
BTFSS STATUS,Z
RETURN

MOVLW .9
MOVWF UNI_MIN

DECF DEZ_MIN,F ;decrementa variável MILHAR e guarda o valor
;nela mesma
MOVLW 0XFF
XORWF DEZ_MIN,W
BTFSS STATUS,Z
RETURN

MOVLW .5
MOVWF DEZ_MIN

DECF HORAS,F
MOVLW 0XFF
XORWF HORAS,W
BTFSS STATUS,Z
RETURN

MOVLW .23
MOVWF HORAS
RETURN

ATUALIZA_HORARIO
MOVF HORAS,W
CALL CONV_BIN8_DEC

BCF RS ;display setado para comando
MOVLW 0XC8 ;dado será atualizado a partir do endereço 0xC3
CALL ATUALIZA ;atualiza LCD
Aula de Microcontrolador
Página 42
BSF RS ;display setado para dados

MOVF CONV_DEZ_HORAS,W
ADDLW 0X30
CALL ATUALIZA

MOVF CONV_UNI_HORAS,W ;resultado da conversão binário para
;decimal
ADDLW 0X30 ;SOMA 0x30 ao resultado para enviar
;o dado
CALL ATUALIZA

MOVLW ':' ;CA
CALL ATUALIZA

MOVF DEZ_MIN,W
ADDLW 0X30
CALL ATUALIZA

MOVF UNI_MIN,W
ADDLW 0X30
CALL ATUALIZA

MOVLW ':' ;CA
CALL ATUALIZA

MOVF DEZ_SEG,W ;resultado da conversão binário para decimal
ADDLW 0X30 ;SOMA 0x30 ao resultado para enviar o dado
;em código ASCII para o LCD
CALL ATUALIZA ;atualiza LCD

MOVF UNI_SEG,W
ADDLW 0X30
CALL ATUALIZA

RETURN

CONV_BIN8_DEC
MOVWF AUX
CLRF CONV_UNI_HORAS
CLRF CONV_DEZ_HORAS
BIN8_DEC_1
MOVLW .10
SUBWF AUX,W
BTFSS STATUS,C
GOTO BIN8_DEC_2
MOVWF AUX
Aula de Microcontrolador
Página 43
INCF CONV_DEZ_HORAS,F
GOTO BIN8_DEC_1
BIN8_DEC_2
MOVF AUX,W
MOVWF CONV_UNI_HORAS
RETURN

;atraso para garantir que uma operação do LCD termine
DELAY_LCD
MOVWF TEMPO1
DELAY_ATU
MOVLW .250
MOVWF TEMPO0
DELAY_ATU1
CLRWDT
DECFSZ TEMPO0,F
GOTO DELAY_ATU1

DECFSZ TEMPO1,F
GOTO DELAY_ATU

RETURN

;atualiza dado ou comando no LCD
ATUALIZA
BSF ENABLE ;habilita LCD para pegar info no barramento
MOVWF DISP_LCD_TEMP ;guarda informação atual no temporário
MOVLW 0X0F ;zera o barramento de 4 vias (DB4 à DB7)
ANDWF DISP_LCD,F ;atualiza LCD: zera o barramento
MOVLW 0XF0 ;máscara para informação de DB4 à DB7

ANDWF DISP_LCD_TEMP,W ;envia parte alta primeiro
IORWF DISP_LCD,F ;atualiza LCD
BCF ENABLE ;desabilita LCD
NOP ;atraso
BSF ENABLE ;habilita LCD para pegar info no barramento
SWAPF DISP_LCD_TEMP,F ;inverte parte alta com parte baixa
MOVLW 0X0F ;zera o barramento de 4 vias (DB4 à DB7)

ANDWF DISP_LCD,F ;atualiza LCD: zera o barramento
MOVLW 0XF0 ;máscara para informação de DB4 à DB7

ANDWF DISP_LCD_TEMP,W ;envia parte baixa da informação original
IORWF DISP_LCD,F ;atualiza LCD
BCF ENABLE ;desabilita LCD

MOVLW .1
Aula de Microcontrolador
Página 44
CALL DELAY_LCD ;garante o término da operação no LCD
RETURN

CONFIG
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE

BANK1
MOVLW B'11111110'
MOVWF TRISA

MOVLW B'11111111'
MOVWF TRISB

MOVLW B'11111111'
MOVWF TRISC

MOVLW B'00001111'
MOVWF TRISD

MOVLW B'00000100'
MOVWF TRISE

MOVLW B'11011011'
MOVWF OPTION_REG

MOVLW B'01000000'
MOVWF INTCON ;interrupções de periféricos serão tratadas

MOVLW B'00000001' ;liga interrupção por TMR1
MOVWF PIE1

MOVLW B'00000111' ;PORTA e PORTE configs como I/O's digitais
MOVWF ADCON1 ;conversor A-D desligado

BANK0

MOVLW B'00110000'
MOVWF T1CON

BTFSC STATUS,NOT_TO ;aguarda estouro do watchdog timer
GOTO $

MOVLW 0X20 ;limpa memório RAM disponível
Aula de Microcontrolador
Página 45
MOVWF FSR

LIMPA_RAM
CLRF INDF
INCF FSR,F
MOVF FSR,W
XORLW 0X80
BTFSS STATUS,Z
GOTO LIMPA_RAM

MOVLW .2
MOVWF DIVISOR_TMR1 ;atualiza variável aux para contagem de 1 segundo

BSF INTCON,GIE ;habilita chave geral da interrupção
BCF FLAG_TMR1 ;apaga LED, pois o TMR1 não foi ainda habilitado

INICIALIZACAO_DISPLAY

BCF RS ;display setado para comandos

MOVLW 0X30 ;inicialização do display
CALL ATUALIZA

MOVLW .3
CALL DELAY_LCD ;delay exigido pelo display

MOVLW 0X30 ;inicialização do display
CALL ATUALIZA

MOVLW 0X30 ;inicialização do display
CALL ATUALIZA

MOVLW 0X02 ;zera o contador de caracteres e retorna à posição 0x80
CALL ATUALIZA

MOVLW 0X28 ;trabalhando com 4 vias de dados
CALL ATUALIZA

MOVLW B'00000001' ;limpa todo o display
CALL ATUALIZA

MOVLW .1 ;delay de 1ms
CALL DELAY_LCD

MOVLW B'00001100' ;liga o display sem cursor
CALL ATUALIZA

Aula de Microcontrolador
Página 46
MOVLW B'00000110' ;incrementa automático à direita
CALL ATUALIZA

MOVLW 0X81 ;endereço do LCD
CALL ATUALIZA

BSF RS ;display setado para dados

MOVLW 'R' ;81
CALL ATUALIZA
MOVLW 'E' ;82
CALL ATUALIZA
MOVLW 'L' ;83
CALL ATUALIZA
MOVLW 'O' ;84
CALL ATUALIZA
MOVLW 'G' ;85
CALL ATUALIZA
MOVLW 'I' ;86
CALL ATUALIZA
MOVLW 'O' ;87
CALL ATUALIZA
MOVLW ' ' ;88
CALL ATUALIZA
MOVLW ' ' ;89
CALL ATUALIZA
MOVLW ' ' ;8A
CALL ATUALIZA
MOVLW ' ' ;8B
CALL ATUALIZA
MOVLW ' ' ;8C
CALL ATUALIZA
MOVLW ' ' ;8D
CALL ATUALIZA
MOVLW ' ' ;8E
CALL ATUALIZA
MOVLW ' ' ;8F
CALL ATUALIZA

BCF RS
MOVLW 0XC8 ;endereço do LCD
CALL ATUALIZA

BSF RS ;display setado para dados

MOVLW '0' ;C8
CALL ATUALIZA
Aula de Microcontrolador
Página 47
MOVLW '0' ;C9
CALL ATUALIZA
MOVLW ':' ;CA
CALL ATUALIZA
MOVLW '0' ;CB
CALL ATUALIZA
MOVLW '0' ;CC
CALL ATUALIZA
MOVLW ':' ;CD
CALL ATUALIZA
MOVLW '0' ;CE
CALL ATUALIZA
MOVLW '0' ;CF
CALL ATUALIZA

VARRE ;testa botões
CLRWDT ;limpa o WDT para o programa não ser
;reinicializado em condições normais

BTFSS BT_UP
GOTO TRATA_BT_UP ;botão para incrementar valor dos displays

BTFSS BT_DOWN
GOTO TRATA_BT_DOWN ;botão para decrementar valor dos displays

BTFSS BT_ZERO ;botão para zerar relógio
GOTO TRATA_BT_ZERO

BTFSS BT_LIGA_DESLIGA ;liga/desliga Relógio
GOTO TRATA_BT_LIGA_DES

MOVLW FILTRO_TECLA ;deboucing
MOVWF FILTRO_BOTOES

MOVLW .40
MOVWF TEMPO_TURBO

GOTO VARRE

TRATA_BT_UP
DECFSZ FILTRO_BOTOES,F
GOTO VARRE

DECFSZ TEMPO_TURBO,F
GOTO VARRE

MOVLW TURBO_TECLA ;diminui a velocidade do incremento
Aula de Microcontrolador
Página 48
MOVWF TEMPO_TURBO ;BT_UP permanecer pressionado

CALL INCREMENTA_TIMER

CALL ATUALIZA_HORARIO

GOTO VARRE

TRATA_BT_DOWN
DECFSZ FILTRO_BOTOES,F
GOTO VARRE

DECFSZ TEMPO_TURBO,F
GOTO VARRE

MOVLW TURBO_TECLA ;diminui a velocidade do decremento
MOVWF TEMPO_TURBO ;BT_DOWN permanecer pressionado

CALL DECREMENTA_TIMER

CALL ATUALIZA_HORARIO

GOTO VARRE

TRATA_BT_LIGA_DES
DECFSZ FILTRO_BOTOES,F
GOTO VARRE

DECFSZ TEMPO_TURBO,F
GOTO VARRE

MOVLW TURBO_TECLA
MOVWF TEMPO_TURBO

BTFSS FLAG_TMR1 ;ESTADO_TIMER=1?
GOTO LIGA_TMR1 ;NÃO

DESLIGA_TMR1 ;SIM
BCF FLAG_TMR1 ;desliga variável referente ao TIMER
BCF T1CON,TMR1ON ;desabilita a contagem
GOTO VARRE ;volta para varredura de botões.

LIGA_TMR1
BSF FLAG_TMR1 ;liga variável referente ao TIMER

MOVLW TMR1_HIGH ;atualiza valores do TMR1
MOVWF TMR1H
Aula de Microcontrolador
Página 49
MOVLW TMR1_LOW
MOVWF TMR1L

MOVLW .2 ;atualiza variável auxiliar para contagem de
;1 segundo.
MOVWF DIVISOR_TMR1

BSF T1CON,TMR1ON ;habilita a contagem

GOTO VARRE


TRATA_BT_ZERO
DECFSZ FILTRO_BOTOES,F
GOTO VARRE

DECFSZ TEMPO_TURBO,F
GOTO VARRE

MOVLW TURBO_TECLA
MOVWF TEMPO_TURBO

CLRF UNI_SEG
CLRF DEZ_SEG
CLRF UNI_MIN
CLRF DEZ_MIN
CLRF HORAS

CALL ATUALIZA_HORARIO

GOTO VARRE

END



Aula 3
Conversor Analógico Digital

Tópicos:

• CAD (Conversor A/D)
• Programação – Tabela
• Terceiro Programa: Sensor de Temperatura


Aula de Microcontrolador
Página 50
CAD (Conversor A/D)


No mundo exterior podemos dizer que tudo está na forma analógica, ou seja,
utilizamos a base 10 (decimal) para efetuarmos todos os cálculos matemáticos do dia-a-
dia, isto é linguagem cotidiana. Para que o “mundo” dos microprocessadores ou
microcontroladores possam nos ajudar a resolver problemas, tal como cálculos é
necessário converter sinais analógicos em sinais digitais, ou seja, linguagem de máquina.

O Conversor Analógico/Digital tem a função de pegar este nível de tensão, codificá-
lo em base binária, e após um certo tempo de processamento, decodificá-lo em decimal
para podermos entendê-lo.

Nesta seção, referiremos ao módulo A/D do 16F877A, características e
registradores utilizados, serão discutidos em detalhe.

As fórmulas mais importantes para este sistema de conversão são mostradas
abaixo.

Resolução = Vref
2
n

V
entrada
= Σ ( Bm 2
(m)
Vref )
2
n


n = número de bits do conversor
Vref = tensão de referência
m = posição do bit (0 a 9)
Bm = valor do bit m, 0 ou 1.

Um ponto importante, diz respeito à velocidade e, conseqüentemente, aos tempos
de amostragem para a conversão A/D. Abaixo mostramos a tabela com os tempos e
etapas do sistema de conversão A/D.

Código Nome Tempo
A Adequação do Capacitor 40µs
B Desligamento do Capacitor 100ns
C Conversão 12T
AD
D Religamento do Capacitor 2T
AD
E Nova adequação do Capacitor 40µs

T
AD
= tempo de conversão de 1 bit.

Para que o sistema de conversão funcione corretamente, um clock deve ser
aplicado a ele. Cada período deste clock será chamado de T
AD
. Este clock é escolhido por
software conforme configuração dos bits ADCS1 e ADCS0 do registrador ADCON0; isto
será detalhado mais adiante.


Aula de Microcontrolador
Página 51
Em PIC’s de 28 pinos (por exemplo: 16F873), temos 5 deles reservados para o
módulo A/D, são eles: RA0/AN0, RA1/AN1, RA2/AN2, RA3/AN3 e RA5/AN4. No
P16F877A (40 pinos) temos 8 pinos dedicados ao módulo A/D, quais sejam: 2, 3, 4, 5, 7,
8, 9 e 10. Estes três últimos se referem ao PORTE (bits 0, 1 e 2), os 5 primeiros são os
mesmos do PIC de 28 pinos citado.
O módulo A/D possui 4 registradores: ADRESH, ADRESL, ADCON0 e ADCON1.

Os registradores: ADRESH e ADRESL contêm o resultado dos 10 bits da
conversão AD. Com isto, verificamos que 6 bits destes registradores serão descartados.
Quais bits serão descartados, pode ser escolhido através do registrador ADCON1,ADFM,
o qual será mostrado na seqüência. A figura abaixo mostra as duas maneiras de
configurar os 10 bits que contém o resultado da conversão AD: justificado pela direita ou
justificado pela esquerda.



REGISTRADOR ADCON0
7 6 5 4 3 2 1 0
R/W R/W R/W R/W R/W R/W U R/W
ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE\ - ADON

ADCS1:ADCS0 – Bit de seleção do clock de conversão A/D

ADCS1 / 0 Clock
00 F
OSC
/2
01 F
OSC
/8
10 F
OSC
/32
11 F
RC
– oscilador RC
interno (Sleep)

Aula de Microcontrolador
Página 52
CHS2:CHS0 – Bit de seleção do Canal Analógico

CHS2/0 Canal PORT
000 0 RA0/AN0 (pino 2)
001 1 RA1/AN1 (pino 3)
010 2 RA2/AN2 (pino 4)
011 3 RA3/AN3 (pino 5)
100 4 RA5/AN4 (pino 7)
101 5 RE0/AN5 (pino 8)
110 6 RE1/AN6 (pino 9)
111 7 RE2/AN7 (pino 10)


GO/DONE\ - Bit de Status da Conversão A/D
1: Conversão A/D em andamento
0: Conversão A/D terminada/parada.

ADON – Bit de ligação do Módulo
1: Módulo de conversão AD está operando
0: Módulo de conversão AD está desligado (não consome corrente).


REGISTRADOR ADCON1
7 6 5 4 3 2 1 0
R/W U U U R/W R/W R/W R/W
ADFM - - - PCFG3 PCFG2 PCFG1 PCFG0

ADFM – Bit de seleção do formato do resultado de AD
1: Justificado pela direita (os 6 bits mais significativos de ADRESH serão
descartados).
0: Justificado pela esquerda (os 6 bits menos significativos de ADRESL serão
descartados).

PCFG3:PCFG0 – Bits de controle da configuração dos Pinos do Módulo AD

Aula de Microcontrolador
Página 53


Após termos verificado a configuração dos registradores referente ao módulo A/D,
vamos discutir um pouco seu funcionamento.
Como vimos o ADCON1 é o registrador responsável por configurar os pinos do
PORTA e do PORTE como entradas analógicas ou digitais. Os pinos dos PORT’s que são
escolhidos como entradas analógicas devem ter seu bit correspondente do TRIS
configurado como entrada.
Basicamente temos duas maneiras diferentes de operação do módulo A/D: com
interrupção ou com verificação do Bit 0 (GO/DONE\) do registrador ADCON0.
O modo de verificação do bit GO/DONE\ é muito mais simples, veja código de
exemplo abaixo:


LOOP
BSF ADCON0,GO
BTFSC ADCON0,GO
GOTO $-1
MOVF ADRESH,W
...
GOTO LOOP


Já no modo de funcionamento por interrupção (um pouco mais minucioso) devemos
proceder da seguinte forma:



Aula de Microcontrolador
Página 54
CONFIG
BCF STATUS,RP0 ;seleciona banco 0
MOVLW B’01000000’ ;chave geral para interrupção por periféricos
MOVWF INTCON
BSF STATUS,RP0 ;seleciona banco 1
MOVLW B’01000000’ ;habilita interrupção por término de conversão A/D
MOVWF PIE1 ;ADIE habilitado
BCF STATUS,RP0 ;seleciona banco 0
BSF INTCON,GIE ;liga chave geral para tratar interrupções
...


Após ocorrer a interrupção, o contador de programa (PCL) será apontado para o
endereço 0X04. No término do tratamento da interrupção, não podemos esquecer de
limpar o bit 6 (flag ADIF) do registrador PIR1.

O módulo A/D aceita ainda uma operação durante SLEEP (economia de energia),
mas a seleção de clock deve ser F
RC
interno, ou seja, os bits ADCS0 e ADCS1 do
ADCON0 devem estar configurados com nível 1 lógico. Uma observação importante é
válida aqui, se utilizarmos a instrução SLEEP com outra opção de clock (não RC), a
conversão será abortada, módulo A/D desligado, embora o bit ADON esteja setado.


Exemplo de código com SLEEP:


Config
...
MOVLW B’11000000’ ;configura clock F
RC
interno
MOVWF ADCON0
...

New_ad
BSF ADCON0,GO ;inicia nova conversão AD
SLEEP
MOVF ADRESH,W ;quando a conversão AD terminar, continuará daqui.
...
GOTO New_ad









Aula de Microcontrolador
Página 55
Programação – Tabela


ORG 0X300
RADIX DEC

TABELA_TEMPERATURA
MOVLW HIGH TABELA_TEMP
MOVWF PCLATH
MOVLW LOW TABELA_TEMP
ADDWF conv_bin_temp,W
BTFSC STATUS,C
INCF PCLATH,F
MOVWF PCL

TABELA_TEMP
DT 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;15
DT 004,004,004,004,004,004,004,004,004,004,004,004,004,004,004,004 ;31
DT 008,008,008,008,008,008,008,008,008,008,008,008,008,008,008,008 ;47
DT 012,012,012,012,012,012,012,012,012,012,012,012,012,012,012,012 ;63
DT 016,016,016,016,016,016,016,016,016,016,016,016,016,016,016,016 ;79
DT 020,020,020,020,020,020,020,020,020,020,020,020,020,020,020,020 ;95
DT 022,022,022,022,022,022,022,022,022,022,022,022,022,022,022,022 ;111
DT 024,024,024,024,024,024,024,024,024,024,024,024,024,024,024,024 ;127
DT 026,026,026,026,026,026,026,026,026,026,026,026,026,026,026,026 ;143
DT 028,028,028,028,028,028,028,028,028,028,028,028,028,028,028,028 ;159
DT 030,030,030,030,030,030,030,030,030,030,030,030,030,030,030,030 ;175
DT 031,031,031,031,031,031,031,031,031,031,031,031,031,031,031,031 ;191
DT 032,032,032,032,032,032,032,032,032,032,032,032,032,032,032,032 ;207
DT 033,033,033,033,033,033,033,033,033,033,033,033,033,033,033,033 ;223
DT 034,034,034,034,034,034,034,034,034,034,034,034,034,034,034,034 ;239
DT 035,035,035,035,035,035,035,035,035,035,035,035,035,035,035,035 ;255




Terceiro Programa: Sensor de Temperatura

#include<p16f877a.inc>
#include<multipli.asm> ; inclui MACROs

__CONFIG _CP_OFF & _CPD_OFF & _DEBUG_OFF & _LVP_OFF & _WRT_OFF
& _BODEN_OFF & _WDT_ON & _PWRTE_ON & _XT_OSC

ERRORLEVEL -302
ERRORLEVEL -305

Aula de Microcontrolador
Página 56
#DEFINE BANK1 BSF STATUS,RP0 ;definições de bancos
#DEFINE BANK0 BCF STATUS,RP0

#DEFINE DISP_LCD PORTD ;define LCD
#DEFINE RS PORTE,0
#DEFINE ENABLE PORTE,1

#DEFINE BT1 PORTB,0
#DEFINE BT2 PORTB,1
#DEFINE BT3 PORTB,2
#DEFINE BT4 PORTB,3

CBLOCK 0X20
PARTE_ALTA ;parte alta do resultado da multiplicação
PARTE_BAIXA ;parte baixa do resultado da multiplicação
conv_bin_temp ;resultado da conversão A/D
fator_multi ;tensão de referência, neste caso, foi de 5V.
TEMPO0 ;delay do LCD
TEMPO1 ;delay do LCD
AUX ;variável auxiliar usada na conv binário para decimal
MOSTRADOR_AV ;variável que será mostrada no LCD antes da vírgula
MOSTRADOR_DV ;variável que será mostrada no LCD depois da vírgula
DISP_LCD_TEMP ;variável temporária que conterá o valor do dado ou
;comando que será enviado ao LCD
AUX_DEC_DV
AUX_DEC_AV
TEMP_CELSIUS

ENDC

ORG 0x00
GOTO INICIO

;atraso para garantir que uma operação do LCD termine
DELAY_MS
MOVWF TEMPO1
MOVLW .250
MOVWF TEMPO0

CLRWDT
DECFSZ TEMPO0,F
GOTO $-2

DECFSZ TEMPO1,F
GOTO $-6

RETURN
Aula de Microcontrolador
Página 57

;atualiza dado ou comando no LCD
ATUALIZA
BSF ENABLE
MOVWF DISP_LCD_TEMP ;guarda informação atual no temporário
MOVLW 0X0F ;zera o barramento de 4 vias (DB4 à DB7)
ANDWF DISP_LCD,F ;atualiza LCD: zera o barramento
MOVLW 0XF0 ;máscara para informação de DB4 à DB7

ANDWF DISP_LCD_TEMP,W ;envia parte alta primeiro
IORWF DISP_LCD,F ;atualiza LCD
BCF ENABLE ;desabilita LCD
NOP ;atraso
BSF ENABLE ;habilita LCD para pegar info no barramento
SWAPF DISP_LCD_TEMP,F ;inverte para alta com parte baixa no temp
MOVLW 0X0F ;zera o barramento de 4 vias (DB4 à DB7)

ANDWF DISP_LCD,F ;atualiza LCD: zera o barramento
MOVLW 0XF0 ;máscara para informação de DB4 à DB7

ANDWF DISP_LCD_TEMP,W ;envia parte baixa da informação original
IORWF DISP_LCD,F ;atualiza LCD
BCF ENABLE ;desabilita LCD

MOVLW .1
CALL DELAY_MS ;garante o término da operação no LCD
RETURN

CONV_BIN8_DEC
MOVWF AUX
CLRF AUX_DEC_DV
CLRF AUX_DEC_AV
BIN8_DEC_1
MOVLW .10
SUBWF AUX,W
BTFSS STATUS,C
GOTO BIN8_DEC_2
MOVWF AUX
INCF AUX_DEC_AV,F
GOTO BIN8_DEC_1
BIN8_DEC_2
MOVF AUX,W
MOVWF AUX_DEC_DV
RETURN

MULTIPLICA8X8
CLRF PARTE_ALTA
Aula de Microcontrolador
Página 58
CLRF PARTE_BAIXA
MOVF fator_multi,W
BCF STATUS,C

MULT8 0
MULT8 1
MULT8 2
MULT8 3
MULT8 4
MULT8 5
MULT8 6
MULT8 7
RETURN

INICIO
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE

BANK1
MOVLW B'11111111'
MOVWF TRISA

MOVLW B'11101111'
MOVWF TRISB

MOVLW B'00000000'
MOVWF TRISC

MOVLW B'00001111'
MOVWF TRISD

MOVLW B'00000100'
MOVWF TRISE

MOVLW B'11011011'
MOVWF OPTION_REG

MOVLW B'00000000'
MOVWF INTCON ;interrupções não serão tratadas


MOVLW B'00000100' ;ADFM justificado à direita
MOVWF ADCON1 ;Canais analógicos 1, 2 e 4

Aula de Microcontrolador
Página 59
BANK0

MOVLW B'00001001'
MOVWF ADCON0

BTFSC STATUS,NOT_TO ;aguarda estouro do watchdog timer
GOTO $

MOVLW 0X20 ;limpa memório RAM disponível
MOVWF FSR

LIMPA_RAM
CLRF INDF
INCF FSR,F
MOVF FSR,W
XORLW 0X80
BTFSS STATUS,Z
GOTO LIMPA_RAM

INICIALIZACAO_DISPLAY

BCF RS ;display setado para comandos

MOVLW 0X30 ;inicialização do display
CALL ATUALIZA

MOVLW .3
CALL DELAY_MS ;delay exigido pelo display

MOVLW 0X30 ;inicialização do display
CALL ATUALIZA

MOVLW 0X30 ;inicialização do display
CALL ATUALIZA

MOVLW 0X02 ;zera o contador de caracteres e retorna à
;posição 0x80
CALL ATUALIZA

MOVLW 0X28 ;trabalhando com 4 vias de dados
CALL ATUALIZA

MOVLW B'00000001' ;limpa todo o display
CALL ATUALIZA

MOVLW .1 ;delay de 1ms
CALL DELAY_MS
Aula de Microcontrolador
Página 60

MOVLW B'00001100' ;liga o display sem cursor
CALL ATUALIZA

MOVLW B'00000110' ;incrementa automático à direita
CALL ATUALIZA

MOVLW 0X82 ;endereço do LCD
CALL ATUALIZA

BSF RS ;display setado para dados

MOVLW 'M' ;82
CALL ATUALIZA
MOVLW 'E' ;83
CALL ATUALIZA
MOVLW 'D' ;84
CALL ATUALIZA
MOVLW 'I' ;85
CALL ATUALIZA
MOVLW 'D' ;86
CALL ATUALIZA
MOVLW 'O' ;87
CALL ATUALIZA
MOVLW 'R' ;88
CALL ATUALIZA
MOVLW ' ' ;89
CALL ATUALIZA
MOVLW ' ' ;8A
CALL ATUALIZA
MOVLW 'D' ;8B
CALL ATUALIZA
MOVLW 'E' ;8C
CALL ATUALIZA


BCF RS
MOVLW 0XC2
CALL ATUALIZA
BSF RS

MOVLW 'T' ;C2
CALL ATUALIZA
MOVLW 'E' ;C3
CALL ATUALIZA
MOVLW 'M' ;C4
CALL ATUALIZA
Aula de Microcontrolador
Página 61
MOVLW 'P' ;C5
CALL ATUALIZA
MOVLW 'E' ;C6
CALL ATUALIZA
MOVLW 'R' ;C7
CALL ATUALIZA
MOVLW 'A' ;C8
CALL ATUALIZA
MOVLW 'T' ;C9
CALL ATUALIZA
MOVLW 'U' ;CA
CALL ATUALIZA
MOVLW 'R' ;CB
CALL ATUALIZA
MOVLW 'A' ;CC
CALL ATUALIZA

LOOP
CLRWDT ;limpa WDT
BSF ADCON0,GO ;inicia conversão
BTFSC ADCON0,GO
GOTO $-1

MOVF ADRESH,W ;resultado da conversão A/D
MOVWF conv_bin_temp ;variável temporária

MOVLW .50 ;tensão de referência de 5 Volts
MOVWF fator_multi

CALL MULTIPLICA8X8 ;executa multiplicação

DIV_256 ;macro de divisão por 256

CALL CONV_BIN8_DEC ;executa um ajuste decimal

MOVFW AUX_DEC_DV
MOVWF MOSTRADOR_DV
MOVFW AUX_DEC_AV
MOVWF MOSTRADOR_AV

CALL MOSTRA_TENSAO_LCD

CALL TABELA_TEMPERATURA

MOVWF TEMP_CELSIUS

CALL CONV_BIN8_DEC
Aula de Microcontrolador
Página 62

CALL MOSTRA_TEMP_LCD

GOTO LOOP

MOSTRA_TENSAO_LCD
BCF RS
MOVLW 0X80
CALL ATUALIZA
BSF RS

MOVLW ' ' ;0
CALL ATUALIZA
MOVLW 'T' ;1
CALL ATUALIZA
MOVLW 'E' ;2
CALL ATUALIZA
MOVLW 'N' ;3
CALL ATUALIZA
MOVLW 'S' ;4
CALL ATUALIZA
MOVLW 'A' ;5
CALL ATUALIZA
MOVLW '0' ;6
CALL ATUALIZA
MOVLW ' ' ;7
CALL ATUALIZA
MOVLW '=' ;8
CALL ATUALIZA
MOVLW ' ' ;9
CALL ATUALIZA

MOVF MOSTRADOR_AV,W ;resultado da conv binário para decimal
ADDLW 0X30 ;SOMA 0x30 ao resultado
CALL ATUALIZA ;em código ASCII para o LCD
;atualiza LCD

MOVLW ',' ;código ASCII da vírgula
CALL ATUALIZA

MOVF MOSTRADOR_DV,W ;resultado da conv binário para decimal
ADDLW 0X30 ;SOMA 0x30 ao resultado.
CALL ATUALIZA

MOVLW ' '
CALL ATUALIZA
MOVLW 'V'
Aula de Microcontrolador
Página 63
CALL ATUALIZA
MOVLW ' '
CALL ATUALIZA

RETURN

MOSTRA_TEMP_LCD
BCF RS ;display setado para comando
MOVLW 0XC0
CALL ATUALIZA
BSF RS

MOVLW 'T' ;0
CALL ATUALIZA
MOVLW 'E' ;1
CALL ATUALIZA
MOVLW 'M' ;2
CALL ATUALIZA
MOVLW 'P' ;3
CALL ATUALIZA
MOVLW '(' ;4
CALL ATUALIZA
MOVLW 'o' ;5
CALL ATUALIZA
MOVLW 'C' ;6
CALL ATUALIZA
MOVLW ')' ;7
CALL ATUALIZA
MOVLW '=' ;8
CALL ATUALIZA
MOVLW ' ' ;9
CALL ATUALIZA

MOVF AUX_DEC_AV,W ;resultado da conversão binário para decimal
ADDLW 0X30 ;SOMA 0x30 ao resultado para enviar o dado
CALL ATUALIZA ;em código ASCII para o LCD
;atualiza LCD

MOVF AUX_DEC_DV,W ;resultado da conversão binário para decimal
ADDLW 0X30 ;SOMA 0x30 ao resultado para enviar o dado
CALL ATUALIZA

MOVLW ' ' ;código ASCII da vírgula
CALL ATUALIZA
MOVLW 'o'
CALL ATUALIZA
MOVLW 'C'
Aula de Microcontrolador
Página 64
CALL ATUALIZA
MOVLW ' '
CALL ATUALIZA

RETURN

ORG 0X300
RADIX DEC

TABELA_TEMPERATURA
MOVLW HIGH TABELA_TEMP
MOVWF PCLATH
MOVLW LOW TABELA_TEMP
ADDWF conv_bin_temp,W
BTFSC STATUS,C
INCF PCLATH,F
MOVWF PCL

TABELA_TEMP
DT 000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000 ;15
DT 004,004,004,004,004,004,004,004,004,004,004,004,004,004,004,004 ;31
DT 008,008,008,008,008,008,008,008,008,008,008,008,008,008,008,008 ;47
DT 012,012,012,012,012,012,012,012,012,012,012,012,012,012,012,012 ;63
DT 016,016,016,016,016,016,016,016,016,016,016,016,016,016,016,016 ;79
DT 020,020,020,020,020,020,020,020,020,020,020,020,020,020,020,020 ; 95
DT 022,022,022,022,022,022,022,022,022,022,022,022,022,022,022,022 ;111
DT 024,024,024,024,024,024,024,024,024,024,024,024,024,024,024,024 ;127
DT 026,026,026,026,026,026,026,026,026,026,026,026,026,026,026,026 ;143
DT 028,028,028,028,028,028,028,028,028,028,028,028,028,028,028,028 ;159
DT 030,030,030,030,030,030,030,030,030,030,030,030,030,030,030,030 ;175
DT 031,031,031,031,031,031,031,031,031,031,031,031,031,031,031,031 ;191
DT 032,032,032,032,032,032,032,032,032,032,032,032,032,032,032,032 ;207
DT 033,033,033,033,033,033,033,033,033,033,033,033,033,033,033,033 ;223
DT 034,034,034,034,034,034,034,034,034,034,034,034,034,034,034,034 ;239
DT 035,035,035,035,035,035,035,035,035,035,035,035,035,035,035,035 ;255

END