Transcript
ESCOLA TÉCNICA ESTADUAL GETÚLIO VARGAS
PROFESSOR: MILTON BARREIRO JUNIOR
Microcontrolador 8051 – Teoria e Prática
São Paulo
2006
ESCOLA TÉCNICA ESTADUAL GETÚLIO VARGAS
PROFESSOR: MILTON BARREIRO JUNIOR
Microcontrolador 8051 – Teoria e Prática
São Paulo
2006
SUMÁRIO
1 –
INTRODUÇÃO..................................................................
......................... 1
2 – ARQUITETURA BÁSICA DE UM MICROCONTROLADOR GENÉRICO.. 2
3 – A FAMÍLIA
8051........................................................................
................. 3
3.1 Organização de
Memória................................................................ 4
3.2 Memória de
Programa....................................................................
. 6
3.3 Memória de
Dados.......................................................................
... 8
3.4 Conjunto de Instruções da Família
8051....................................... 10
3.5 Registrador da palavra de controle (Program Status
Word)......... 10
3.6 Modos de
Endereçamento..........................................................
.. 11
3.7 Instruções
Aritméticas............................................................
....... 12
3.8 Instruções
Lógicas................................................................
........ 14
3.9 Transferência de Dados Interna e
Externa................................... 15
3.10 Instruções
Booleanas..................................................................
17
3.11 Instruções de
Salto..................................................................
... 18
3.12 Oscilador
Interno................................................................
......... 20
3.13 Estrutura de
Interrupções...........................................................
. 21
4 – DESCRIÇÃO DO
HARDWARE................................................................ 24
4.1 Registradores de função especial
(SFR)...................................... 24
4.2 Acumulador
(ACC)..................................................................
....... 25
4.3 Registrador B
(B)....................................................................
........ 25
4.4 Registrador da palavra de controle
(PSW).................................... 25
4.5 Stack Pointer (SP) e Data Pointer
(DPTR)..................................... 26
4.6 Buffer Serial
(SBUF).................................................................
...... 26
4.7 Port's de I/O (P0, P1, P2,
P3)........................................................ 28
4.8 Registradores de Timer e de
Controle........................................... 29
4.9 Estrutura e operação dos ports de
I/O........................................... 32
4.10 Acesso à memória
externa.......................................................... 35
4.11 Temporizadores e
Contadores..................................................... 35
4.12 Modos de
operação...............................................................
...... 36
4.13 Interface
Serial.................................................................
............ 38
4.14 Modos de
Operação...............................................................
...... 38
4. 15 Registrador de
Controle..............................................................
43
4.16 Baud
Rates..................................................................
................. 43
4.17
Interrupções...........................................................
...................... 44
4.18 Estrutura de
prioridades............................................................
... 46
4.19 Interrupções
externas...............................................................
... 46
4.20 Circuitos de
Controle...............................................................
..... 47
4.21
Reset..................................................................
.......................... 47
4.22
Clock..................................................................
.......................... 48
4.23 Operação passo a
passo............................................................. 49
4.24 Descrição da
pinagem................................................................
. 50
5 – PROGRAMAÇÃO E
SIMULAÇÃO............................................................ 52
5.1 "Compilação" E
"Linkagem"............................................................ 52
5.2 Diretivas (Ou Pseudo-
Instruções).................................................. 53
5.3 Uso Do Compilador E Do Linker (Passo A
Passo)........................ 54
5.4 Simulador dos Microcontroladores da família
8051....................... 55
5.5 Operação básica do
simulador...................................................... 56
6 – TABELA DE INSTRUÇÕES
COMPLETA................................................. 58
7 – ESQUEMA DA CPU MÍNIMA PARA TESTE E CARREGAMENTO DE
PROGRAMA....................................................................
.......................................... 70
8 – PROGRAMA TESTE DO SISTEMA
MÍNIMO........................................... 71
9 – REFERÊNCIAS
BIBLIOGRÁFICAS......................................................... 72
APÊNDICE
A...........................................................................
.................................. 73
APÊNDICE
B...........................................................................
.................................. 80
ANEXO
1...........................................................................
........................................ 84
1 – Introdução
Podemos considerar os microcontroladores, como sendo uma CPU dedicada
e incorporada em um só chip, ou seja, todos os periféricos que nos
microprocessadores se encontravam em chips independentes, assim como
memórias, temporizadores, portas de comunicação serial, dispositivos de
entrada/saída, estão presentes em um único componente.
Isso torna o projeto mais compacto, mais dinâmico e com o custo final
reduzido, devido aos dispositivos integrados em um só chip.
O chip a ser apresentado nessa apostila será o microcontrolador da
família 8051, o qual será estudado com mais detalhes nos capítulos a
seguir.
2 – Arquitetura básica de um microcontrolador genérico
Um microcontrolador genérico é composto pelos seguintes blocos:
Unidade Central de Processamento (CPU);
Memória de Programa (ROM ou EPROM);
Memória de dados (RAM);
Linhas de I/O (PORT's);
Controle de interrupções;
Gerador de clock;
Temporizadores (Timer's) e Contadores (counter's).
É representada na figura abaixo constituição clássica de um
microcontrolador contendo os blocos citados e suas respectivas
interligações.
As diferenças básicas entre os diversos tipos de microcontroladores
disponíveis no mercado são relacionadas à capacidade e tipos de memórias,
na quantidade de port's disponíveis, velocidade de operação, e alguns
recursos específicos como por exemplo, portas seriais, maior número de
contadores, opção de baixo consumo, entre outros.
Existem também, os componentes chamados derivativos que, como o
próprio nome diz, são microcontroladores derivados dos tipos mais comuns
(8048 e 8051), ou seja, a célula básica é o microcontrolador e este é
acrescido de outros componentes de acordo com as necessidades.
3 – A Família 8051
Quando temos vários microcontroladores utilizando uma mesma célula,
chamamos esse conjunto de componentes de família. Desta forma temos várias
famílias como, por exemplo, a família do 8048, do 8051, do 8096, entre
outras.
Vamos tratar aqui da família do 8051, que será utilizado em nossas
aplicações. A tabela abaixo descreve os principais componentes dessa
família:
"Nome "Versão"Versão"Bytes "Bytes "Timers"Tipo " "
"do "sem "EPROM "de "de "16 "de " "
"Chip "ROM " "ROM "RAM "Bits "Circui" "
" " " " " " "to " "
CY – (PSW7): Carry flag, indica "vai um" nas operações
aritméticas.
AC – (PSW6): Auxiliary carry flag, auxilia nas operações de
adição.
F0 – (PSW5): Flag de uso geral.
RS1 – (PSW4): Seleção do banco de registradores.
RS0 – (PSW3): Seleção do banco de registradores.
OV – (PSW2): Overflow em operações aritméticas.
- – (PSW1): Flag definível pelo usuário.
P – (PSW0): Flag de paridade
O bit de carry, entre outras funções serve como "vai um" em operações
aritméticas, e também como acumulador para um número de operação booleana.
Os bits RS0 e RS1 são utilizados para selecionar um entre quatro bancos de
registradores, disponíveis nos primeiros 128 bytes de RAM. O bit de
paridade indica a quantidade de bits em um no acumulador: se P=1, o
acumulador contém um número ímpar de uns; se P=0, o número de uns no
acumulador é par. Dois bits do PSW estão disponíveis e podem ser
utilizados como flags de uso geral. O PSW encontra-se localizado na área
denominada SFR, no endereço D0H.
3.6 – Modos de endereçamento
Podemos ter seis modos distintos de endereçamento no 8051. Estes
modos são adequados às operações de controle.
Endereçamento direto: Neste modo, o operando é especificado por 8 bits
de endereço na instrução. Somente a RAM interna e os SFR's podem ser
acessados diretamente.
Endereçamento indireto: No modo indireto, a instrução especifica um
registrador que contém o endereço do operando. Ambas as memórias,
interna e externa podem ser acessadas desta forma. O registrador de
endereço, para operações de 8 bits, pode ser R0 ou R1, ou ainda o
Stack Pointer. Endereços de 16 bits podem ser acessados somente pelo
Data Pointer.
Instruções de registrador: Os bancos de registradores contêm os
registradores de R0 até R7, que podem ser acessados por certas
instruções que levam a especificação do registrador junto com o opcode
da instrução. As instruções que acessam os registradores dessa forma
são eficientes, pois eliminam o byte de endereço. Quando a instrução
é executada, um dos oito registradores do banco selecionado é acessado
e a seleção do banco é feita por dois bits (RS0 e RS1) no PSW.
Instruções de registrador específico: Algumas instruções são
especificadas para certos registradores, por exemplo, as instruções
que operam com acumulador ou Data Pointer não necessitam um byte de
endereço para apontá-las, pois o próprio opcode faz isso.
Constantes imediatas: Podemos carregar um registrador com uma
constante, diretamente por um simples comando, como por exemplo, mov
A, #100, que coloca no acumulador o valor 100 (decimal).
Endereçamento indexado: Somente a memória de programa (ROM) pode ser
acessada desta forma e somente pode ser lida. Este modo de
endereçamento é destinado à leitura de tabelas. Um registrador de 16
bits (DPTR ou PC) indica o endereço de base da tabela e o acumulador é
carregado com o valor da tabela.
3.7 – Instruções aritméticas
O conjunto de instruções aritméticas é listado na tabela a seguir. A
tabela indica o modo de endereçamento que pode ser utilizado com cada
instrução, para acessar o byte operando. Por exemplo, a instrução Add A,
; pode ser escrita como:
"Add A, 7FH "(endereçamento direto) "
"Add A, @R0 "(endereçamento indireto) "
"Add A, R7 "(endereçamento por "
" "registrador) "
"Add A, #127 "(constante imediata) "
"Mnemônico "Operação "Modo de "Tempo de "
" " "Endereçamento "Execução "
"ADD A, "A = A + "Dir / Ind / Reg"1 "
" " "/ Imm " "
"ADDC A, "A = A + + C "Dir / Ind / Reg"1 "
" " "/ Imm " "
"SUBB A, "A = A - - C "Dir / Ind / Reg"1 "
" " "/ Imm " "
"INC A "A = A + 1 "Acumulador "1 "
"INC " = + 1 "Dir / Ind / Reg"1 "
"INC DPTR "DPTR = DPTR + 1 "Data Pointer "2 "
"DEC A "A = A - 1 "Acumulador "1 "
"DEC " = - 1 "Dir / Ind / Reg"1 "
"MUL AB "B e A = B x A "Acumulador e B "4 "
"DIV AB "A = INT [A/B] "Acumulador e B "4 "
" "B = MOD [A/B] " " "
"DA A "Ajuste decimal "Acumulador "1 "
Os tempos de execução indicados consideram um clock de 12MHz. Todas
as instruções aritméticas são executadas num tempo de 1(s com exceção da
instrução INC DPTR que consome 2(s, e as instruções de multiplicação e
divisão que são efetuadas em 4(s.
Perceba que qualquer byte no espaço de memória interno pode ser
incrementado ou decrementado sem o uso do acumulador. Inclusive o
registrador de 16 bits DPTR pode ser incrementado desta forma. A instrução
MUL AB opera com os registradores A e B e põe o resultado (16 bits) nos
registradores B (byte high) e A (byte low) concatenados. A instrução DIV
AB divide A por B e coloca o quociente (resultado da divisão inteiro em 8
bits) no acumulador e o resto (8 bits) no registrador B.
Devido às suas características, a operação de divisão é mais utilizada
em conversões de radicais e operações de deslocamento programáveis, do que
na divisão aritmética propriamente dita.
A instrução de ajuste decimal DA A é utilizada na aritmética BCD,
quando utilizamos esta aritmética, as operações ADD e ADDC devem,
obrigatoriamente, ser seguidas por uma operação de ajuste decimal, para que
os resultados continuem em BCD. Note que o ajuste decimal não converte o
número binário em BCD, mas corrige os erros de aproximação ocorridos nos
registradores.
3.8 – Instruções lógicas
A tabela a seguir mostra uma lista de instruções lógicas do 8051.
" " "Modos de "Tempo de "
"Mnemônico "Operação "Operação "Execução "
"ANL A, "A = A and "Dir / Ind / Reg /"1 "
" " "Imm " "
"ANL , A " = and A "Direto "1 "
"ANL , " = and "Direto "2 "
"#DATA "#DATA " " "
"ORL A, "A = A or "Dir / Ind / Reg /"1 "
" " "Imm " "
"ORL , A " = or A "Direto "1 "
"ORL , " = or "Direto "2 "
"#DATA "#DATA " " "
"XRL A, "A = A xor "Dir / Ind / Reg /"1 "
" " "Imm " "
"XRL , A " = xor A "Direto "1 "
"XRL , " = xor "Direto "2 "
"#DATA "#DATA " " "
"CLR A "A = 00H "Acumulador "1 "
"CPL A "A = not A "Acumulador "1 "
"RL A "Roda Acum. à esquerda "Acumulador "1 "
" "1 bit " " "
"RLC A "Roda Acum. à esquerda "Acumulador "1 "
" "c/ carry " " "
"RR A "Roda Acum. à direita 1"Acumulador "1 "
" "bit " " "
"RRC A "Roda Acum. à direita "Acumulador "1 "
" "c/ carry " " "
"SWAP A "Swap nibbles in A "Acumulador "1 "
Todos os modos de endereçamento podem ser utilizados e as instruções
são executadas em tempo de 1 a 2 (s. Estas instruções podem ser executadas
em qualquer byte de memória interna ou na área de SFR. O conjunto de
instruções permite que sejam realizadas todas as operações lógicas e ainda
a instrução SWAP A, que inverte os nibbles alto e baixo do acumulador,
operação útil quando operamos com o código BCD.
3.9 – Transferência de dados interna e externa
A tabela a seguir mostra as instruções disponíveis para movimentação
de dados entre os espaços de memória interna.
"Mnemônico "Operação "Modo de "Tempo de "
" " "Endereçamento "Execução "
"MOV A, "A = "Dir / Ind / Reg /"1 "
" " "Imm " "
"MOV , A " = A "Dir / Ind / Reg "1 "
"MOV , " = "Dir / Ind / Reg /"2 "
" " "Imm " "
"MOV DPTR, #DATA"DPTR = 16 bit Const "Constante "2 "
" " "imediata " "
"PUSH "INC SP: MOV @SP, "Direto "2 "
" " " " "
"POP "MOV , @SP: DEC "Direto "2 "
" "SP " " "
"XCH A, "Acc e trocam "Dir / Ind / Reg "1 "
" "os dados " " "
"XCHD A, @RI "Acc e trocam "Indireto "1 "
" "os nibbles " " "
" "baixos " " "
A instrução MOV , permite que os dados sejam
transferidos entre quaisquer dos registradores da RAM interna ou dos SFR,
sem o uso do acumulador, lembrando que os 128 bytes superiores podem ser
acessados apenas por endereçamento indireto e os SFR apenas por
endereçamento direto.
A área de stack reside na própria RAM interna e as instruções de PUSH
primeiro incrementam o stack pointer, então copia o byte no stack. As
instruções de PUSH e POP usam apenas o endereçamento direto para
identificar o byte que está sendo manipulado, enquanto que o stack é
acessado por endereçamento indireto através do registrador SP. Isto
significa que o stack vai para os 128 bytes altos (se existirem) mas não
para a área de SFR. Nos dispositivos onde não está implementado a área
alta, os bytes "PUSHed" são perdidos e os bytes "POPed" são indeterminados.
As transferências de dados incluem movimentações em 16 bits, que podem
ser utilizadas para inicializar o Data Pointer (DPTR), para o uso de
tabelas na memória de programa, ou para acesso à memória de dados externa.
A instrução XCH A, resulta na troca dos dados entre o
acumulador e o byte endereçado. A instrução XCHD A, @RI é similar, com a
diferença que apenas os nibbles baixos estão envolvidos na operação. Esta
instrução facilita a manipulação de dados, de forma a economizar instruções
nos programas.
A memória externa pode ser acessada por endereçamento indireto,
utilizando 8 ou 16 bits de endereço. A escolha recai no uso de
endereçamento de um byte, através de @Ri, onde Ri pode ser R0 ou R1 do
banco de registradores selecionado, ou um endereço de 2 bytes (16 bits)
colocado no Data Pointer (DPTR). A desvantagem do uso do endereçamento de
16 bits está no fato de que, se utilizarmos um pequeno espaço de memória,
ainda assim o port 2 será inteiramente indisponibilizado para uso. No
endereçamento de 8 bits, sacrificamos apenas algumas linhas do port 2.
A tabela abaixo indica as instruções de movimentação de dados em
memória externa. Todas as instruções são executadas em 2(s, com um clock
de 12MHz.
"Largura do Endereço "Mnemônico "Operação "
"8 Bits "MOVX A, @Ri "Lê RAM Externa (Ri) "
"8 Bits "MOVX @Ri, A "Escreve RAM Externa (Ri) "
"16 Bits "MOVX A, @DPTR "Lê RAM Externa (DPTR) "
"16 Bits "MOVX @DPTR, A "Escreve RAM Externa (DPTR) "
Em todos os acessos à RAM externa, utilizamos sempre o acumulador como
registrador intermediário. Os pulsos de READ ou WRITE são ativos somente
durante a execução da instrução MOVX. Normalmente estes sinais estão
inativos e se não forem utilizados, podem ser configurados como linhas de
I/O extra.
Existem ainda duas instruções que estão disponíveis para leitura de
tabelas na memória de programa. Estas instruções permitem apenas a leitura
de dados na memória de programa (ROM), não permitindo a atualização dos
mesmos. O mnemônico é MOVC (mov constant), e pode se apresentar de duas
formas:
MOVC A, @A + DPTR
MOVC A, @A + PC
A diferença está no registrador auxiliar utilizado durante a leitura,
que pode ser o DPTR ou o PC. A primeira instrução permite o acesso a
tabelas de até 256 itens, sendo que o DPTR indica o início da tabela, e o
acumulador indica o off-set do endereço desejado. Com a variação
(incremento) do acumulador, podemos ler a tabela inteira mantendo o DPTR
fixo. A outra instrução, utiliza o acumulador como base de endereçamento e
o PC como off-set, de forma que a leitura de tabelas deve ser feita por sub-
rotinas como a que se segue:
MOV A, valor inicial
CALL tabela
A rotina "tabela" seria:
"tabela"MOVC A, @A + PC "
": "RET "
Este tipo de tabela pode conter até 255 itens, lembrando que neste
caso, não podemos utilizar o valor "0" da tabela, que variará entre 1 e
255. Um valor colocado no off-set 0 não será lido.
3.10 – Instruções Booleanas
A família 8051 contém um processador booleano completo. Um
processador booleano consiste num elemento que permite a manipulação direta
de um único bit dentro da palavra que pode ser de 8 ou mais bits (byte). A
RAM interna contém 128 bits endereçáveis e o espaço SFR contém mais 128.
Todos os port's são bits endereçáveis, e cada um pode ser tratado como um
port separado. As instruções que acessam esses bits não são apenas
seqüências de desvios condicionais, mas um completo conjunto de instruções
como indicado na tabela abaixo:
"Mnemônico "Operação "Tempo de "
" " "Execução "
"ANL C, bit "C = C and bit "2 "
"ANL C, /bit "C = C and not bit "2 "
"ORL C, bit "C = C or bit "2 "
"ORL C, /bit "C = C or not bit "2 "
"MOV C, bit "C = bit "1 "
"MOV bit, C "bit = C "2 "
"CLR C "C = 0 "1 "
"CLR bit "bit = 0 "1 "
"SETB C "C = 1 "1 "
"SETB bit "bit =1 "1 "
"CPL C "C = not C "1 "
"CPL bit "bit = not bit "1 "
"JC REL "Jump If C = 1 "2 "
"JNC REL "Jump If C = 0 "2 "
"JB bit, REL "Jump If bit = 1 "2 "
"JNB bit, REL "Jump If bit = 0 "2 "
"JBC bit, REL "Jump If bit = 1 : CLR"2 "
" "bit " "
Este tipo de operação de bit não é facilmente obtido em arquiteturas
de microprocessador. Todos os bits são acessados diretamente nos endereços
00H até 7FH na área dos 128 bytes inferiores e de 80H até FFH no espaço
SFR. Desta forma podemos com as instruções de programa, implementar
circuitos lógicos dentro do microcontrolador, evitando o uso de circuitos
discretos ou PAL's.
3.11 – Instruções de Salto
Podemos utilizar 3 tipos de instruções de desvio, quando endereçamos
um programa no microcontrolador. Estas instruções diferem entre si no
formato do endereço de destino. A instrução SJMP (Short Jump) é composta
por dois bytes, constituindo um byte de opcode e um byte de off-set. Este
fato limita o espaço de endereçamento em valores de -127 até +127 bytes em
torno da instrução seguinte ao SJMP.
Quando utilizamos a instrução LJMP (Long Jump) temos um comprimento de
3 bytes, que consiste de dois bytes de endereço e um byte de opcode,
permitindo o endereçamento de 64Kbytes de memória de programa.
A instrução AJMP (Absolute Jump) é codificada em 2 bytes sendo que o
endereço é formado por 11 bits e os 5 bits restantes utilizados no opcode.
A tabela abaixo indica as instruções de salto disponíveis.
"Mnemônico "Operação "Tempo de "
" " "Execução "
"JMP end "Salto para end "2 "
"JMP @A + DPTR "Salto para A + DPTR "2 "
"CALL end "Chama subrotina no endereço "2 "
" "end " "
"RET "Retorno de subrotina "2 "
"RETI "Retorno de interrupção "2 "
"NOP "Sem operação "1 "
Em todos os casos, o programador especifica o endereço de destino para
o assembler da mesma forma, por um "label" ou uma constante de 16 bits. O
assembler colocará o endereço de destino no formato correto para cada
instrução, e se o formato não comportar o valor, aparecerá a mensagem
"Destination out of range".
Temos ainda as instruções LCALL, que permite a chamada de subrotinas
em qualquer posição dos 64Kbytes de memória, e ACALL, que se utiliza do
mesmo formato de endereçamento de 11 bits utilizado no AJMP. As subrotinas
devem ser finalizadas com o comando RET, e deve-se lembrar que cada chamada
necessita de um RET, sem o qual o programa se perde.
A instrução RETI é utilizada como retorno da rotina de interrupção. A
única diferença entre a instrução RET e a RETI, é que a RETI informa ao
sistema de controle de interrupção que a interrupção em progresso foi
atendida.
Os saltos acima listados são chamados de saltos incondicionais, pois
não dependem de nenhuma verificação de condições anteriores. Os chamados
saltos condicionais, dependentes da verificação de certos bits de controle,
e estão listados a seguir:
"Mnemônico "Operação "Modo de "Tempo de "
" " "Endereçamento "Execução "
"JZ rel "Salto se A=0 "Acumulador "2 "
"JNZ rel "Salto se A não 0 "Acumulador "2 "
"DJNZ , rel "Decrementa e salta se"Direto "2 "
" "não 0 "Registrador " "
"CJNE A, , rel"Salta se A diferente "Direto Imediato "2 "
" "de " " "
"CJNE , #DATA,"Salta se "Indireto "2 "
"rel "diferente de #DATA "Registrador " "
Não existe bit de zero no registrador PSW, portanto as instruções JZ e
JNZ devem testar o dado do acumulador para estas condições. A instrução
DJNZ é adequada para controle de loops, pois sua configuração de dupla
função (decrementa e testa) torna fácil a execução de loops.
A instrução CJNE pode ser utilizada para controle de loops ou para
teste condicional de bytes, na forma de "maior que" ou "menor que", pois
existe a indicação de maior ou menor pelo bit de CARRY, localizado no PSW.
3.12 – Oscilador Interno
Todos os membros da família 8051 possuem um oscilador interno que pode
ser utilizado como fonte de clock para a CPU, bastando para isso que se
implemente a configuração abaixo:
Se ao invés de utilizarmos o oscilador interno, utilizamos outro
gerador qualquer (para sincronizar com outros circuitos, por exemplo)
devemos ter o cuidado de interligar a entrada no pino certo. Este fato é
importante, pois este pino muda conforme o tipo de chip utilizado, por
exemplo, com chips HMOS (8051) devemos ligar a entrada de clock ao pino
XTAL2, enquanto que em circuitos CMOS (80C51), o clock deve ser colocado no
pino XTAL1. A figura abaixo indica a correta montagem destas entradas nos
diversos componentes.
3.13 – Estrutura de Interrupções
A família 8051 atende a cinco entradas de interrupções distintas, duas
externas, duas relativas aos dois timers, e uma relativa ao canal serial
interno. Cada interrupção pode ser habilitada ou desabilitada
individualmente, setando ou resetando um bit no registrador denominado IE
(Interrupt Enable) dentro do SFR. Este registrador contém ainda um bit que
habilita todas as interrupções, e sua estrutura completa é mostrada abaixo.
O bit em 0 desabilita a interrupção e o bit em 1 habilita a interrupção.
"EA "- "- "ES "ET1 "EX1 "ET0 "EX0 "
EA – (IE.7) Habilita todas as interrupções globais quando
em 1; ES – (IE.4) Interrupção do port serial;
ET1 – (IE.3) Interrupção do timer 1;
EX1 – (IE.2) Interrupção externa 1;
ET0 – (IE.1) Interrupção do timer 0;
EX0 – (IE.0) Interrupção externa 0.
Cada fonte de interrupção pode ser programada quanto à sua prioridade
de atendimento, por um outro registrador localizado na área de SFR e
denominado IP (Interrupt Priority).
A rotina de prioridade de interrupção determina que se uma interrupção
de baixo nível estiver sendo executada, esta pode ser interrompida por uma
interrupção de alto nível, sendo continuada após o término da mesma. O
contrário não é verdadeiro, ou seja, uma interrupção de alto nível não é
interrompida por uma interrupção de nível inferior, nem igual ao dela. Se
duas interrupções de mesmo nível são recebidas simultaneamente, uma
sequência de pool interna determina qual será atendida em primeiro lugar.
A figura abaixo ilustra o conteúdo do registrador IP. O Bit em 0
desabilita a interrupção e o bit em 1 habilita a interrupção.
"- "- "- "PS "PT1 "PX1 "PT0 "PX0 "
PS – (IP.4) Prioridade de interrupção do canal serial;
PT1 – (IP.3) Prioridade de interrupção timer 1;
PX1 – (IP.2) Prioridade de interrupção externa 1;
PT0 – (IP.1) Prioridade de interrupção do timer 0;
PX0 – (IP.0) Prioridade de interrupção externa 0.
Quando em operação, todos os flags de interrupção estão retidos no
sistema de controle de interrupção durante o estado de cada ciclo de
máquina. As amostras são "pooladas" durante o ciclo seguinte, e se uma
delas se encontrar setada, o sistema de interrupção gera um LCALL para o
endereço apropriado na memória de programa, a menos que outra condição
bloqueie a interrupção.
Esta LCALL gerada por hardware resulta na transferência do conteúdo do
registrador PC para o Stack e recarrega o PC com o primeiro endereço da
rotina de interrupção. Cada rotina de uma dada interrupção começa num
endereço fixo. Somente o PC é transferido automaticamente para o stack,
então devemos nos lembrar de salvar os registradores importantes em cada
rotina de interrupção. Salvando apenas o PC, torna-se mais simples a
aplicação destas rotinas nas funções mais comuns de controle, onde não
necessitamos grandes recursos de software, pois precisamos apenas setar um
pino, ou recarregar um timer, ou ler um canal serial, por exemplo.
A figura a seguir indica como atuam os registradores no controle do
hardware de interrupção:
4 – Descrição do Hardware
A descrição a seguir mostra as características construtivas do
microcontrolador 8051.
4.1 – Registradores de função especial (Special Function Register –
SFR)
A figura abaixo indica a disposição do registrador de funções
especiais (SFR).
Na área de SFR, nem todos os endereços estão ocupados, de forma que
estes endereços não estão implantados no chip. Estes espaços destinam-se a
acessórios que encontramos em outros componentes da família.
Vamos descrever os nomes e funções de cada registrador.
"Endere"F8H "F9H "FAH "FBH "FCH "FDH "FEH "
"ço " " " " " " " "
CY – (PSW7): Carry flag, indica "vai um" nas operações aritméticas.
AC – (PSW6): Auxiliary carry flag, auxilia nas operações de adição.
F0 – (PSW5): Flag de uso geral.
RS1 – (PSW4): Seleção do banco de registradores em uso.
RS0 – (PSW3): Seleção do banco de registradores em uso.
OV – (PSW2): Overflow em operações aritméticas.
- – (PSW1): Flag definível pelo usuário.
P – (PSW0): Flag de paridade, indica o número de bits em "1" no
acumulador.
"RS0 "RS1 "Banco Selecionado "Endereço "
"0 "0 "Banco 0 "00H até 07H "
"0 "1 "Banco 1 "08H até 0FH "
"1 "0 "Banco 2 "10H até 17H "
"1 "1 "Banco 3 "18H até 1FH "
4.5 – Stack Pointer (SP) e Data Pointer (DPTR)
O Stack Pointer (ponteiro de pilha) é incrementado antes do
armazenamento dos dados em uma instrução PUSH ou CALL. Observe que o Stack
pode ser alocado em qualquer região da memória RAM, o ponteiro é sempre
inicializado no endereço 07H, e o Stack começa no endereço 08H.
O Data Pointer consiste em dois registradores de 8 bits (DPH byte
alto, e DPL byte baixo), que podem ser manipulados tanto como dois
registradores separados de 8 bits como um único de 16 bits.
4.6 – Buffer Serial (SBUF)
O Buffer de dados serial (Serial data BUFfer) consiste de dois
registradores separados, o buffer de transmissão e o buffer de recepção.
Quando um dado é colocado no buffer serial, ele vai diretamente para o
buffer de transmissão serial, e quando ele chega ao buffer de recepção, ele
é colocado diretamente no SBUF.
Existe um registrador que controla todas as operações da interface
serial chamado SCON (Serial CONtrol). Seu conteúdo é descrito a seguir.
"SM0 "SM1 "SM2 "REN "TB8 "RB8 "TI "RI "
SM0 – (SCON.7): Modo de operação da interface serial.
SM1 – (SCON.6): Modo de operação da interface serial.
SM2 – (SCON.5): Modo de operação da interface serial.
REN – (SCON.4): Habilitação de recepção.
TB8 – (SCON.3): É o nono bit transmitido (stop bit).
RB8 – (SCON.2): É o nono bit recebido.
TI – (SCON.1): Flag indicando fim de transmissão.
RI – (SCON.0): Flag indicando buffer de recepção cheio.
"SM0 "SM1 "Modo "Descrição "Frequência "
"0 "0 "0 "Shift "Freq. Oscilador /12 "
" " " "Register " "
"0 "1 "1 "8 bit UART "Variável "
"1 "0 "2 "9 bit UART "Freq. Oscilador /64 ou"
" " " " "32 "
"1 "1 "3 "9 bit UART "Variável "
4.7 – Portos de E/S (P0, P1, P2, P3)
Os portos P0, P1, P2 e P3 são latches dos seus respectivos portos
físicos. Escrevendo um bit "1" no SFR, o pino de saída do porto respectivo
irá para "1" imediatamente. Quando este port for acessado para leitura, o
estado do pino externo é armazenado no registrador correspondente. A
estrutura dos port's é ilustrada abaixo.
Todos os 4 port's são bidirecionais e consistem num latch (que é o
próprio SFR), num driver de saída e num driver de entrada. Os drivers de
saída dos port's P0 e P2 e o driver de entrada do port P0, são utilizados
durante o acesso à memória externa.
4.8 – Registradores de Timer e de Controle
Os pares de registradores (TH0, TL0, e TH1, TL1) são registradores de
contagem de 16 bits, nos quais programamos os valores de
contagem/temporização dos respectivos contadores.
Existem outros registradores de funções específicas de controle de
alguns módulos do microcontrolador. Vamos descrever cada um desses
registradores.
O registrador IP (Interrupt Priority), define um dos dois níveis
possíveis para cada interrupção, de acordo com a descrição abaixo.
"- "- "PT2 "PS "PT1 "PX1 "PT0 "PX0 "
PT2 – (IP5): Define nível de prioridade do timer 2 (somente no 8052).
PS – (IP4): Define o nível de prioridade do port serial.
PT1 – (IP3): Define o nível de prioridade do timer 1.
PX1 – (IP2): Define o nível de prioridade da interrupção externa 1.
PT0 – (IP1): Define o nível de prioridade do timer 0.
PX0 – (IP0): Define o nível de prioridade da interrupção externa 0.
Já o registrador IE (Interrupt Enable), permite a habilitação ou
desabilitação individual de cada uma das fontes de interrupção. Através de
um bit neste mesmo registrador podemos atuar sobre todas as interrupções de
maneira global.
"EA "- "ET2 "ES "ET1 "EX1 "ET0 "EX0 "
EA – (IE7): Desabilita todas as interrupções quando em 0.
ET2 – (IE5): Habilita ou desabilita a interrupção do timer 2 (somente
8052).
ES – (IE4): Habilita ou desabilita a interrupção do port serial.
ET1 – (IE3): Habilita ou desabilita a interrupção do timer 1.
EX1 – (IE2): Habilita ou desabilita a interrupção externa 1.
ET0 – (IE1): Habilita ou desabilita a interrupção do timer 0.
EX0 – (IE0): Habilita ou desabilita a interrupção externa 0.
O registrador TMOD (Timer MODe), permite o controle do modo de
operação dos timers existentes no microcontrolador, bem como a definição
quanto à operação como timer ou como contador.
"Gate "C/T "M1 (1)"M0 (1)"Gate "C/T "M1 (0)"M0 (0)"
"(1) "(1) " " "(0) "(0) " " "
Gate: Permite o disparo do timer por hardware (gate=1), ou
por software (gate=0), via registrador TCON.
C/T: Em 0 opera como timer, em 1 opera como contador.
M1: Modo de operação.
M0: Modo de operação.
"M1 "M0 "Modo de Operação "
"0 "0 "0 – Timer de 13 bits compatível com o 8048. "
"0 "1 "1 – Timer/counter de 16 bits. "
"1 "0 "2 – Timer/counter de 8 bits auto reload. "
"1 "1 "3 – No timer 0, TL0 define um contador de 8 bits e TH0 é"
" " "controlado pelos bits de controle do timer 1. O timer 1"
" " "está parado. "
A operação dos timers/counters dependem também de um registrador
denominado TCON (Timer CONtrol), utilizado para configurá-lo e monitorar
suas condições de funcionamento. Neste mesmo registrador encontramos os
flags de interrupções externas, os quais estão ativos quando da ocorrência
da interrupção.
"TF1 "TR1 "TF0 "TR0 "IE1 "IT1 "IE0 "IT0 "
TF1 – (TCON.7): Flag de overflow do timer 1. Seta quando overflow.
TR1 – (TCON.6): Bit de disparo do timer 1.
TF0 – (TCON.5): Flag de overflow do timer 0. Seta quando overflow.
TR0 – (TCON.4): Bit de disparo do timer 0.
IE1 – (TCON.3): Flag da interrupção externa 1.
IT1 – (TCON.2): Seleciona o tipo de interrupção 1 (borda ou nível).
IE0 – (TCON.1): Flag da interrupção externa 0.
IT0 – (TCON.0): Seleciona o tipo de interrupção 0 (borda ou nível).
O registrador de controle da interface serial SCON (Serial CONtrol),
permite a programação das características funcionais da interface serial do
microcontrolador. Normalmente devemos utilizar este registrador para
definir que tipo de UART vamos utilizar, e verificar o status da
transmissão pelos bits de controle, presentes neste mesmo registrador.
"SM0 "SM1 "SM2 "REN "TB8 "RB8 "TI "RI "
SM0 – (SCON.7): Modo de operação do port serial.
SM1 – (SCON.6): Modo de operação do port serial.
SM2 – (SCON.5): Usado nos modos 2 e 3 para multiprocessamento.
REN – (SCON.4): Habilita ou desabilita a recepção definido por
soft.
TB8 – (SCON.3): É o nono bit transmitido (stop bit) definido por
soft.
RB8 – (SCON.2): É o stop bit recebido do hardware para
sinalização.
TI – (SCON.1): Setado pelo hardware no fim da transmissão.
RI – (SCON.0): Setado pelo hardware no fim da recepção.
"SM0 "SM1"Modo "Descrição "Frequência "
"0 "0 "0 "Shift Register "Freq. Oscilador /12 "
"0 "1 "1 "8 bit UART "Variável "
"1 "0 "2 "9 bit UART "Freq. Oscilador /64 "
" " " " "ou 32 "
"1 "1 "3 "9 bit UART "Variável "
Existe ainda um registrador para controle genérico das funções de
alimentação do microcontrolador. O registrador PCON (Power CONtrol) é
bastante utilizado quando optamos pela utilização da tecnologia CHMOS
(80C51 por exemplo), para garantir baixo consumo em circuitos alimentados
por bateria, ou ainda que permaneçam um grande período em "stand-by".
"SMOD "- "- "- "GF1 "GF0 "PD "IDL "
SMOD: Dobra o baud rate quando utilizamos o timer 1.
GF1: Flag de uso geral.
GF0: Flag de uso geral.
PD: Ativa o modo de operação Power Down (só nos CHMOS).
IDL: Ativa o modo de operação IDLE (só nos CHMOS).
4.9 – Estrutura e operação dos ports de I/O
Os quatro ports presentes no 8051 são bidirecionais, consistindo cada
um de um latch (que é o próprio registrador Px no SFR), em um driver de
saída e em um buffer de entrada. Para acessar a memória externa,
utilizamos os ports P0 e P2, sendo que o port P0 leva os dados e endereços
multiplexados, enquanto que o port P2 leva à memória o restante dos
endereços. Fica claro que quando utilizamos os microcontroladores sem
memória interna (80C31 por exemplo) o port P2 tem seu uso restrito para
endereçamento. O port P3 é um port multifuncional, ou seja, seus pinos não
são apenas pinos de entrada e saída, mas tem diversas funções específicas,
que estão listadas abaixo:
P3.0 – RXD – entrada do port serial
P3.1 – TXD – saída do port serial
P3.2 – INT0 – entrada da interrupção externa 0
P3.3 – INT1 – entrada da interrupção externa 1
P3.4 – T0 – entrada do Timer/counter 0
P3.5 – T1 – entrada do Timer/counter 1
P3.6 – WR – sinal de escrita para memória externa
P3.7 – RD – sinal de leitura para memória externa
Os portos 1, 2 e 3 são providos de resistores pull-up internos,
enquanto que o port 0 apresenta saídas em open drain. Qualquer uma das
linhas pode ser usada independentemente como entrada ou saída, uma vez que
os ports são endereçáveis por bit (bit addressable). Para utilizarmos os
ports como entradas, devemos colocar nível lógico "1" no latch de entrada,
para que o pino fique em nível alto pelo resistor de pull-up, mas possa ser
colocado em nível baixo pela ação de um sinal externo.
No port 0, não existe o resistor de pull-up interno, de forma que
torna-se obrigatório o uso de pull-up's externos. Quando ocorre o
endereçamento, a estrutura do port permite que sejam colocados "1's" ou
"0's" conforme a necessidade. A estrutura dos ports está representada a
seguir, ilustrando o funcionamento dos mesmos.
Para escrever um dado em um dispositivo através de um dos ports,
devemos simplesmente mover o dado para o registrador respectivo no SFR.
Devemos lembrar sempre que os valores de corrente fornecidos pelos port's
são da ordem de miliampères, de forma que precisamos de drivers de corrente
na maioria dos casos. Os resistores pull-up internos fornecem baixos
valores de corrente e na maioria dos projetos determinamos a ativação dos
dispositivos de saída em níveis baixos, pois neste caso a corrente pode ser
significativamente maior.
Os buffers de saída dos ports 1, 2 e 3 fornecem corrente suficiente
para 4 cargas TTL cada um, enquanto que o port 0 pode fornecer corrente
para até 8 cargas TTL.
Algumas instruções de leitura no port, realizam uma leitura no latch
(registrador), enquanto outras realizam a leitura diretamente no pino do
CI. As instruções que realizam a leitura no latch, lêem este valor,
processam, e depois se for necessário rescrevem-no no latch. São chamadas
de "read-modify-write", e estão listadas a seguir:
ANL – "E" lógico
ORL – "Ou" lógico
XRL – "Ou Exclusivo" lógico
JBC – Jump se bit =1 e limpa o bit
CPL – Complementa o bit
INC – Incremento
DEC – Decremento
DJNZ – Decrementa e salta se não zero
MOV, Px,y, C – Move carry bit para o bit y do port x
CLR Px,y – Limpa bit y do port x
SETB Px,y – Seta bit y do port x
A razão pela qual as instruções acima são direcionadas
preferencialmente ao latch é evitar uma má interpretação do nível lógico no
pino. Um exemplo disso é quando utilizamos transistores na saída dos
microcontroladores, e escrevemos nível "1" na base do mesmo. A tensão
neste pino pode ser confundida com nível "0" facilmente, enquanto que se a
mesma for lida no latch, representará o valor real do sinal no pino.
4.10 – Acesso à memória externa
Podemos ter dois tipos de acesso à memória externa, acesso à memória
de programa externa (ROM, EPROM) e acesso à memória de dados externa (RAM).
Acessos à ROM externa utilizam o sinal PSEN como strobe de leitura,
enquanto que utilizamos o sinal RD ou WR como strobe quando acessamos a
memória RAM.
Buscas à memória externa de programa utilizam sempre endereços de 16
bits, e os acessos à memória de dados podem utilizar 8 ou 16 bits de
endereço.
Quando utilizamos acessos de 16 bits, o byte alto de endereço é
exibido pelo porto 2, que fica indisponível como port de I/O genérico.
Quando utilizamos acessos em 8 bits, o valor do port 2 existente no latch
do seu respectivo SFR é mantido de forma que podemos implementar um sistema
de gerenciamento com facilidade.
Em qualquer dos casos, o port 0 contém o byte baixo de endereços
multiplexado com os dados, e nesta função utilizamos um dos FETs internos
com pull-up de forma que não se orna necessária a adição de pull-up externo
(se forem realizadas apenas operações de busca na memória, o que não é
muito comum). O sinal de ALE deve ser utilizado para capturar o endereço
válido no latch externo.
Durante qualquer acesso à memória externa, é escrito o byte 0FFH no
latch do port 0 (SFR), destruindo a informação presente neste port,
portanto, devemos salvar qualquer informação útil existente no port 0 antes
de acessar a memória externa.
A memória de programa externa é acessada sempre em duas condições:
quando o sinal EA estiver ativo (nível baixo), ou o contador de programa PC
apresentar um número maior do que 0FFFH.
4.11 – Temporizadores e Contadores
O microcontrolador 8051 tem 2 temporizadores/contadores de 16 bits,
timer 0 e timer 1. Os dois podem ser programados para operar como
temporizadores ou contadores independentemente.
Na função de timer, o registrador é incrementado a cada ciclo de
máquina, de forma que podemos imaginar o timer como um "contador de ciclos
de máquina". Como um ciclo de máquina consiste de 12 períodos do
oscilador, podemos calcular facilmente a frequência do nosso timer.
Na função de contador, o registrador é incrementado a cada transição
de 1 para 0 no correspondente pino de entrada. Desta forma, cada leitura
toma o tempo de dois ciclos de máquina, limitando a frequência máxima de
amostragem a 1/24 da frequência de clock.
4.12 – Modos de operação
Podemos ter quatro modos distintos de operação dos timer's
selecionados pelo registrador TMOD.
Modo 0:
No modo 0, o timer é um contador de 8 bits com um divisor por 32,
executando na realidade, um timer de 13 bits, compatível com o timer do
8048, como indicado na figura abaixo:
Neste modo, quando o contador passa de todos os bits em 0, o flag
respectivo TFx é setado no registrador TCON. O disparo do timer é feito
por outro bit no registrador TCON, o bit TRx (Timer Run). O bit Gate,
presente no registrador TMOD permite o uso de uma interrupção conjuntamente
com o timer. Devemos lembrar sempre de programar TMOD antes de programar
TCON para disparo do timer.
O registrador de 13 bits consiste nos 8 bits de THx e nos 5 bits mais
baixos de TLx, sendo os 3 bits restantes do registrador TLx ignorados.
Modo 1:
No modo 1, os timer se comportam da mesma forma que no modo 0, exceto
pelo fato de que os registradores agora utilizam a totalidade dos 16 bits
disponíveis para cada um dos contadores.
Modo 2:
O modo 2 configura o registrador do timer como um contador de 8 bits
(TLx) com recarga automática, como mostrado na figura abaixo:
Quando ocorre o overflow de TLx, o flag TLx é setado e o conteúdo de
TLx é recarregado com o valor de THx, que deve ser anteriormente carregado
por software. O valor de THx permanece inalterado.
Modo 3:
O modo 3 deve ser utilizado quando necessitamos de um outro contador
no 8051. Quando ativamos o modo 3, estabelecemos dois contadores
separados, um para o THx e outro para o TLx. O timer procedente de TLx
utiliza para seu controle, os bits C/T, Gate, TR0, INTx e TFx, relativos ao
timer 0, enquanto que o timer relativo ao registrador THx, utiliza os bits
de controle relativos ao timer 1. A figura abaixo ilustra a lógica de
atuação deste modo.
4.13 – Interface Serial
A interface serial presente no microcontrolador é do tipo full-duplex,
pode transmitir e receber dados simultaneamente, com buffer de recepção, ou
seja, pode começar a receber um segundo byte antes de ler o primeiro byte
do buffer. Os buffers de transmissão e recepção são comandados pelo
registrador SBUF no SFR. Escrita no SBUF carrega o buffer de transmissão,
enquanto que leituras no SBUF acessam um registrador de recepção separado
fisicamente.
A interface serial pode operar em 4 modos distintos, e em qualquer dos
modos a transmissão é iniciada por qualquer instrução que utilize o SBUF
como registrador de destino. A recepção se dá quando chega um dado no
SBUF.
4.14 – Modos de Operação
Podemos operar com a interface serial interna do microcontrolador, de
quatro modos diferentes:
Modo 0:
Neste modo, os dados manipulados entram pelo pino RXD, enquanto que o
pino TXD é utilizado como saída. Temos então a transmissão de 8 bits,
sendo que o primeiro bit é o LSB, e a frequência de baud rate é fixa em
1/12 da frequência do oscilador.
A transmissão é iniciada por qualquer instrução que utilize o SBUF
como registrador de destino. Imediatamente após esta instrução, é colocado
um bit "1" na nona posição do shift register e o bloco de controle de
transmissão começa a transmissão. Os bits de dados são deslocados para a
direita e são colocados zeros nas posições desocupadas, até que se chegue
no MSB. Esta condição avisa para o bloco de controle que deve ser efetuado
um deslocamento, e em seguida é setada a flag TI. Todo este processo
ocorre no tempo de 10 ciclos de máquina.
A recepção começa quando a condição REN é igual a "1" e o flag RI é
igual a "0". Os dados recebidos são deslocados e após a chegada do último
bit, o flag de recepção RI é setado, indicando que existem dados no buffer
de recepção. A figura abaixo ilustra o processo.
Modo 1:
Dez bits são recebidos pelo pino RXD, ou transmitidos pelo pino TXD;
um start bit (0), 8 bits de dados (LSB primeiro), e um stop bit. Na
recepção, o stop bit vai para a posição RB8 no registrador SCON, e o baud
rate é determinado pelo timer 1, na maioria dos casos (podem ser utilizados
também o timer 2 ou ambos no 8052).
A transmissão ocorre da mesma forma que no modo anterior, exceto ao
fato de que não existe uma linha de clock sincronizando os dois circuitos.
Este sincronismo é função de bits de start e stop, presentes em cada
transmissão. Após a transmissão do último bit (stop bit) o flag TI é
setado no registrador SCON.
A recepção é iniciada com a detecção da transição de 1 para 0 na linha
RXD, indicando a presença do start bit na linha. Para esta função, a linha
RXD é amostrada a uma taxa de 16 vezes a frequência determinada para o baud
rate. Após esta detecção, o sinal começa a ser deslocado a partir da
frequência gerada pelo timer 1. Quando for recebido o último bit (stop
bit), este é colocado em RB8, e o flag TI é setado. A figura a seguir
ilustra o diagrama de sinais da recepção do modo 1.
Modos 2 e 3:
Nestes dois modos são transmitidos 11 bits pelo pino TXD, ou recebemos
11 bits através do pino RXD: um start bit "0", 8 bits de dados (LSB
primeiro), um nono bit programável e um stop bit "1". A diferença entre os
modos 2 e 3 é que no modo 3 a frequência de baud rate é variável, enquanto
que no modo 2 a frequência é fixa em 1/32 ou 1/64 da frequência do
oscilador. Os processos de transmissão e recepção dos dados são
semelhantes aos outros modos anteriormente mostrados. A figura abaixo
ilustra o processo.
4. 15 – Registrador de Controle
O controle da interface serial é feito pelo já descrito registrador
SCON, com a atuação do registrador PCON, (utilizando o bit SMOD). Por este
registrador podemos monitorar o funcionamento da interface serial pelos
bits TI, RI, TB8 e RB8, que indicam o estado da interface serial nas
operações de transmissão ou recepção.
4.16 – Baud Rates
A taxa de transmissão (baud rate), tem seus valores definidos de
acordo com o modo de operação estabelecido para o interface serial. No
modo 0, o baud rate é fixo e tem seu valor estabelecido como sendo 1/12 da
frequência do oscilador.
No modo 2, a frequência pode ter dois valores distintos, dependendo do
valor do bit SMOD no registrador PCON. Se SMOD for igual a 0, o baud rate
é igual a 1/64 da frequência do oscilador, se o SMOD for igual a 1, o baud
rate passa a ser 1/32 da frequência do oscilador.
Quando utilizamos o timer 1 como gerador de baud rate, o baud rate nos
modos 1 e 3 tem seu valor determinado pela taxa de overflow do próprio
timer 1, obedecendo a fórmula:
Baud rate = [(2Smod)/32] x (timer 1 overflow rate)
A interrupção do timer 1 deve ser desabilitada neste caso para evitar
sinalização indevida. O timer pode ser configurado para operação como
timer ou como contador em qualquer um dos três modos. O modo mais
comumente utilizado é o modo de operação como timer de auto-recarga. A
fórmula para se obter diretamente a frequência do baud rate é a seguinte:
Baud Rate = {[(2Smod)/32] x [Fosc./[12 x (256 - TH1)]]}
A tabela abaixo indica os valores mais utilizados a partir de uma dada
frequência de cristal, e os valores de recarga dos timers para facilitar a
programação.
"Baud Rate"Freq. "SMOD "Modo "Valor de Recarga "
" "Osc. " " " "
"19,2K "11,059 "1 "2 "FDH "
" "MHz " " " "
"9,6K "11,059 "0 "2 "FDH "
" "MHz " " " "
"4,8K "11,059 "0 "2 "FAH "
" "MHz " " " "
"2,4K "11,059 "0 "2 "F4H "
" "MHz " " " "
"1,2K "11,059 "0 "2 "E8H "
" "MHz " " " "
"137,5 "11,968 "0 "2 "1DH "
" "MHz " " " "
"110 "6 MHz "0 "2 "72H "
"110 "12 MHz "0 "1 "FEEBH "
Devemos observar os valores de máxima frequência para cada um dos
modos, e respeitá-los, pois o uso de frequências acima destes valores
acarretariam perdas de informação na comunicação serial. A tabela abaixo
indica estas frequências:
"Modo "Frequência Máxima "
"0 "1 MHz "
"1 e 3 "62,5 KHz "
"2 "375 KHz "
4.17 – Interrupções
Os microcontroladores da família 8051 são providos de 5 fontes de
interrupção, como mostradas na figura a seguir. As interrupções externa
INT0 e INT1 podem ser ativadas por nível lógico ou por transição (borda),
dependendo para isto, dos bits IT0 e IT1 no registrador TCON. Os flags que
indicam a presença da interrupção nos pinos externos são IE0 e IE1 no mesmo
registrador TCON. Quando uma interrupção externa é recebida, o respectivo
flag é limpo quando a rotina de serviço é vetorada para o endereço da
interrupção, somente se a interrupção for do tipo ativa por transição. Se
a interrupção for ativa por nível , o dispositivo externo que solicitou a
interrupção se encarrega do seu controle.
As interrupções dos timers são geradas quando houver overflow dos
mesmos, e são reestabelecidas ao seu estado inativo por hardware quando a
interrupção já se encontrar devidamente vetorada.
A interrupção da interface serial é gerada por um OU lógico entre os
flags de RI e TI, e estes flags não são limpos após o vetoramento da
interrupção, devendo ser feito este procedimento por software, após o
recebimento ou transmissão do dado.
Todos os bits que geram interrupção podem ser habilitados ou não pelo
registrador de habilitação de interrupção IE.
Os vetores de endereço das interrupções, ou seja, os endereços para
qual o PC é direcionado quando ocorre uma interrupção são fixos e seus
valores são indicados a seguir:
"Fonte "Endereço "
"IE0 "0003H "
"TF0 "000BH "
"IE1 "0013H "
"TF1 "001BH "
"Serial "0023H "
4.18 – Estrutura de prioridades
Cada uma das fontes de interrupção pode ser individualmente programada
para atender a um dos dois possíveis níveis de interrupção, mediante um bit
específico no registrador IP. Colocando um valor 0 no bit correspondente,
definimos esta interrupção como de menor prioridade, e vice-versa.
Quando temos duas interrupções de mesma prioridade, no mesmo instante,
elas serão atendidas pelo pool select que é realizado na seguinte ordem:
IE0 – TF0 – IE1 – TF1 – Serial
4.19 – Interrupções externas
As fontes externas de interrupção podem ser programadas para serem
ativadas por nível ou por borda, desde que os pinos de interrupção externa
sejam amostrados uma vez a cada ciclo de máquina, a entrada de interrupção
deve manter-se estável por pelo menos 12 períodos do oscilador para que a
interrupção seja reconhecida. No caso da interrupção ser ativa por
transição, deve-se manter em um nível por um ciclo de máquina e mudar para
outro nível, mantendo-se nele por outro ciclo de máquina.
Após o reconhecimento, o flag IEx é setado no registrador TCON sendo
automaticamente resetado pela CPU quando a rotina de serviço da interrupção
é chamada.
Se a interrupção é ativa por nível, este nível deve ser mantido pelo
tempo necessário para que seja reconhecida a interrupção, e depois deve ser
desativada antes que a rotina de tratamento da interrupção se complete,
para evitar que outro pedido de interrupção seja gerado.
4.20 – Circuitos de Controle
Existem outros circuitos que devem ser considerados quando da
elaboração do hardware de um microcontrolador. Além dos já citados
circuitos de decodificação de dados/endereços, utilizado para acesso a
memória externa, pull-ups e buffers nas linhas de dados e endereços, alguns
merecem especial cuidado e atenção na construção.
4.21 – Circuito de Reset
A entrada do reset se dá pelo pino RST, quando este é mantido em nível
alto por pelo menos dois ciclos de máquina, após o circuito do oscilador
começar a funcionar. Logo após o reset, os valores colocados nos
registradores são os indicados abaixo:
"Fonte "Endereço "
"PC "0000H "
"Acc "00H "
"B "00H "
"PSW "00H "
"SP "07H "
"DPTR "0000H "
"P0-P3 "FFH "
"IP "XXX00000b "
"IE "0XX00000b "
"TMOD "00H "
"TCON "00H "
"TH0 "00H "
"TL0 "00H "
"TH1 "00H "
"TL1 "00H "
"SCON "00H "
"SBUF "Indeterminado "
"PCON (HMOS)"0XXXXXXXb "
"PCON "0XXX0000b "
"(CHMOS) " "
Normalmente utilizamos um circuito conhecido como Power On Reset, para
que o microcontrolador seja inicializado ao ligarmos o equipamento. O
circuito abaixo ilustra um exemplo típico de circuito para uma tensão de
5Vcc, e frequência de 10MHz. Devemos notar que para os circuitos CHMOS,
devido à características construtivas do dispositivo, não se faz necessário
o uso do resistor externo, simplificando ainda mais o circuito.
4.22 – Circuito de Clock
Podemos utilizar o oscilador interno ao microcontrolador como indicado
anteriormente neste mesmo manual. Devemos utilizar um cristal com as
seguintes características:
Co (Shunt Capacitance) – máx. 7pF
Cl (Load Capacitance) – 30 pF (10%)
Potência – 1mW
A resistência equivalente em série depende da frequência do cristal,
tendo seus valores práticos demarcados no gráfico a seguir:
4.23 – Operação passo a passo
Este modo de operação é muito útil durante a construção de programas,
e desenvolvimento do hardware, para solucionar eventuais problemas surgidos
no decorrer destes processos.
Podemos entender esta operação, lembrando o funcionamento da já
conhecida estrutura das interrupções do microcontrolador. Quando uma
interrupção está em progresso, outra interrupção de mesmo nível não pode
ser ativada simultaneamente. O fato é que a próxima interrupção só ocorre
após a execução de pelo menos uma instrução do programa interrompido, de
forma que, colocando a interrupção INT0 (por exemplo) em nível baixo e
acrescentando algumas linhas de programa nas rotinas de tratamento da
interrupção. As linhas são as seguintes:
JNB P3.2,$ ; aguarda até que a interrupção vá para alto
JB P3.2,$ ; aguarda até que a interrupção vá para baixo
RETI ; volta e executa uma instrução
Desta forma, quando a INT0 é ativada em nível baixo, a CPU vai para a
rotina de tratamento da interrupção e fica até que o sinal INT0 pulse (de
baixo para alto e novamente para baixo). Desta forma ela executa o comando
de retorno da interrupção, executa uma instrução e imediatamente retorna a
rotina de interrupção, permanecendo nesta até que o sinal INT0 pulse
novamente.
Esta é uma forma simples de acompanhar a execução das rotinas de um
programa passo a passo, mas normalmente vamos executar estas rotinas
através de um software de simulação apropriado, onde serão detectadas as
principais falhas na programação.
4.24 – Descrição da pinagem
A figura abaixo ilustra a pinagem do controlador 8051 nas duas formas
de encapsulamento mais comuns:
A descrição da pinagem deste componente, no invólucro DIP é dada
abaixo:
"Pino "Descrição "
"1 "Port 1, Dado 0 "
"2 "Port 1, Dado 1 "
"3 "Port 1, Dado 2 "
"4 "Port 1, Dado 3 "
"5 "Port 1, Dado 4 "
"6 "Port 1, Dado 5 "
"7 "Port 1, Dado 6 "
"8 "Port 1, Dado 7 "
"9 "Entrada de Reset "
"10 "Port 3, Dado 0 (RXD da interface serial"
" "interna) "
"11 "Port 3, Dado 1 (TXD da interface serial"
" "interna) "
"12 "Port 3, Dado 2 (Interrupção externa "
" "INT0) "
"13 "Port 3, Dado 3 (Interrupção externa "
" "INT1) "
"14 "Port 3, Dado 4 (Entrada do Timer 0) "
"15 "Port 3, Dado 5 (Entrada do Timer 1) "
"16 "Port 3, Dado 6 (Sinal de escrita para "
" "memória exemploterna) "
"17 "Port 3, Dado 7 (Sinal de leitura para "
" "memória externa) "
"18 "Entrada do cristal do oscilador "
"19 "Entrada do cristal do oscilador "
"20 "Alimentação Terra "
"21 "Port 2, Bit0 (Endereço A8) "
"22 "Port 2, Bit1 (Endereço A9) "
"23 "Port 2, Bit2 (Endereço A10) "
"24 "Port 2, Bit3 (Endereço A11) "
"25 "Port 2, Bit4 (Endereço A12) "
"26 "Port 2, Bit5 (Endereço A13) "
"27 "Port 2, Bit6 (Endereço A14) "
"28 "Port 2, Bit7 (Endereço A15) "
"29 "Sinal PSEN (Program Search Enable) "
"30 "Sinal ALE (Address Latch Enable) *Prog"
" "no 8751 "
"31 "Sinal EA (External Access) *Tensão de "
" "Prog no 8751 "
"32 "Port 0, Bit 7 (Dado 7) "
"33 "Port 0, Bit 6 (Dado 6) "
"34 "Port 0, Bit 5 (Dado 5) "
"35 "Port 0, Bit 4 (Dado 4) "
"36 "Port 0, Bit 3 (Dado 3) "
"37 "Port 0, Bit 2 (Dado 2) "
"38 "Port 0, Bit 1 (Dado 1) "
"39 "Port 0, Bit 0 (Dado 0) "
"40 "Alimentação de +5V "
5 – PROGRAMAÇÃO E SIMULAÇÃO
5.1 – "COMPILAÇÃO" E "LINKAGEM"
Um programa escrito em linguagem assembly (PROGRAMA FONTE), não pode
ser diretamente processado pelo microcontrolador do sistema, devendo
primeiramente ser traduzido para a sua linguagem de máquina, com o uso de
tabelas ou por meio de um programa destinado para tal tarefa chamado de
COMPILADOR, que fornece então como saída o PROGRAMA OBJETO.
Define-se COMPILADOR como um programa aplicativo que transforma um
arquivo constituído por códigos ASCII (PROGRAMA FONTE: obrigatoriamente com
extensão ".ASM"), gerado normalmente por um editor de textos, em um arquivo
binário que contém os bytes correspondentes às instruções (códigos de
máquina) do microcontrolador.
Como resultado da compilação são criados dois arquivos:
- Arquivo de mesmo nome, porém com a extensão ".OBJ" (PROGRAMA
OBJETO).
- Arquivo de mesmo nome, porém com a extensão ".LIST", que corresponde
a um arquivo texto que mostra o resultado da compilação, contendo para cada
linha de programa, o código de máquina correspondente à instrução, sendo
muito útil na depuração de erros de compilação.
A "linkagem" tem a finalidade de reunir, em um único arquivo, todos as
rotinas escrita em um ou vários arquivos diferentes.
Após a "linkagem" são gerados dois arquivos:
- Arquivo de mesmo nome, sem extensão, usado pelo programa simulador.
- Arquivo de mesmo nome, porém com a extensão ".HEX", usado por
gravadores de memórias e microcontroladores e também pelo programa
simulador.
PROGRAMA COMPILADOR PROGRAMA LINKER PROGRAMA
FONTE OBJETO EXECUTÁVEL
.ASM .OBJ .HEX
O compilador, o "Linker" e o Simulador usados no laboratório são
produzidos pela AVOCET.
5.2 – DIRETIVAS (ou PSEUDO-INSTRUÇÕES) de Compilação
Além das instruções pertencentes ao microcontrolador em questão, a
linguagem assembly possui ainda algumas instruções especiais, pseudo-
instruções ou diretivas, que são usadas apenas para a estruturação do
programa.
Estas instruções especiais, que não são traduzidas para o código de
máquina por não pertencerem ao conjunto de instruções do microcontrolador
escolhido, possuem apenas funções especiais no programa como: definir
símbolos, estabelecer o endereço inicial do programa, reservar área de
memória etc, não sendo, portanto, processadas.
PSEUDO-INSTRUÇÕES MAIS USADAS
ORG (ORIGIN)
Formato: Pseudo-instrução operando
ORG endereço
Função:
Usado para o endereço inicial de memória, no qual o programa ou um
trecho de programa será armazenado.
Exemplo: ORG 0100H
Assim o programa objeto será carregado na memória a partir do endereço
0100H
DB (DEFINE BYTE)
Formato: Pseudo-instrução operando
DB byte
Função:
O byte do operando é carregado diretamente na posição de memória
escolhida pelo ORG.
Exemplo:
ORG 0050H
DB 3FH
DB 1AH
Assim os bytes 3FH e 1AH foram armazenados nas posições de memória
0050H e 0051H respectivamente.
END
Formato: Pseudo-instrução
END
Função:
Indica o final do programa.
5.3 – USO DO COMPILADOR E DO LINKER (PASSO A PASSO)
OBS: Comandos digitados na linha de "prompt do DOS".
1. Com o "NE" ou "EDIT" escrever um programa em assembly nomeado
obrigatoriamente com a extensão ".ASM" (criando assim programa fonte).
OBS: No editor de textos deve-se obrigatoriamente reservar as colunas
de "1" a "6" para os "labels" ou "tags" que representam os endereços do
programa, de entrada de "loops", chamada de sub-rotinas etc.
2. Com o "X8051" (compilador) obter os arquivos com extensão ".OBJ"
(programa objeto) e ".LST" (listagem) da seguinte forma:
X8051 [ENTER]
Listing Destination (..........): D [ENTER]
Generate cross reference [ENTER]
Input file name:.........nome do arquivo.ASM [ENTER]
Output file name: ...... nome do arquivo [ENTER]
3. Com o "LINK" ligar o arquivo ".OBJ", gerando um arquivo ".HEX" da
seguinte
forma:
LINK [ENTER]
Input file name: ........ .OBJ [ENTER]
Enter offset for ....... [ENTER]
Input file name: [ENTER]
Output file name: [ENTER]
Options (..........): H [ENTER]
4. No simulador:
Load
Avocet
.... .HEX
Simulation
F1 (total)
F10 (passo a passo)
5.4 – Simulador dos Microcontroladores da família 8051
****** TELA DE ENTRADA DO SIMULADOR: ******
Deve-se selecionar uma opção em função da cpu escolhida para o
projeto.
****** TELA DE SIMULAÇÃO: ******
5.5 – Operação básica do simulador
Para uma rápida ambientação com o programa simulador, é apresentada
uma seqüência de testes para as principais teclas e/ou comandos:
· Visualização geral da tela, visando reconhecer os seus principais
campos (coloridos) e funções correspondentes.
· Teclas: ESC
CTRL C
· Comandos: Help Commands
Display
Simulation
Avocet
Registration
Load Avocet
Quit Exit
setUp Cursor Yes
No
View Memory-map
Symbols Alpha
Registers
Data
Bit
SFR
eXecute
· Seqüência para carregar um arquivo no simulador e informações sobre
a simulação:
Load Avocet ... .OBJ Help Simulation
· Teclas para a simulação
F1: executa o programa inteiro.
F10: executa um programa instrução por instrução.
F9: volta para a condição anterior, após a execução de uma instrução.
6 – Tabela de Instruções completa
Temos na tabela a seguir o set de instruções do 8051, indicando o seu
opcode, conforme já explicado, o número de bytes da instrução, os períodos
de clock necessários e os flags afetados.
Temos a seguinte codificação na tabela:
@ – significa "endereçado pelo valor de ...";
#Dado – indica valor constante de 8 bits;
#Dado 16 – indica valor constante de 16 bits;
Direto – indica um endereçamento de memória de 8 bits (primeiras 256
posições interna ou externas)
rel – indica que o endereçamento é relativo;
? – indica "depende do resultado ou da operação";
"-" – indica "não afetado";
1 – indica setado;
0 – indica zerado.
"Opcode "Mnemôn"Função"Bytes "
" "ico " " "
"4000 "0 "0 "Instrução – Escrita no módulo "
"4001 "0 "1 "Dados – Escrita no módulo "
"4002 "1 "0 "Instrução – Leitura no módulo "
"4003 "1 "1 "Dados – Leitura no módulo "
Tabela 4 - Endereçamento do módulo LCD para Figura 3
O exemplo apresentado na Figura 3 refere-se à conexão do módulo LCD
com comunicação/transmissão de 8 bits, mas podemos conectar o módulo com
transmissão a cada 4 bits, conforme é mostrado na Figura 4. Neste caso não
utilizamos os pinos 7, 8, 9 e 10. Isto é muito útil quando a CPU do usuário
possui poucos pinos de I/O, caso típico da linha de microprocessadores PIC,
como por exemplo o Basic Stamp. Agora surge a dúvida, um mesmo módulo pode
conectar-se com 8 ou 4 bits? como isto é possível?
Ocorre que o módulo LCD quando alimentado necessita de algumas
instruções de inicialização que identificará qual a forma de transmissão de
dados que será estabelecida entre a CPU e o módulo.
Figura 4 - Modulo LCD comunicando-se com 4 bits
03 – PROGRAMAÇÃO / INSTRUÇÕES
Tabela 5 - Conjunto de instruções do módulo LCD
A Tabela 5 apresenta o conjunto de instruções, levando-se em
consideração que a comunicação com o módulo seja com barramento de 8 bits
(fixado durante a inicialização)
. Para o caso desta comunicação ocorrer com apenas 4 bits (nible), os
8 dados
ou instruções serão enviados por nible. sendo enviado o nible mais
significativo primeiro. Por exemplo para limpar o display, escreve-se o
nible 0000 e depois 0001.
A Tabela 6 traz um resumo das instruções mais usadas na comunicação
com os módulos LCD.
Tabela 6 - Instruções mais comuns
3.1 – DESCRIÇÃO DETALHADA DAS INSTRUÇÕES
3.1.1 – Limpa Display
Esta instrução escreve o caracter ASCII 32 que corresponde ao branco
ou barra de espaço em todos os endereços da DDRAM apagando a mensagem que
estiver escrita. O cursor retorna ao endereço "zero", ou seja, à posição
mais a esquerda da primeira linha.
3.1.2 – Cursor Home
Faz retornar o cursor para a posição mais a esquerda da primeira linha
e faz voltar à posição original mensagens previamente deslocadas. O
conteúdo da DDRAM permanece inalterado.
3.1.3 – Fixa o modo de operação
Esta instrução tem efeito somente durante a leitura ou escrita de
dados, portanto, deve ser ativada na inicialização.
-Estabelece o sentido de deslocamento do cursor (X=0 p/ esquerda, X=1
p/ direita)
-Estabelece se a mensagem deve ou não ser deslocada com a entrada de
um novo caracter S=1 SIM, S=0 NÃO. Exemplo: X=1 e S=1 => mensagem desloca
p/ direita.
3.1.4 – Controle do Display
A mensagem fica aparente quando D=1 e desaparece quando D=0, porém o
conteúdo da DDRAM fica inalterado. O cursor fica aparente quando C=1 e
desaparece quando C=0, porém as propriedades de escritas vigentes
permanecem inalteradas. O cursor quando aparente liga a última linha que
compõem o caracter, exceto quando B=1, que apresenta em alternância com uma
matriz com todos os pontos negros em intervalos de 0,4 segundos. Quando B=1
e C=0, obteremos a ativação intermitente de uma matriz completa (todos os
pontos da matriz).
3.1.5 – Deslocamento do Cursor ou da Mensagem
Desloca o cursor ou a mensagem sem que para isso tenha que escrever ou
ler dados do display. Utilizado para posicionamento dos dados no display.
3.1.6 – Estabelece o modo de utilização do Módulo LCD
Y estabelece o modo de comunicação. Se Y=1 estabelece 8 bits e quando
Y=0 será 4 bits, enviados em duas operações, com os 4 bits (Nible) mais
significativos sendo enviados primeiro. N fixa o número de linhas: N=0 para
uma linha e N=1 para duas ou mais linhas. F fixa o tipo da matriz: F=0 para
matriz 7x5 ou 8x5 e F=1 para matriz 10x5 (somente possível quando
apresentando em uma linha).
3.1.7 – Endereçamento da CGRAM
CGRAM é uma região da memória RAM destinada para criação de caracteres
especiais, como por exemplo: ç é, Ê, etc.
Estabelece o endereço da CGRAM no contador de endereços (AC) como um
número binário AAAAAA e após isto os dados serão escritos ou lidos pela CPU
neste endereço. Cada caracter especial ocupa 8 endereços na CGRAM.
3.1.8 – Endereçamento da DDRAM
Estabelece o endereço da DDRAM no contador de endereços (AC) como um
número binário AAAAAAA e após isto os dados serão escritos ou lidos pela
CPU neste endereço. Para os display de uma linha AAAAAAA varia de 80H a
CFH. Já para todos os display de duas linhas varia de 80H a A7H para a
primeira linha e de C0H a E7H para a segunda linha.
3.1.9 – Busy Flag (BF)
Busy Flag ou o bit 7 indica ao sistema onde está conectado o módulo
LCD, se o controlador do módulo está ocupado com alguma operação interna
(BF=1), e neste caso, não aceita nenhuma instrução até que BF volte para 0.
Além disso, permite a leitura do conteúdo do contador de endereços
(AC) expressa por AAAAAAA. O contador de endereços pode conter tanto
endereço da CGRAM como da DDRAM, depende neste caso, da instrução anterior.
3.1.10 – Escrita de dados na DDRAM ou CGRAM
Escreve o byte AAAAAAAA tanto na CGRAM como na DDRAM, dependendo da
instrução anterior (que define o endereço). Após a escrita, o endereço é
automaticamente incrementado ou decrementado de uma unidade dependendo do
modo escolhido (ver item 3.1.3).
3.1.11 – Leitura de dados na DDRAM ou CGRAM
Faz uma leitura na CGRAM ou na DDRAM, dependendo da instrução anterior
(que define o endereço). É importante que precedendo a esta leitura seja
executado a instrução de estabelecimento do endereço da CGRAM ou DDRAM,
pois caso contrário o dado lido é inválido.
3.2 – TABELAS DE ENDEREÇOS DOS CARCTERES NA DDRAM
A seguir resumiremos os endereços da DDRAM (em hexadecimal) dos
caracteres da maioria dos módulos LCD disponíveis no mercado.
OBS:
· Para os módulos de 04 linhas estamos considerando que existe um
outro pino de habilitação (como o pino 6) para as duas últimas linhas,
portando outros endereços de hardware.
· Antes de enviar uma instrução para escrita de dados no display,
enviar antes uma de endereçamento na DDRAM, com o endereço onde deve ser
escrito o caracter, tipo um gotoxy().
3.3 – TABELAS DE ENDEREÇOS DOS CARCTERES NA CGRAM
Os caracteres especiais previamente programado, durante a
inicialização, podem ser utilizados a qualquer tempo como se fossem
caracteres normais, lembrando que os endereços bases em hexadecimal para
gravação dos caracteres especiais, na maioria dos módulos LCD, são
respectivamente: 40, 48, 50, 58, 60, 68, 70 e 78. Cada caracter especial
ocupa 8 (oito) endreços.
Tabela 7 - Caracter especial {ç} na CGRAM
Isto significa que para utilizarmos o caracter gravado no endereço
base 50, durante a inicialização ou reset do sistema, teremos que
escrevermos 8 bytes entre os endereços 50 e 57, para construirmos o
caracter. Para ilustrar este procedimento, supor que queiramos construir o
caracter {ç} no endereço base 50. Neste caso, devemos construir o mapa
deste caracter especial como mostrado na Tabela 7 (supondo estar
trabalhando com matriz 7x5 e com auto incremento de endereço a cada
escrita). Observe que o último endereço sempre será 00, pois esta posição é
sempre ocupada pelo cursor.
4 – INICIALIZAÇÃO DOS MÓDULOS LCD
Toda vez que alimentamos o módulo LCD deve ser executado o
procedimento de inicialização, que consiste no envio de uma seqüência de
instruções para configurar o modo de operação para execução de um dado
programa de interfaceamento. Em muitos display este procedimento ocorre
automaticamente, dentro de condições específicas que envolve temporizações
mínimas referente a transição do nível lógico 0 para 1, ao ligarmos a
fonte. Em caso de dúvidas, recomendamos o envio destas instruções após o
reset do sistema.
a) Inicialização para sistemas 8 bits de dados (5 instruções)
Entre as duas primeiras instruções recomendamos um delay de 15 mS. As
demais instruções podem ser escritas após checar o Busy Flag.
b) Inicialização para sistemas 4 bits de dados (5 instruções)
Entre as quatro primeiras instruções recomendamos um delay de 15 mS.
As demais instruções podem ser escritas após checar o Busy Flag. Estes bits
(nible) devem estar conectados aos pinos 11, 12.13 e 14.
5 – ROTEIRO PARA PROGRAMAÇÃO
A seguir passaremos a descrever um resumo dos procedimentos para
utilização de um módulo ou display LCD:
1_ Ao energizar o módulo ajuste o potenciômetro de controle do brilho
ou contraste até obter a visualização da matriciação na primeira linha para
módulo de duas linhas ou até a matriciação de meia linha para módulos de
uma linha.
2_ Alguns módulos de uma linha só funcionam com a instrução 38 ao
invés de 30, conforme instruções de inicialização.
3_ O sinal de Enable (pino 6) deverá ser gerado conforme a
temporização mostrada na Figura 2. Os códigos de dados ou de instruções só
serão processados pelo processador do módulo após a descida do sinal do
Enable.
4_ Para ajustar a velocidade de comunicação entre a CPU do usuário e o
módulo LCD existem duas possibilidades:
· Intercalar uma rotina de atraso de aproximadamente 15 mS entre as
instruções.
· Fazer a leitura do Busy Flag antes do envio de cada instrução e só
enviar
quando o mesmo for 0. Neste caso, a única exceção será durante a
inicialização.
1_ Durante a inicialização enviar a seqüência correta das instruções
de inicialização conforme item 3.4
2_ Para programar caracteres na CGRAM, faça inicialmente o
endereçamento da mesma.
3_ Após a escrita de dados na CGRAM envie a instrução 01, para
posicionar o cursor.
4_ Para escrever os caracteres especiais previamente gravados na
CGRAM, utilize os códigos de 00 até 07 correspondente aos endereços bases
de 40, 48 até 78 em hexa.
6 – COMANDOS ÚTEIS
Obs:
Após o endereçamento da CGRAM, o cursor se desloca para a primeira
posição da segunda linha (ou metade), portanto é recomendado enviar a
instrução 01 ou "limpa display e cursor home".
7 – CUIDADOS ESPECIAIS COM MÓDULOS LCD
a ) MANUSEIO
· Somente retire o módulo de sua embalagem protetora imediatamente
antes de sua instalação · Não guarde os módulos em recintos de alta
temperatura e alta umidade. A temperatura de armazenamento deverá estar
compreendida entre 5 e 30 oC.
· O LCD é coberto por uma lâmina plástica polarizada a qual não pode
ser riscada. Cuidado em seu manuseio. Para a limpeza da lâmina utilize
cotonetes embebido em benzina. Não utilize outros tipos de solventes.
· Observe cuidadosamente os procedimentos de controle anti-estático
quando manusear os módulos. Eles incorporam circuitos integrados CMOS LSI
os quais são sensíveis à descarga eletrostática. Não toque nos terminais do
conector, trilhas do circuito impresso e/ou terminais do CI.
b) INSTALAÇÃO
· Nunca desmonte o módulo
· Use uma estação de solda aterrada para soldagem de conectores ou
terminais.
· montador deverá também ser convenientemente aterrado.
· Sempre que o projeto o permita, instale o módulo atrás de uma janela
protetora de plástico ou vidro.
· Somente retire a fita adesiva que protege a lâmina plástica frontal
imediatamente antes de seu uso.
8 – OPERAÇÃO
· Nunca instale ou desconecte o módulo com sua alimentação ligada.
· Sempre opere os módulos respeitando sua gama de temperatura de
operação.
· Observe cuidadosamente os valores das tensões de alimentação e os
níveis dos sinais de controle.
· Ajuste a tensão no pino 3 (V0) para obter o contraste mais
conveniente para uma dada aplicação.
9 – Software de Teste do LCD
;****************** Programa de Escrita em LCD *******************
;*
*
;* POR: MILTON BARREIRO JUNIOR *
;* DATA: JUNHO DE 2006
*
;************************************************************************
;******************** Declaração de Variáveis ***********************
;* DEFINIÇÃO DOS I/O'S DE CONEXÃO DO LCD *
;************************************************************************
DISPLAY EQU P2 ;Define port P2 como bits de dados do LCD
RS EQU P3.5 ;Define P3.5 como bit RS do LCD
RW QUE P3.6 ;Define P3.6 como bit RW do LCD
EN EQU P3.7 ;Define P3.7 como bit EN do LCD
ORG 0000H
LJMP START
ORG 0050H
START: MOV SP, #40H ;Ajusta Stack Pointer
;************************** Parâmetros do LCD **************************
;* DEFINE MODO DE OPERAÇÃOO DO LCD *
;***************************************************************************
*
CLR EN ;Bit EN=0
CLR RS ;Bit RS=0
CLR RW ;Bit RW=0
MOV A, #38H ;Define LCD como matriz 7x5 pixels e 8
bits de dados
LCALL CMD ;Escreve comando no LCD
MOV A, #0EH ;Liga LCD e ativa cursor
LCALL CMD ;Escreve comando no LCD
MOV A, #06H ;Cursor deslocando para a direita
LCALL CMD ;Escreve comando
MOV A, #01H ;Limpa LCD
LCALL CMD ;Escreve comando
;******************************** Escreve no LCD
*******************************
;* ROTINA DE ESCRITA DE MENSAGENS NO LCD *
;***************************************************************************
********
WRITE: MOV A, #80H ;Posiciona LCD no primeiro caractere
na primeira linha
LCALL CMD ;Escreve comando
MOV DPTR, #MSG1 ;Movimenta inicio da tabela da
primeira mensagem para o DPTR
LCALL MSG ;Escreve primeira mensagem
MOV A, #0C0H ;Posiciona LCD no primeiro caractere
da segunda linha
LCALL CMD ;Escreve comando
MOV DPTR, #MSG2 ;Movimenta inicio da tabela da
segunda mensagem para o DPTR
LCALL MSG ;Escreve segunda mensagem
LJMP WRITE
;************************* Escreve Comandos no LCD
*************************
;* ENVIA COMANDOS DE ESCRITA NO LCD
*
;***************************************************************************
********
CMD: SETB EN ;Esse bloco de instruções é
CLR RS ;responsável pela escrita de
MOV DISPLAY,A ;comandos e dados no LCD
LCALL DELAY
CLR EN
LCALL DELAY
RET
MSG: MOV R1, #00H
WRCHAR: MOV A, R1
INC R1
MOVC A, @A+DPTR
CJNE A, #'$', NEXTCHAR
RET
NEXTCHAR: SETB EN
SETB RS
MOV DISPLAY,A
LCALL DELAY
CLR EN
LCALL DELAY
LJMP WRCHAR
;******************************** Rotina de Delay
********************************
;* ROTINA QUE CONTA TEMPO DE 10mS PARA ESCRITA NO LCD *
;***************************************************************************
********
DELAY: MOV TMOD, #11H ;Essa rotina tem como objetivo
MOV TCON, #00H ;contar tempo de 10mS de atrazo
MOV TH0, #0D8H ;para que o LCD seja capaz de
MOV TL0, #0F0H ;ler comandos e dados
CLR TF0
SETB TR0
JNB TF0, $
CLR TF0
CLR TR0
RET
;****************************** Tabela de Mensagens
**************************
;* MENSAGENS A SEREM ESCRITAS NO LCD *
;* DEVEM SER ESCRITAS NO FINAL DO PROGRAMA *
;***************************************************************************
********
MSG1: DB " TESTE DO $" ;Tabela da primeira mensagem
MSG2: DB " LCD OK $" ;Tabela da segunda mensagem
END ;Fim de programa
10 – Software de teste do teclado
; ROTINA DE LEITURA DE TECLADO MATRICIAL 4X3, KIT ETE JORGE STREET
; CONFIGURAÇÃO DO TECLADO
; P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0
; L4 L3 L2 L1 C3 C2 C1 -
TECLADO EQU P1 ;DEFINIR END PORT ONDE ESTÁ O TECLADO
MARCTEC EQU 23H ;MARCADOR DE MEMORIA
; OBS: ALTERA REGS A, ACC E R7
MOV SP,#40H
; ********************** EXEMPLO DE ROTINA DE LEITURA DE TECLADO
********************
VOLTA: LCALL VETEC
CJNE A, #0FH, ESC
LJMP VOLTA
ESC: MOV P3, A
LJMP VOLTA
;***************************************************************************
******************************
;*********** SUBROTINAS DO TECLADO (COLOCAR NO FINAL DO PROGRAMA)
**********
; RETORNO TECLA ACIONADA OU OFH SEM TECLA
VETEC: MOV TECLADO, #0FH
NOP
NOP
MOV A, TECLADO
CJNE A, #0FH, VETEC1
RET
VETEC1: LCALL DETEC
PUSH ACC
LCALL ESTEC
POP ACC
RET
DETEC: MOV MARCTEC, #7FH
DETEC1: MOV TECLADO, MARCTEC
NOP
NOP
MOV A, TECLADO
CJNE A, MARCTEC, VETEC0
MOV A, MARCTEC
RR A
MOV MARCTEC, A
CJNE A, #0F7H, DETEC1
RET
VETEC0: MOV MARCTEC, A
MOV DPTR, #TABTEC
MOV R7, #00H
VETECA: MOV A, R7
MOVC A, @A+DPTR
CJNE A, MARCTEC, VETECB
MOV A, R7
RET
VETECB: INC R7
SJMP VETECA
ESTEC: MOV R0, #02H
LCALL AT50R0
VESTEC: MOV TECLADO, #0FH
NOP
NOP
MOV A, TECLADO
CJNE A, #0FH, VESTEC
RET
;****************************** SUBROTINA DE ATRASO 50MS X R0
******************************
AT50R0: MOV TH0, #3CH
MOV TL0, #0B0H
MOV TMOD, #11H
SETB TR0
CLR TF0
ATR1: JNB TF0, ATR1
DJNZ R0, AT50R0
CLR TF0
CLR TR0
RET
;***************************************************************************
******************************
;**************** TABELA DE TECLAS (COLOCAR NO FINAL DO PROGRAMA)
***************
TABTEC: DB 7BH,0EDH,0EBH,0E7H,0DDH,0DBH,0D7H,0BDH,0BBH,0B7H,7DH,77H
;***************************************************************************
******************************
END
11 – Rotina exemplo de transmissão serial
;******************************** Programa de Transmissão Serial
**********************************
;* POR: MILTON BARREIRO JUNIOR
*
;* DATA: OUTUBRO DE 2006
*
;***************************************************************************
******************************
;************************************* Declaração de Variáveis
***************************************
;* CONFIGURAÇÃO DO CANAL SERIAL E TAXA DE TRANSMISSÃO
*
;***************************************************************************
******************************
ORG 0000H
LJMP START
ORG 0050H
START: MOV SP, #40H ;Ajusta Stack Pointer
MOV TCON, #00H ;Zera Flags dos Timers
MOV PCON, #00H ;Define PCON.7 como ZERO (SMOD
= 0 para cálculo da Taxa)
MOV TMOD, #21H ;Configura Timer 1 no
modo 2 e Timer 0 no modo 1
MOV TH1, #152 ;Carrega TH1 e TL1 com
152d
MOV TL1, #152 ;para 300bps de Taxa
MOV SCON, #40H ;Configura Canal Serial no
modo 1
SETB TR1
;*************************************** Rotina de Transmissão
**************************************
DENOVO: MOV DPTR, #MSG
PROXIMO: CLR A
MOVC A, @A+DPTR
CJNE A, #'$', ENVIA
LJMP DENOVO
ENVIA: MOV SBUF, A
JNB TI, $
CLR TI
INC DPTR
LJMP PROXIMO
;***************************************************************************
******************************
;*********************************** Tabela de String a Transmitir
***********************************
MSG: DB " Teste de Transmissão Serial $" ;Tabela da primeira
mensagem
;***************************************************************************
*****************************
END ;Fim de programa
12 – Programa exemplo conversão BCD para 7 Segmentos
;**************** PROGRAMA CONVERSÃO BCD PARA 7 SEGMENTOS
******************
;* POR: MILTON BARREIRO JUNIOR EM: JUNHO DE 2006 *
;***************************************************************************
**************************
;***************************************************************************
**************************
;* ROTINA DE CONVERSÃO DE BCD PARA 7 SEGMENTOS
*
;***************************************************************************
**************************
CONVERTE: ANL A, #00001111B ;ACC Recebe o valor BCD
MOV DPTR, #TABDISP ;a ser convertido de
MOVC A, @A+DPTR ;para 7 Segmentos
RET
;***************************************************************************
**************************
;***************************************************************************
**************************
;* TABELA DE CONVERSÃO DECIMAL E HEXADECIMAL PARA 7 SEGMENTOS *
;***************************************************************************
**************************
TABDISP: DB 11000000B ;Tabela
DB 11111001B ;de
DB 10100100B ;valores
DB 10110000B ;para
DB 10011001B ;display
DB 10010010B ;7 segmentos
DB 10000010B ;anodo
DB 11111000B ;comum
DB 10000000B ;que
DB 10011000B ;vai
DB 11001000B ;de
DB 10000011B ;zero a nove em decimal,
DB 11000110B ;até
DB 10100001B ;F
DB 10000110B ;em
DB 11000000B ;Hexadecimal
END ;Indica fim de programa ao compilador
13 – Exemplo didático de um frequencímetro (0 – 999Hz)
;*********************** PROGRAMA FREQUENCÍMETRO *************************
;* ESSE FREQUENCÍMETRO MEDE E INDICA VALORES ATÉ 999Hz *
;* POR: MILTON BARREIRO JUNIOR EM: NOVEMBRO DE 2006 *
;***************************************************************************
***************
;UFREQ EQU R1 ;Incremento de unidade
;DFREQ EQU R2 ;Incremento de dezena
;CFREQ EQU R3 ;Incremento de centena
;***************************************************************************
***************
;* RESERVA ENDEREÇOS DOS VETORES DE INTERRUPÇÕES *
;***************************************************************************
***************
ORG 0000H
LJMP INICIO ;Busca linha de inicio
ORG 000BH
LJMP INTT0 ;Vetor de Int Timer 0
ORG 0013H
LJMP INTE1 ;Vetor de Int Ext 1
;***************************************************************************
****************
;* CARREGA VALORES INICIAIS DAS VARIÁVEIS *
;***************************************************************************
****************
ORG 0050H
INICIO: MOV IP, #00000010B ;Prioriza Int T0
SETB ET0 ;Habilita Int T0
SETB EX1 ;Habilita Int EX1
SETB EA ;Habilita Int Global
MOV SP, #40H ;Ajusta Stack Pointer
MOV TMOD, #11H ;Configura T0 e T1 no Modo 1
MOV TCON, #00000101B ;Modo de atuação das Interrupções
MOV TH0, #3CH ;Carrega inicio de contagem para
MOV TL0, #0B0H ;timer 0 contar 50mS
SETB TR0
;***************************************************************************
**************
;* ROTINA DE RESET DO FREQUENCÍMETRO
*
;***************************************************************************
**************
MOV R0, #00H
MOV R1, #00H
MOV R2, #00H
MOV R3, #00H
MOV R4, #00H
MOV R5, #00H
MOV R6, #00H
;***************************************************************************
**************
;* ROTINA DE MULTIPLEXAÇÃO DOS DISPLAYS *
;* MOSTRA VALORES DE FREQUENCIA MEDIDA
*
;***************************************************************************
**************
DISPLAY: MOV A, R4 ;Carrega no ACC valor de Unidade de
Segundos
LCALL CONVERTE ;Converte Decimal para 7 Segmentos
SETB P2.2 ;Desliga Displays não utilizados
MOV P0, A ;Mostra Unidade de Segundos
CLR P2.0 ;Liga Digito Unidade de Segundos
ACALL TEMPO ;Tempo Display ativo
MOV A, R5 ;Carrega no ACC valor de Dezena de
Segundos
LCALL CONVERTE ;Converte Decimal para 7 Segmentos
SETB P2.0 ;Desliga Displays não utilizados
MOV P0, A ;Mostra Dezena de Segundos
CLR P2.1 ;Liga Digito Dezena de Segundos
ACALL TEMPO ;Tempo Display ativo
MOV A, R6 ;Carrega no ACC valor dos Minutos
LCALL CONVERTE ;Converte Decimal para 7 Segmentos
SETB P2.1 ;Desliga Displays não utilizados
MOV P0, A ;Mostra Minutos
CLR P2.2 ;Liga Digito Minutos
ACALL TEMPO ;Tempo Display ativo
LJMP DISPLAY
;***************************************************************************
***************
;* TRATAMENTO DA INTERRUPÇÃO DO TIMER 0 E CRONÔMETRO *
;***************************************************************************
***************
INTT0: CLR TR0 ;Trata interrupção Int T0
MOV TH0, #3CH ;para base de tempo de 1s
MOV TL0, #0B0H
SETB TR0
INC R0
CJNE R0, #20, SAI
MOV A, R1
MOV R4, A
MOV A, R2
MOV R5, A
MOV A, R3
MOV R6, A
MOV R0, #00H
MOV R1, #00H
MOV R2, #00H
MOV R3, #00H
SAI: RETI
;***************************************************************************
***************
;* TRATAMENTO DA INTERRUPÇÃO EXTERNA INT_1 *
;***************************************************************************
***************
INTE1: INC R1
CJNE R1, #10, ESC
MOV R1, #00
INC R2
CJNE R2, #10, ESC
MOV R2, #00
INC R3
CJNE R3, #10, ESC
MOV R3, #00
ESC: RETI
;***************************************************************************
***************
;* ROTINA DE CONVERSÃO DE BCD PARA 7 SEGMENTOS *
;***************************************************************************
***************
CONVERTE: ANL A, #00001111B ;Rotina de
MOV DPTR, #TABDISP ;Conversão
MOVC A, @A+DPTR ;Decimal para 7 Segmentos
RET
;***************************************************************************
***************
;* TEMPO DE AMOSTRAGEM DOS DÍGITOS *
;***************************************************************************
***************
TEMPO: MOV TH1, #0D8H ;Carrega inicio de contagem para
MOV TL1, #0F0H ;timer 1 contar 10mS
CLR TF1
SETB TR1
JNB TF1, $
RET
;***************************************************************************
***************
;* TABELA DE CONVERSÃO DECIMAL E HEXADECIMAL PARA 7 SEGMENTOS *
;***************************************************************************
***************
TABDISP: DB 11000000B ;Tabela
DB 11111001B ;de
DB 10100100B ;valores
DB 10110000B ;para
DB 10011001B ;display
DB 10010010B ;7 segmentos
DB 10000010B ;anodo
DB 11111000B ;comum
DB 10000000B ;que
DB 10011000B ;vai
DB 11001000B ;de
DB 10000011B ;zero a nove em decimal,
DB 11000110B ;até
DB 10100001B ;F
DB 10000110B ;em
DB 11000000B ;Hexadecimal
END ;Indica fim de programa ao compilador
14 – Exemplo de rotina para teclado matricial 4x4
;************************ Programa de Teclado Matricial
************************
;* POR: MILTON BARREIRO JUNIOR
*
;* DATA: OUTUBRO DE 2006
*
;* FONTE: www.8052.com
;***************************************************************************
*********
;******************** CONFIGURAÇÃO DO TECLADO (MATRIZ 4X4)
*********************
;
;P1.0 ---------------------------\
; "
;P1.1 -----------------------\
; " "
;P1.2 -------------------\
; " " "
;P1.3 ---------------\
; " " " "
;
;P1.7 -------------- 1 - 2 - 3 - A ---
;
;P1.6 -------------- 4 - 5 - 6 - B ---
;
;P1.5 -------------- 7 - 8 - 9 - C ---
;
;P1.4 -------------- * - 0 - # - D ---
; " " " "
;
;***************************************************************************
**********
;********************** Define o Port e Memoria das Teclas
*********************
KBOARD EQU P1 ;Teclado Matricial em P1
MEMKEY EQU R1 ;Memória de tecla pressionada
;***************************************************************************
**********
MOV SP, #40H ;Ajusta STACK POINTER
;******************* Loop de Leitura do Teclado Matricial
**********************
KEY_B: LCALL BUSCA
CJNE A, #0FH, SAIDA
LJMP START
SAIDA: MOV P3, A
LJMP KEY_B
;***************************************************************************
**********
;************************ SUBROTINAS DO TECLADO *************************
; devem ser inserida no final do programa
; RETORNA TECLA ACIONADA OU OFH SEM TECLA ACIONADA
;***************************************************************************
**********
BUSCA: MOV KBOARD, #0FH ;Carrega P1 com 0FH
NOP
NOP
NOP
NOP
MOV A, KBOARD ;Le teclado e salva no
Acumulador
CJNE A, #0FH, SELECT ;Se valor lido igual 0Fh,
retorna para loop de leitura
RET
SELECT: LCALL LOOP
PUSH A
LCALL DEBOU
POP A
RET
LOOP: MOV MEMKEY, #7FH
LOOP1: MOV KBOARD, MEMKEY
NOP
NOP
NOP
NOP
MOV A, KBOARD
CJNE A, MEMKEY, PROCURA
MOV A, MEMKEY
RR A
MOV MEMKEY, A
CJNE A, #0F7H, LOOP1
RET
PROCURA: MOV MEMKEY, A
MOV DPTR, #TABKEY
MOV R7, #00H
NOVO: MOV A, R7
MOVC A, @A+DPTR
CJNE A, MEMKEY, PROXIMA
MOV A, R7
RET
PROXIMA: INC R7
LJMP NOVO
;***************************************************************************
****
;************************** DEBOUNCE DE 50mS **************************
DEBOU: MOV TH0, #3CH
MOV TL0, #0B0H
MOV TMOD, #11H
SETB TR0
CLR TF0
JNB TF0, $
CLR TF0
CLR TR0
RET
;***************************************************************************
***
;************************** TABELA DE TECLAS ***************************
TABKEY: DB 0EBH ;Tecla 0
DB 77H ;Tecla 1
DB 7BH ;Tecla 2
DB 7DH ;Tecla 3
DB 0B7H ;Tecla 4
DB 0BBH ;Tecla 5
DB 0BDH ;Tecla 6
DB 0D7H ;Tecla 7
DB 0DBH ;Tecla 8
DB 0DDH ;Tecla 9
DB 0E7H ;Tecla *
DB 0EDH ;Tecla #
DB 7EH ;Tecla A
DB 0BEH ;Tecla B
DB 0DEH ;Tecla C
DB 0EEH ;Tecla D
;***************************************************************************
**
END ;Final do Programa
15 – Programa exemplo de controle digital de temperatura
;****************************************************
; Controle digital de temperatura
; Software implementado por alunos do
; curso de Automação Industrial do CEFET (2006)
;
; Autores:
; Alessander Martins Leite
; Flávio Roberto dos Santos
; Maércio Litwin Camargo
;****************************************************
ORG 0000H ;Inicio do programa
MOV PSW, #10H
MOV R1, #3CH ;Temperatura=60 Graus Celsius
LJMP COMECO
ORG 0030H
COMECO: MOV SP, #40H
CLR P2.5
CLR P2.6
CLR P2.7
LCALL INIC_LCD
LCALL CLEAR_LCD
LCALL TEXTOS
LCALL LINHA2
LCALL TESTOC
LCALL POS0
LCALL SET_TEMP
LCALL VER_TEMP
LJMP $
;****************************************************
; Inicializa Display LCD
;****************************************************
INIC_LCD: SETB P2.5
CLR P2.7
MOV P0, #38H
LCALL TEMPO0
CLR P2.5
LCALL ESPERA_LCD
SETB P2.5
CLR P2.7
MOV P0, #0C0H
LCALL TEMPO0
CLR P2.5
LCALL ESPERA_LCD
SETB P2.5
CLR P2.7
MOV P0, #06H
LCALL TEMPO0
CLR P2.5
LCALL ESPERA_LCD
RET
;****************************************************
; Rotina para limpar o LCD
;****************************************************
CLEAR_LCD: SETB P2.5
CLR P2.7
MOV P0, #01H
LCALL TEMPO0
CLR P2.5
LCALL ESPERA_LCD
RET
;****************************************************
; Rotina para mudar para linha 2 do LCD
;****************************************************
LINHA2: SETB P2.5
CLR P2.7
MOV P0, #0C0H
LCALL TEMPO0
CLR P2.5
LCALL ESPERA_LCD
RET
;****************************************************
; Rotina para mudar de posição para
; ajustar a temperatura
;****************************************************
POS0: PUSH A
SETB P2.5
CLR P2.7
MOV P0, #8CH
LCALL TEMPO0
CLR P2.5
LCALL ESPERA_LCD
POP A
RET
;****************************************************
; Rotina para mudar de posição para
; controlar a temperatura
;****************************************************
POS1: PUSH A
SETB P2.5
CLR P2.7
MOV P0, #0CCH
LCALL TEMPO0
CLR P2.5
LCALL ESPERA_LCD
POP A
RET
;****************************************************
; Rotina TEMPO0 (1 segundo)
;****************************************************
TEMPO0: MOV PSW, #18H
MOV R0, #02H
MOV TMOD, #01H
NAO_AC0: MOV TH0, #0FFH
MOV TL0, #0FAH
SETB TR0
ESP0: JNB TF0, ESP0
CLR TF0
CLR TR0
DJNZ R0, NAO_AC0
MOV PSW, #10H
RET
;****************************************************
; Rotina TEMPO1
;****************************************************
TEMPO1: MOV PSW, #18H
MOV R0, #01H
MOV TMOD, #01H
NAO_AC1: MOV TH0, #0FFH
MOV TL0, #0FAH
SETB TR0
ESP1: JNB TF0, ESP1
CLR TF0
CLR TR0
DJNZ R0, NAO_AC1
MOV PSW, #10H
RET
;****************************************************
; Rotina de texto (ajuste)
;****************************************************
TEXTOS: MOV DPTR, #TEMPERATURAS
AS: MOV A, #00H
MOVC A, @A+DPTR
JZ FIMS
LCALL ESCRT
INC DPTR
JMP AS
FIMS: RET
;****************************************************
; Rotina de texto (controle)
;****************************************************
TEXTOC: MOV DPTR, #TEMPERATURAC
AC: MOV A, #00H
MOVC A, @A+DPTR
JZ FIMC
LCALL ESCRT
INC DPTR
JMP AC
FIMC: RET
;****************************************************
; Rotina de texto
;****************************************************
AU_TS: MOV DPTR, #ATEMPERATURA
AT: MOV A, #00H
MOVC A, @A+DPTR
JZ AFIM
LCALL ESCRT
INC DPTR
JMP AT
AFIM: RET
;****************************************************
; Rotina para setar a temperatura
;****************************************************
SET_TEMP: MOV PSW, #10H
MOV R0, #11H
MOV A, @R0
LCALL ASCI
LCALL ESCR
RET
ESCR: MOV PSW, #10H
MOV R0, #17H
ESCRV: SETB P2.5
SETB P2.7
MOV A, @R0
ADD A, #30H
MOV P0, A
LCALL TEMPO0
CLR P2.5
LCALL ESPERA_LCD
DEC R0
CJNE R0, #14H, ESCRV
LCALL TEMPO0
RET
;****************************************************
; Rotina de escrita
;****************************************************
ESCRT: SETB P2.5
SETB P2.7
MOV P0, A
LCALL TEMPO0
CLR P2.5
LCALL ESPERA_LCD
RET
;****************************************************
; Rotina de espera LCD
;****************************************************
ESPERA_LCD: SETB P2.5
SETB P2.6
CLR P2.7
MOV P0, #0FFH
ESP: LCALL TEMPO1
JB P0.7, ESP
CLR P2.5
CLR P2.7
CLR P2.6
RET
;****************************************************
; Rotina que le P3 e converte para ASCII
;****************************************************
VER_TEMP: MOV A, P3
MOV PSW, #10H
LCALL VER_C
LCALL ASCI
LCALL POS1
LCALL ESCR
LCALL M_T_S
JMP VER_TEMP
;****************************************************
; Rotina para alterar a temperatura
;****************************************************
M_T_S: JNB P2.0, AU_T
RET
AU_T: LCALL INIC_LCD
LCALL CLEAR_LCD
LCALL AU_TS
LCALL POS0
LCALL I_D
;****************************************************
; Incrementa ou decrementa temperatura
;****************************************************
I_D: MOV PSW, #10H
JNB P2.0, $
V_V: JB P2.1, D_TS
JNB P2.1, $
LCALL MAI_T
LCALL SET_TEMP
LJMP I_D
MAI_T: CJNE R1, #0FFH, MAI_TN
RET
MAI_TN: INC R1
RET
D_TS: JB P2.2, S_TS
JNB P2.2, $
LCALL MEI_T
LCALL SET_TEMP
LJMP I_D
S_TS: JB P2.0, V_V
JNB P2.0, $
LCALL COMECO
MEI_T: CJNE R1, #00H, MEI_TN
RET
MEI_TN: DEC R1
RET
;****************************************************
; Converte para código ASCII
;****************************************************
ASCI: MOV PSW, #10H
MOV R5, #00H
MOV R6, #00H
MOV R7, #00H
COMPA: CJNE A, #00H, UND
RET
UND: DEC A
INC R5
CJNE R5, #0AH, COMPA
INC R6
MOV R5, #00H
CJNE R6, #0AH, COMPA
INC R7
MOV R6, #00H
LJMP COMPA
;****************************************************
; Rotina para verificar a temperatura
;****************************************************
VER_C: MOV PSW, #10H
PUSH A
PUSH 11H
CJNE A, 11H, N
CLR P1.0
POP 11H
POP A
RET
N: JZ X
CJNE R1, #00H, DIF
CLR P1.0
POP 11H
POP A
RET
X: SETB P1.0
POP 11H
POP A
RET
DIF: DEC A
DEC R1
JZ X
CJNE R1, #00H, DIF
CLR P1.0
POP 11H
POP A
RET
;****************************************************
; Tabelas de mensagens
;****************************************************
TEMPERATURAS: DB "Temp_Setada:",00H
TEMPERATURAC: DB "Temp_Contr.:",00H
ATEMPERATURA: DB "Mudar_Temp.:",00H
END
-----------------------
&'()*0QRWZ ƒ ÍÎÏÑÒÔÝÞáâã
1 2 7
òáÑ¿°¤–…¤°vd°¤°¤°¤°…–…–…òáÑ¿°¤V…¤hðCõCJOJ[?]QJ[?]^J[?]aJ#hb1 h1o"5?CJ$OJ[?]Q
J[?]^J[?]aJ$h1o"5?CJ$OJ[?]QJ[?]^J[?]aJ$
hb1 h1o"CJOJ[?]QJ[?]^J[?]aJh1o"CJOJ[?]QJ[?]^J[?]aJh1o"OJ[?]QJ[?]^J[?]aJhÜ2#h
1o"OJ[?]QJ[?]^J[?]aJ"hÜ2#
Figura 3 - Sistema baseado na CPU 8051 com módulo LCD
b7
b0
b0
b7
b0
b7
Cy
b0
b7
Cy
Apostila sobre Microcontroladores família 8051, apresentada aos cursos
de Eletrônica, Telecomunicações e Automação Industrial da Escola Técnica
Estadual Getúlio Vargas, com o propósito de auxiliar nas aulas teóricas e
práticas.
-----------------------