Prévia do material em texto
Microcontrolador 8051 – Hardware Curso Completo – Hardware – Software - Interfaceamento 1INTRODUÇÃO Na Década de 70 começaram a ser utilizados microprocessadores em microcomputadores para uma maior eficiência no processamento de dados. O microprocessador Intel foi um dos precursores e, a partir daí, houve uma preocupação em melhorar cada vez mais o sistema de processamento de dados através desses componentes. Baseado na arquitetura de um microprocessador e seus periféricos, foi criado um componente que (fisicamente em uma unidade) comportasse todo um sistema que equivalesse a um microprocessador e seus periféricos; assim surgiu o microcontrolador. 1.1Unidade Central de Processamento (CPU) A unidade central de processamento controla todas as funções realizadas pelo sistema. A CPU de qualquer sistema de computador contém os seguintes grupos de unidades Funcionais: Registradores e contadores Os registradores e contadores são unidades funcionais usadas para armazenamento temporário de bits dentro da CPU. Unidade lógica e aritmética A unidade lógica e aritmética é a unidade funcional da CPU que executa operações lógicas e aritméticas entre palavras binárias, gerando uma outra palavra na saída. Unidade de controle e sincronização A unidade de controle e sincronização coordena e controla todas as unidades funcionais em uma seqüência lógica e sincronizada. 1.2Processamento O processador ou unidade central de processamento (CPU) é a parte do sistema que faz o processamento das informações para que as instruções sejam executadas; as instruções devem estar armazenadas na memória de programa em seqüência, formando assim o programa. A CPU possui um registrador chamado de CONTADOR DE PROGRAMA (PC) que contém o endereço da próxima instrução que deve ser executada. Toda vez que uma instrução é retirada da memória pela unidade central de processamento, automaticamente o contador de programa é incrementado para que, após o processamento desta instrução, quando a CPU for buscar a próxima instrução, basta usar o endereço contido no contador de programa. Toda vez que a CPU é ligada ou resetada, automaticamente o seu contador de programa é zerado, desta forma, a primeira tarefa que a CPU irá realizar é a execução da instrução contida na posição de memória de endereço “0000”. Cada instrução possui duas fases distintas: o ciclo de busca e o ciclo de execução. Durante o ciclo de uma instrução a CPU faz com que o conteúdo do contador de programa seja colocado no barramento de endereços, endereçando, desta maneira, a posição de memória que contém a instrução que deve ser executada. 1.3Unidades de Entrada e Saída (I/O) As unidades de entrada/saída são os meios pelos quais o usuário se comunica com o sistema. Essas unidades possuem interfaces que permitem a conexão com dispositivos chamados de periféricos, tais como teclado, LCDs, etc. 1.4Arquitetura A performance do microcontrolador depende da sua arquitetura interna, ou seja, do modo em que o microcontrolador foi projetado tanto para o hardware como para software. No hardware apresentaremos a arquitetura Von-Neumann, na qual se refere o software CISC. Arquitetura Von-Neumann Na arquitetura Von-Neumann, os barramentos de dados e endereços são compartilhados entre memórias de programas e memórias de dados na comunicação com a CPU. Nesse tipo de arquitetura, quando a CPU está acessando a memória de programa não pode acessar a memória de dados, porque usa os mesmos barramentos para as duas memórias. CISC (Complex Instruction Set Computer) CISC: Computador com Set de Instrução mais Complexo, quanto maior a complexidade da instrução que deve ser executada, mais espaço ela ocupa no chip. Desse modo, chegará um momento que passaremos e ter um set de instruções tão grande que começará a afetar o desempenho, dificultando a possibilidade de implementar outras funções importantes. Ter um complexo (grande) set de instruções “CISC” nem sempre é interessante para um bom desempenho do processador. Numa análise feita pelo laboratório da IBM sobre como estavam sendo usados os diversos tipos de instruções, concluíram que num microprocessador que usava um set de instruções de, por exemplo, 200 instruções, a maior parte do processamento era feita apenas com umas 10 instruções. Uma grande parte das instruções era pouco usada, às vezes até uma única vez em um longo programa, de modo que elas poderiam ser implementadas pelas instruções básicas mais usadas. Daí o aparecimento da nova arquitetura com o set de instruções reduzido “RISC” (característico dos microcontroladores da família PIC). 1.5Memórias Memórias são os dispositivos que armazenam informações e são usadas em todos os sistemas microcontrolados. Existem vários tipos de memórias que podem ser classificadas por vários itens diferentes. 1.5.1Acesso As memórias armazenam informações em lugares que se denominam “localidade de memória”. Cada localidade de memória guarda um conjunto de bits e tem um endereço. No acesso desses endereços podemos analisar: -O tempo de acesso: é o tempo que a memória necessita para que sejam escritos ou lidos os dados em suas localidades -Acesso seqüencial: nas memórias que tem acesso seqüencial, para acessar um endereço de uma certa localidade, precisa-se passar por endereços intermediários (as memórias mais comuns desse tipo são as que utilizam fita magnética); -Acesso aleatório: as memórias que utilizam esse tipo de acesso são as memórias que permitem que seja acessado qualquer dado em qualquer endereço sem a necessidade de ter que passar por outros endereços intermediários. 1.5.2Volatilidade -Memórias voláteis: são aquelas que perdem as informações quando é cortada sua alimentação. São memórias que geralmente usam como elemento de memória o Flip-Flop. -Memórias não voláteis: são memórias que mesmo desligando-se sua alimentação, não perdem as informações armazenadas. Dentre essas se destacam as magnéticas e as eletrônicas ROM, PROM, EPROM, EEPROM, e outras. 1.5.3Memórias de escrita/leitura ou somente leitura -Escrita/Leitura: são memórias que podem ser acessadas pela CPU tanto para leitura quanto para escrita; elas são usadas para armazenar dados que serão utilizados durante a execução do programa (memórias RAM, EEPROM) -Somente Leitura: são a memórias que armazenam o programa, ou seja, são as memórias que só serão lidas pela CPU e que já vêm gravadas para o sistema (memórias ROM, PROM, etc). 1.5.4Tipos de armazenamento -Estáticas: memórias estáticas são aquelas nas quais as informações permanecem armazenadas enquanto não houver escrita ou não faltar energia. -Dinâmicas: memórias dinâmicas são memórias que perdem informações armazenadas mesmo com alimentação. Na RAM dinâmica (ou DRAM) isso acontece porque cada célula tem um transistor MOSFET e um capacitor que armazena um dado (1 bit). 1.5.5Tipos de Memórias Veremos a seguir, alguns tipos de memórias existentes no mercado e que são muito utilizadas: Memórias RAM (Random Access Memory) Essas memórias são de acesso aleatório, que podem ser acessadas a qualquer momento e em qualquer endereço. Elas podem ser estáticas ou dinâmicas e também podem ser gravadas pelo sistema com a tensão de 5v. São memórias consideradas voláteis. Memórias ROM (Read Only Memory) Essas memórias são utilizadas somente para a leitura. Memórias PROM (programable Read Only Memory) Essas memórias são utilizadas no sistema somente para leitura; geralmente usadas como memórias de programa, só podem ser gravadas com gravadores específicos e só uma vez. São a memórias não Voláteis. Memórias EPROM( Erasable Programmable Read Only Memory) Essas memórias são utilizadas no sistema somente para leitura, também empregadas como memórias de programa e só podem ser gravadas com gravadores específicos. Podem ser apagadas por raios ultravioleta e regravadas por muitas vezes. São chamadas memórias não voláteis. Memórias EEPROM ou E2PROM (Electrically Erasable Programmable Read Only Memory) Essas memórias podem ser usadas no sistema tanto para leituracomo para escrita. Podem ser gravadas com programadores ou pelo sistema; são apagadas eletricamente e regravadas por muitas vezes; são consideradas memórias não voláteis. Memórias PEROM (programable Read Only Memory) Uma linha de memórias programáveis apenas para leitura, de 3v e 5v, apenas dentro do sistema. Fabricadas com avançada tecnologia CMOS, não voláteis, suas características incluem: -Operação de leitura e programação em apenas 3v e 5v; -Proteção de dados de software e hardware; -Operação de programação por setor -1000 ciclos de programa; -Retenção de dados de 10 anos; -Baixa dissipação de potência; -Tempo de ciclo de programa rápido; -Detecção de fim de programa. Memórias FLASH A memória FLASH é um dispositivo de armazenamento confiável, não volátil, de boa relação custo/benefício e que possui características de leitura da EPROM, EEPROM e SRAM, porém quando se aplica 12v sobre o dispositivo, este pode ser gravado com base em bytes. No caso da memória FLASH – 5v estes dispositivos foram projetados para serem programados dentro do sistema com fornecimento padrão de 5V. Em programadores de EPROM convencionais não há necessidade de 12vpp, nem para programação, nem para apagamento. É composta de uma arquitetura de apagamento de setor (qualquer combinação pode ser apagada simultaneamente) e 100.000 ciclos de apagamento/programação. Memória FLASHFILE A memória FLASHFILE, simetricamente bloqueada, da intel, oferece uma solução não volátil com leitura e programação de mais alta densidade para armazenamento em massa. O armazenamento de aplicação de software e a operação com código de sistema em RFAs (Residential Flash Arrays) proporcionam execução instantânea , rápida e local (in Place). RFAs são protegidas também contra envelhecimento do software, já que este pode ser atualizado no sistema. O software RFA prolonga a vida da bateria e aumenta a confiabilidade do sistema através da redução do número de acessos ao disk-drive. 100.000 ciclos de apagamento/programação. Memórias Seriais Estes dispositivos são de tamanho reduzido podendo ser ligados a um barramento serial I2C (Inter-Integrated Circuit Bus) ou SPI (Serial Peripheral Interface) junto com outros dispositivos seriais, com muitas vantagens em relação às memórias paralelas. 2ESTRUTURA BÁSICA DA FAMÍLIA 8051 2.1A Família MCS-51 A família Intel MCS-51 é dez vezes mais rápida que sua antecessora, a família MCS- 48. A MCS-51 contém vários componentes similares, cada um indicado para um tipo de sistema específico. Os diferentes membros da família MCS-51 estão listados na tabela 2.1. O 8051 é o componente base dessa família, tendo dois similares próximos, o 8751 e o 8031, e uma versão com mais memória, o 8052. Toda a versão contém a mesma CPU e instruções. O 8051 possui 4KB de ROM, a qual é gravada no processo de fabricação do chip. Já no 8751, a ROM é substituída por uma EPROM, que pode ser programada e apagada. O 8031 é indicado para sistemas expandidos e usa memória de programa externa. Por último, pode-se destacar o 8052, que possui o dobro de memória ROM e RAM do 8051. Tabela 2.1: Membros da família 8051 MEMBRO TECNOLOGIA MEM. PROGRAMA MEM. DE DADOS (RAM) 8051 HMOS 4K – ROM 128 bytes 8031 HMOS Não tem 128 bytes 8751H HMOS I 4K – EPROM 128 bytes 80C51 CHMOS 4K – ROM 128 bytes 80C31 CHMOS Não tem 128 bytes 8052 HMOS 8K – ROM 256 bytes 8032 HMOS Não tem 256 bytes AT89C2051 CMOS 2K –FLASH 128 bytes AT89C51 CMOS 4K-FLASH 128 bytes AT89C52 CMOS 8K-FLASH 256 bytes Nesta apostila, não se pretende estabelecer os critérios usados na escolha deste ou daquele componente da família MCS-51. Pretende-se apenas estudar a arquitetura interna do chip 8051 e seus aspectos de programação, que são comuns a todos os membros da família MCS-51. Os microcontroladores MCS-51 são também fornecidos por outros fabricantes, além da Intel, e todos são totalmente compatíveis entre si. 2.2Recursos Gerais do 8051 A figura 2.1 mostra o diagrama de blocos do núcleo do 8051, enquanto a figura 2.2 mostra o diagrama de blocos detalhado do 8051. O microcontrolador 8051 possui: CPU de 8 bits otimizada para aplicações de controle; 32 linhas de E/S bidirecionais e individualmente endereçáveis; 4 Kbytes de memória de programa interna; 128 bytes de RAM interna, destinada a dados; 64 Kbytes endereçáveis de memória externa, de programa ou dados; 2 temporizadores/contadores de 16 bits cada um; Porta serial (UART) full-duplex, para comunicação com outro processador; 5 estruturas (fontes) de solicitação de interrupção, com 2 níveis de prioridade; Oscilador de clock interno; Freqüência de clock entre 1,2 MHz e 12 MHz. Figura 2.1 – Diagrama de blocos do 8051. O 8051 é um microcontrolador de 8 bits, pois tanto a ROM, RAM, ULA e via de dados manipulam informação de 8 bits. O seu conjunto de instruções é formado por 111 instruções, onde se incluem as de transferência de dados, aritmética, lógica, desvio de fluxo de programa e booleanas. Estas são instruções de manipulação de variáveis de um bit do 8051 (lógica de bit único). Figura 2.2 - Diagrama de blocos detalhado do 8051. 2.3Principais Vantagens do Microcontrolador 8051 Popular: prontamente disponível e amplo suporte. Gama completa de produtos de suporte estão disponíveis de graça e comercialmente, proporcionando economia real em termos de ferramentas de treinamento e suporte para software. Rápido e eficaz: a arquitetura se correlaciona de perto com o problema sendo solucionado (sistemas de controle). Instruções especializadas significam que menos bytes precisam ser buscados e menos jumps condicionais são processados. Baixo custo: alto nível de integração do sistema em um único componente. Poucos componentes a mais são necessários para se criar um sistema que funcione. Compatibilidade: opcodes e código binário são os mesmos para todas as variações do 8051, diferente de outras famílias de microcontroladores. Multi Sourced: mais de 12 fabricantes, centenas de variedades. Aperfeiçoamentos constantes: melhorias na manufatura aumentam a velocidade e reduzem o consumo de potência. Há ainda versões de 16 bits, de diversos fabricantes. 2.4Linguagens de Programação para o 8051 As linguagens mais utilizadas na programação da família MCS-51 são C, BASIC e Assembly. Especificamente para microcontroladores desta família, não tem surgido muito texto de apoio sobre linguagens de programação. Todos os livros sobre linguagem C que aparecem no mercado vêm repletos de exemplos clássicos de processamento de dados, os quais são, na sua grande maioria, impróprios para microcontroladores. 2.4.1Linguagem C C é uma linguagem que surgiu com o sistema operacional Unix. Ela é estruturada, produz um código compacto e permite atingir alguns detalhes de controle da máquina sem recorrer ao Assembly. Há seis fabricantes que oferecem compiladores C para microcontroladores da família MCS-51. Destes compiladores, o Archimedes e o Franklin estão no topo da lista. Após estes, vêm os da BTO/Tasking e Avocet. Isto para mencionar apenas os quatro mais conhecidos. 2.4.2Linguagem Assembly A linguagem Assembly do 8051 é semelhante a outras linguagens Assembly de microprocessadores. O conjunto de instruções dispõe de um maior número de operações para manipular bits que os microprocessadores usuais, mas o fato de ter diferentes regiões de memória torna as coisas mais complicadas. As instruções de movimentação de dados, lógicas e desvio de execução são geralmente similares as da maioria dos outros microprocessadores. Desta forma, para quem já trabalhou com linguagem Assembly de microprocessador, o processo é o mesmo, com suas vantagens e desvantagens. 2.4.3Linguagem Basic Basic atende bem ao seu propósito: ser uma linguagem de introdução à programação. Ela é muito fácil de se usar. O uso de uma nova variável faz com que esta variável persista pelo resto do programa. Erros podem ser detectados ao final de cada linha,ao invés de mostrá-los somente quando o programa termina de ser traduzido. Porém, existem duas razões pelas quais o Basic não é conveniente em sistemas dedicados. Em primeiro lugar, como ele é interpretado, ele é naturalmente lento. Cada linha deve ser convertida para o código de máquina toda vez que for executada. O processo de interpretação faz com que seja perdido muito tempo de processamento, que deveria ser usada para a aplicação propriamente dita. Existem versões do Basic compilado (QuickBasic, por exemplo), que evitam esse problema. Entretanto, não há nenhuma versão do Basic compilado para o 8051. Em segundo lugar, pode-se destacar a inconveniente simplificação no uso de variáveis.Todas as variáveis são, usualmente, implementadas como ponto-flutuante. Isto resulta na necessidade de se executar rotinas complexas, mesmo para valores tipo inteiro. Isto torna os programas lentos e grandes. Pode-se dizer que o Basic, no contexto de sistemas dedicados, deve ser indicado para aplicações onde a facilidade de programação seja mais importante que a eficiência ou velocidade. 3ORGANIZAÇÃO DE MEMÓRIA EM DISPOSITIVOS MCS – 51 3.1Separação Lógica de Memória de Programa e de Dados Toda a família MCS-51 possui espaços de endereçamento separados para programas e dados, isto é, uma memória de programa e uma memória de dados com endereços independentes (configuração Harvard). Essa separação permite que a memória de dados seja acessada por endereços de 8 bits, que podem ser mais rapidamente manipulados pela CPU, também de 8 bits. Entretanto, endereços de 16 bits também podem ser utilizados para a memória de dados, podendo ser gerados através do registrador DPTR (Data Pointer Register). O preço a pagar pela facilidade de manipulação dos endereços, dada pela separação lógica das memórias, é o de um aumento de complexidade no conjunto de instruções; historicamente, esta separação presente na maioria dos dispositivos INTEL foi a responsável pela criação da arquitetura CISC, que vem há tempos sendo superada pela maior elegância de soluções apresentada pela arquitetura RISC, que já está sendo utilizada até pela própria INTEL nos seus dispositivos mais recentes. 3.2Memória de Programa A memória de programa é composta por duas áreas distintas: 4KB de ROM interna e até mais 60KB externos. Entretanto, pode-se inibir os 4KB de ROM internos através do pino 31 (EA - External Access), ficando a memória externa com todo o espaço de endereçamento. A memória de programa pode ser apenas lida, não escrita. Existem até 64K de memória de programa acessáveis, sendo que os primeiros 4K são disponíveis internamente no 8051, e selecionáveis através do sinal EA . Os primeiros 4 Kbytes da memória de programas podem ser endereçados interna ou externamente. Se o pino EA estiver em nível alto, esses bytes são acessados no chip. Levando o pino EA a nível baixo, o acesso a tais bytes é feito na memória externa, como mostrado na figura 3. A Figura 3.2 mostra a configuração de hardware para a execução de programas externos; nesta configuração, duas das 4 portas de E/S disponíveis (Portas 0 e 2) são utilizadas com função de barramento de endereço/dados, ou seja, essas 16 linhas de E/S são dedicadas para desempenhar função de bus durante buscas na memória de programas. Isto se deve ao fato de que os endereços da memória de programa são sempre de 16 bits, mesmo que o tamanho real desta seja menor que 64K bytes. A porta 0 emite o byte menos significativo do contador de programas (PCL). Nesse momento o sinal ALE (Address Latch Enable) funciona como clock para o latch, armazenando o PCL. As linhas da Porta 0 entram em estado de alta impedância. Enquanto isso, a porta 2 emite o byte mais significativo do contador de programas (PCH). O latch e a porta 2 formam portanto o endereço necessário ao acesso da ROM externa. O dispositivo emite o sinal PSEN (Program Store Enable) para ler a memória de programa externa. Este sinal, em nível baixo, habilita a ROM à leitura. A porta 0 entra no modo entrada e a instrução da ROM do endereço correspondente é enviada a essa porta. Figura 3.1 – Estrutura de memória da família MCS-51. Figura 3.2 – Configuração de hardware para o uso de memória de programa externa. Evidentemente o ciclo de busca do 8051 é projetado de forma que os primeiros 4096 endereços de memória de programa sejam acessados internamente. Daí em diante, o ciclo de busca gera os sinais de controle necessários para acessar a memória de programa externa. Certas posições na memória de programa estão reservadas para situações específicas. Uma destas situações é a condição de “reset”, que força o fluxo de execução para o endereço 0000H. Normalmente, usa-se as três primeiras posições para efetuar o desvio para a rotina de inicialização. A seguir, estão alocadas as posições alvos de interrupções, ou seja, os endereços de 0003H a 0023H são reservados para cinco rotinas de tratamento de interrupção. Em cada uma dessas posições, deve-se armazenar a sub-rotina que atende à respectiva interrupção quando requisitada por um dispositivo. O espaçamento entre essas posições fixas é de 8 bytes. Na maioria das aplicações de controle, essas rotinas cabem inteiramente nesse intervalo, de outra forma faz-se necessário um jump nessas posições. A figura 3.3 mostra um mapa da parte inferior da memória de programa dos dispositivos MCS-51, com a localização dos vetores de interrupção. Após o reset, a CPU inicia a execução da posição 0000H. Figura 3.3 – Mapa da parte inferior da memória de programa. 3.3Memória de Dados A memória de dados ocupa, como já foi dito, um espaço de endereçamento separado da memória de programa, e até 64K bytes de RAM externa podem ser acessados neste espaço. Os 64 Kbytes de memória de dados externa são acessados pelo dispositivo através dos sinais RD/WR. Os sinais PSEN e RD podem ser injetados na entrada de uma porta AND e a saída dessa porta utilizada como sinal de requisição de leitura a uma memória externa de dados e programas convencional. A memória de dados, como mostra a figura 3.4, é composta por uma área interna formada por 128 bytes, mais os registros de função especial, e por até 64Kb de memória externa. Figura 3.4: Composição da memória de dados do 8051 De outra forma, pode-se visualizar a memória do 8051 como sendo parte interna e parte externa. A memória interna é constituída pelos 4 Kb de ROM, pelos 128 bytes de RAM e pelos registros da CPU. Já a memória externa é formada por até 60 Kb (ou até 64 Kb, caso o pino EA seja aterrado) de memória de programa, e por até 64 Kb de memória de dados. Caso o espaço de memória interna seja suficiente para determinada aplicação, o sistema pode trabalhar sem a memória externa. Os 64 Kb de memória externa de dados são acessados automaticamente quando a instrução MOVX (Move eXternal) for executada. Já os 128 bytes da RAM interna podem ser acessados por diferentes instruções, através de endereçamento direto ou indireto. Esta RAM interna pode ser subdividida em três segmentos que são: Banco de Registros: são quatro bancos de registros, numerados de 0 a 3, ocupando as posições de 0 até 1FH (32 bytes no total). Cada banco contém oito registros de um byte cada, numerados de 0 a 7. Por “default” o banco corrente é o 0, entretanto pode-se selecioná-lo por software, através de dois flags, RS0 e RS1, que fazem parte do registrador PSW, conforme a tabela 3.1. Tabela 3.1 - Mapeamento dos bancos de registros BANCO RS1 RS0 REGISTRADORES POSIÇÃO DE MEMÓRIA 3 1 1 R7,R6, . . .,R0 1FH,1EH, . . .,18H 2 1 0 R7,R6, . . .,R0 17H,16H, . . .,10H 1 0 1 R7,R6, . . .,R0 0FH,0EH, . . .,08H 0 0 0 R7,R6, . . .,R0 07H,06H, . . .,00H Área de bits Endereçáveis: este segmento é composto por 16 bytes, ocupando as posições de 20H a 2FH. Pode-se acessar os dados contidos neste segmento de duas formas: individualmente cada um dos 128 bits do segmento; ou em grupos de 8 bits, ou seja, byte a byte. A CPUdispõe de instruções específicas para o manuseio de bits, onde se designa diretamente o endereço do bit desejado. Área de Propósito Geral: os bytes localizados nos endereços de 30H até 7FH formam uma área de propósito geral, porém parte deste segmento é usado para acomodar a pilha do sistema. A figura 3.5 mostra a configuração de hardware para o acesso a até 2K de RAM externa. Neste caso a CPU está executando a partir da ROM interna. Note o modo de endereçamento paginado a que esta configuração se propõe, com o que apenas 11 linhas de E/S são utilizadas como barramento. O endereço pode ter largura de 1 ou 2 bytes. Quando utilizando 1 byte, uma ou mais outras linhas de E/S podem ser utilizadas, como mostrado na figura 3.5. Quando utilizando 2 bytes de largura, o byte mais significativo é enviado pela porta 2. Figura 3.5 – Configuração de hardware para o uso de memória de dados externa. O mapeamento da memória de dados interna é mostrado na figura 3.6. Ela é dividida em três blocos, referidos como 128-Inferior (Lower 128), 128-Superior (Upper 128) e espaço SFR (Special Function Register). Os registradores mapeados em memória ocupam os primeiros 32 bytes do bloco Inferior, agrupados em quatro bancos de 8 registradores (R0 a R7). Dois bits na Palavra de Status de Programa (PSW, Program Status Word) selecionam um dos bancos. Isto permite maior eficiência no espaço do código, uma vez que instruções que se referem a registradores são menores do que instruções de endereçamento direto. Figura 3.6 – Mapa da memória de dados interna. Os 16 bytes acima do banco de registradores formam o espaço de bits endereçáveis. O conjunto de instruções do 8051 inclui uma grande quantidade de instruções de um único bit, e os 128 bits dessa área podem ser acessados por essas instruções. O bloco 128-Inferior ocupa o intervalo de endereços de 00H até 7FH, e seu mapeamento é visto na Figura 3.7. Figura 3.7 – Mapeamento do bloco 128-Inferior. Os bancos são selecionáveis pelas instruções através de dois bits do registrador PSW. Os próximos 16 bytes acima dos bancos de registradores formam um espaço de memória endereçável-por-bit. Todos os bytes no 128-inferior podem ser acessados por endereçamento direto ou indireto; já o 128-Superior só pode ser acessado por endereçamento indireto, e ficam disponíveis como pilha nos dispositivos com 256 bytes de RAM. Mas o bloco 128-Superior não está implementado no 8051. Figura 3.8 – Estrutura simplificada do espaço SFR. A Figura 3.8 mostra a estrutura simplificada do espaço SFR; este inclui buffers (latches) de E/S, temporizadores, controles de periféricos, etc. Tais registradores só podem ser acessados por endereçamento direto, sendo que 16 endereços são simultaneamente endereçados-por-bit e endereçados-por-byte. O bloco SFR ocupa o espaço de endereçamento 80H a FFH. Tais registradores podem ser acessados exclusivamente por acesso direto. Todos os membros da família 8051 executam o mesmo conjunto de instruções classificadas como: aritméticas, lógicas, transferência de controle, transferência de dados e booleanas. Dispõem de uma variedade de modos de endereçamento à RAM interna. Suporte a variáveis de um bit também é disponível, permitindo manipulação direta em sistemas de controle e lógica que requerem processamento booleano. 3.4Descrição dos Registros de Função Especial Os registros mapeados em memória incluem os latches das portas de E/S, temporizadores/contadores, canal serial, registros ligados à unidade de lógica e aritmética (ULA), registros apontadores, registros usados no sistema de interrupção, além de outros registros de função especial. É importante ressaltar que, com exceção do contador de programa, todos os outros registros são mapeados em memória interna de dados. O 8051 possui 20 SFRs de 8 bits cada, mapeados em memória interna, e um contador de programa (PC) de 16 bits. Na tabela 3.2 estão relacionados os 20 SFRs com seus mnemônicos, nomes e endereços. Nesta tabela também estão destacados os registros que podem ser endereçados bit a bit. Tabela 3.2: Registros de função especial MNEMÔNICO NOME ENDEREÇO *ACC Accumulator 0E0H *B Register B 0F0H *PSW Program Status Word 0D0H SP Stack Pointer 81H DPTR Data PointerRegister DPL Data Pointer Low 82H DPH Data Pointer High 83H *P0 Port 0 80H *P1 Port 1 90H *P2 Port 2 0A0H *P3 Port 3 0B0H *IP Interrupt Priority 0B8H *IE Interrupt Enable 0A8H TMOD Timer Mode 89H *TCON Timer/Counter Control 88H TH0 Timer/Counter 0 – high 8CH TL0 Timer/Counter 0 – low 8AH TH1 Timer/Counter 1 – high 8DH TL1 Timer/Counter 1 – low 8BH *SCON Serial Control 98H SBUF Serial Buffer 99H PCON Power Control 87H Será feita agora uma descrição funcional dos registros do 8051. Contador de Programa (PC): os 16 bits deste registro controlam a seqüência na qual as instruções armazenadas na memória de programa serão executadas. Este registro é manipulado pelas instruções de transferência de fluxo (desvio), ou seqüencialmente incrementado, seguindo o fluxo normal de execução. Registro A ou ACC: é o tradicional acumulador, fortemente ligado à ULA. Registro B: é um acumulador auxiliar, usado principalmente nas instruções de multiplicação e divisão. Registro de flags (sinalizadores da CPU): os flags do 8051 fazem parte do registrador Program Status Word (PSW). Este byte, localizado no espaço SFR, contém alguns bits de status que refletem o estado de manipulação da informação e controle de operações da CPU. Mostrado na figura 3.9, o PSW contém os flags Carry (CY), Auxiliary Carry (AC) para operações BCD, Overflow (OV), Paridade (P), dois bits de seleção de banco de registradores (RS0 e RS1) e dois bits de status definidos pelo usuário. O bit de paridade reflete o número de ‘1’s no acumulador; se P = ‘1’, este número é ímpar e, se P = ‘0’, o conteúdo é par. Ou seja, o número de ‘1’s no acumulador mais P é sempre par. O bit de Carry, além de sua função tradicional em operações aritméticas, também tem função de “acumulador” em algumas operações booleanas. Figura 3.9 – Flags do registrador PSW. Apontador de Pilha (SP): como o próprio nome sugere, é o registro que aponta para o topo da pilha. É manipulado pelas instruções de chamada e retorno de sub-rotinas, além de instruções específicas para inserção ou retirada de dados da pilha. Por conter apenas 8 bits, este registro endereça apenas a memória RAM interna. Desta forma, a pilha do sistema fica limitada a esta área. Apontador de Dados (DPTR): é usado basicamente para endereçar conteúdos dentro de uma memória externa (de dados ou programa), através da instrução MOVX. Pode ser dividido em dois registros de 8 bits (DPL e DPH). Portas - P0, P1, P2 e P3: são 4 registros usados para realizar as operações de E/S, compondo 32 linhas de interface com o mundo exterior. Controle de Prioridade de Interrupção (IP): contém os bits de controle que indicam a prioridade das interrupções. Controle de Habilitação de Interrupção (IE): este registro controla as máscaras de habilitação global de interrupções e de cada interrupção em particular. Registros TCON e TMOD: são registros usados para programar os temporizadores/contadores (T/C). Registros TH1, TL1, TH0 e TL0: são os registros de dados dos T/C’s. Estes 4 registros podem ser lidos ou escritos, facilitando o acesso aos T/C. Registro de Controle da Serial (SCON): serve para selecionar o modo de operação da interface serial. “Buffers” de dados da porta serial (SBUF): são dois registros mapeados no mesmo endereço, entretanto um é de leitura (recepção de dados) e o outro é de escrita (transmissão de dados). 3.5Modos de Endereçamento Para acessar um dado ou operando, as instruções dos microcontroladores MCS-51 contam com seis modos de endereçamento: Endereçamento Direto Endereçamento Indireto Instruções de Registradores Instruções de Registradores Específicos EndereçamentoImediato Endereçamento Indexado Endereçamento Direto: nesse modo, o endereço do operando é especificado por um campo de 8 bits na instrução. Somente a RAM de dados interna e a região SFR podem ser diretamente endereçadas. Endereçamento Indireto: a instrução especifica um registrador que contém o endereço do operando. Ambas as RAM's, externa e interna, podem ser indiretamente acessadas. Se tal endereço possui 8 bits, seu valor é armazenado em R0 ou R1 do respectivo banco selecionado, ou no Stack Pointer. Por outro lado, se tal endereço possui 16 bits, seu valor é armazenado no registrador DPTR. Endereçamento Direto por Registradores: é realizado por instruções de registradores, que são instruções que carregam uma especificação de 3 bits em seu opcode, com referência ao registrador a ser utilizado, podendo acessar registradores de R0 a R7 dos bancos de registradores. Instruções deste tipo são mais eficientes em termos de código, uma vez que eliminam um byte de endereço. Quando uma instrução desse tipo é executada, um dos quatro bancos de registradores é selecionado pelos bits de seleção de banco, RS0 e RS1, do PSW. Endereçamento Inerente ou por Registrador Específico: algumas instruções são específicas a certos registradores. O próprio opcode é capaz de realizar tal tarefa. As instruções de Registradores específicos nada mais são do que aquelas que operam sempre num registrador em especial , como no acumulador, DPTR, etc. Ou seja, não é necessário um byte de endereçamento específico para apontar qual o registrador. Endereçamento Imediato: quando uma constante (o próprio dado) segue o opcode. Endereçamento Indexado: somente a memória de programa, cuja única operação é leitura, pode ser acessada por esse modo, usado para fazer leituras de tabelas nessa memória. Um registrador de 16 bits (DPTR ou PC) aponta para o início da tabela, enquanto o acumulador é ajustado para a n-ésima posição da mesma. O endereço de uma entrada para a tabela é formado pela soma entre o acumulador e o registrador de 16 bits. Uma outra aplicação desse tipo de endereçamento é na formação do endereço destino de jumps pela soma do índice e do valor do acumulador. Por exemplo, a instrução ADD A, <byte> pode ser escrita como: ADD A, 7FH (direto) ADD A, @RO (indireto) ADD A, R7 (registrador) ADD A, #127 (imediato) 4HARDWARE DO 8051 4.1Análise externa O aspecto externo do 8051 é o da figura 4.1. Os pinos com nomes da forma P0.0, P0.1, etc. correspondem às quatro portas de E/S (P0 a P3). Note a dupla utilidade das portas P0 e P2, que ficam comprometidas com o uso de memória externa, assim como os pinos P3.6 e P3.7. O sinal ALE (Address Latch Enable) permite fazer a demultiplexação de dados e endereços na porta P0, da maneira que foi mostrado anteriormente. Através do sinal PSEN (program storage enable), o controlador informa o mundo externo se a operação em andamento é uma leitura de instrução (acesso à memória de programa) ou um acesso à memória de dados. Este sinal permite que o processador tenha duas regiões distintas de memória externa, uma para armazenar código e outra para dados. Ambas ocupam os endereços de 0 a FFFFH (64 kB), num total de 128 kB. Figura 4.1 – Pinagem do 8051 O pino EA é um sinal de entrada, através do qual o usuário escolhe se será utilizada a memória ROM interna ou se todo o programa será armazenado externamente. Descrição dos Pinos do 8051: Vcc (40) - Alimentação de +5V. Vss (20) - Terra. P0 (32-39) - Porta 0 (AD0...AD7). Além de porta paralela, está multiplexada com o byte menos significativo (LSB) dos endereços e dos dados. Admite 8 cargas LS TTL. P2 (21-28) - Porta 2 (A8...A15). Além de porta paralela, está multiplexada com o byte mais significativo (MSB) dos endereços. Admite 4 cargas LS TTL. P1 (1-8) - Porta 1. Admite 4 cargas LS TTL. P3 (10-17) - Porta 3. Compartilhada com uma série de recursos Admite 4 cargas LS TTL. Os pinos da porta P3 também são utilizados para realizar certas funções especiais: P3.0 - RxD/data - recepção serial assíncrona ou E/S de dados síncronos; P3.1 - TxD/clock - transmissão porta serial assíncrona ou saída de clock p/ dados síncronos; P3.2 - INT0 - entrada da interrupção 0 ou bit de controle para o temporizador/contador 0; P3.3 - INT1 - entrada da interrupção 1 ou bit de controle para temporizador/contador ; P3.4 - T0 - entrada de clock externo para o temporizador/contador 0; P3.5 - T1 - entrada de clock externo para o temporizador/contador 1; P3.6 - WR - sinal de escrita na memória de dados externa; P3.7 - RD - sinal de leitura na memória de dados externa. RST (9) - Reset. Com o oscilador funcionando, deve ser mantido um nível alto durante 24 períodos. ALE/PROG (30) - Address Latch Enable. Pulso para acionar o latch que captura o LSB do endereço (com sua borda ascendente). Ele é emitido à razão de 1/6 da freqüência do oscilador e pode ser usado para acionar entradas externas. Um ALE é omitido durante o acesso à Memória de Dados Externa. Também é usada na gravação da ROM interna. *PSEN (29) - Program Store Enable. Pulso de leitura para a Memória de Programa Externa. Quando o programa está sendo executado na memória de programa externa ele aparece como 1/6 da freqüência de clock. Quando há acesso à memória de dados externa, 2 PSEN são perdidos. *EA/VPP (31) - External Access Enable. Informa à CPU se o programa está na Memória de Programa Externa ou na ROM Interna. Também usado para gravação da ROM Interna. *EA = 1 (Vcc) (0000H - 0FFFH) ROM Interna (1000H - FFFFH) Memória de Programa Externa *EA = 0 (Vss) (0000H - FFFFH) Memória de Programa Externa XTAL1 (19) - Entrada do amplificador inversor do oscilador interno. Deve ser conectado à terra se for usado um clock externo (HMOS) ou ao clock externo (CHMOS). XTAL2 (20) - Saída do amplificador inversor do oscilador interno. Se for usado clock externo, serve como entrada para o mesmo (HMOS) ou não é conectado (CHMOS). 4.2Oscilador do 8051 Todos os microcontroladores da familia MCS-51 possuem um oscilador interno que pode ser utilizado, se desejado, como um gerador de clock para a CPU. Para se usar o oscilador interno, basta conectar um cristal ou um ressonador cerâmico entre os pinos XTAL1 e XTAL2 do microcontrolador, e capacitores ao terra como mostra a figura 4.2. Figura 4.2: Utilização do 8051 com cristal. Exemplos de como se utilizar o clock com oscilador externo são mostrados abaixo: Figura 4.3: utilização do 8051 com oscilador externo. 4.3Ciclos de Máquina Um ciclo de máquina consiste de uma seqüência de 6 estados (S1 a S6). Cada estado toma 2 períodos de clock e, portanto, um ciclo de máquina toma 12 períodos de clock ou 1 μs sob uma freqüência de 12MHz. A figura 4.4 mostra a seqüência de busca/execução para alguns tipos de instruções. Normalmente dois ciclos de busca são executados em cada ciclo de máquina, mesmo que a instrução sendo executada não o requeira, caso em que o byte buscado é ignorado e o PC não é incrementado. Figura 4.4 – Ciclo de Máquina. Instruções de um ciclo começam em S1, em S4 é gerada uma segunda busca e, no fim de S6, a instrução está completa. O ciclo busca/execução é o mesmo com memória de programa externa ou interna. A Figura 4.5 mostra os sinais e as temporizações envolvidas quando a memória de programas é externa. Nesse caso, o sinal PSEN é ativo duas vezes por ciclo de máquina. Se um acesso à memória de dados externa ocorre, como mostrado na Figura 4.4, dois PSEN são pulados porque o bus de endereços e o bus de dados estão sendo utilizados para acesso à memória de dados. Note que um ciclo de memória de dados externa toma duas vezes mais tempo que um ciclo de memória de programas. A figura 4.5 mostra a dinâmica dos endereços sendo enviados às Portas 0 e 2 e dos sinais ALE e PSEN . O sinal ALE é ativado indiferentemente se a CPU está executando a partir da memória de programas externa ou interna, podendo ser utilizado como uma saída de clock. Figura 4.5 – Ciclo de barramento para acesso àmemória externa. A instrução MOVX gasta 2 ciclos máquinas a ser executadas, não sendo necessária nenhuma busca do código de programa é feita durante o 2º ciclo máquina, pois esta instrução ocupa 1 byte na memória de programa. 4.4Hardware para memória externa Um exemplo de utilização de memória externa é mostrado na figura 4.6. No caso, estão sendo utilizadas externamente tanto memória de programa como memória de dados, mas é possível a utilização de apenas uma delas (somente a ROM). Figura 4.6 - Expandindo RAM e ROM Como pode ser visto na figura 4.6, além das memórias faz-se necessário a utilização de um outro CI (no caso o 74373) para a multiplexação de dados e endereços. Ocorre da seguinte forma: no primeiro ciclo de máquina, o 8051 coloca nos pinos AD0 a AD7 o byte menos significativo do endereço externo e leva o pino ALE (Address Latch Enable – Habilitador da Trava de Endereços) a nível alto, de modo que o 74373 (oito Latches tipo D) coloque em suas saídas essa informação, e logo em seguida passa este pino para nível baixo, para que esse byte fique retido no 74373. Após isso, os pinos AD0 a AD7 estarão livres para o transporte dos dados. O 8051 pode, no modo expandido (memória externa), utilizar toda a memória de programa externa (com nível lógico 0 aplicado ao pino 31 - External Address NOT) ou ainda utilizar os primeiros 4 KB internos e o restante externo (com 1 em EA). O CI 8031 é a versão sem ROM interna do 8051. O mesmo é muito utilizado em fase de desenvolvimento ou quando se quer produzir em pequenas quantidades. Como o 8031 tem a mesma pinagem que o 8051, o mesmo possui o pino EA, que deverá sempre ser utilizado em nível lógico baixo. Retornando a figura 4.6, nela estamos utilizando 8kB de RAM externa, além dos 256 bytes de RAM interna. Além disso, temos um total de 8kB de memória ROM que, no caso do 8051, pode estar sendo utilizado apenas no CI externo ou com os 4096 bytes menos significativos em memória interna e os 4096 bytes mais significativos na memória externa. Ainda em relação à figura 4.6, para fazer uma leitura na ROM externa, o pino PSEN será levado a nível baixo, para fazer uma leitura na RAM externa, o pino RD será levado a nível baixo e, para fazer uma escrita na RAM externa, o pino WR será levado a nível baixo. 4.5Reset A entrada de Reset é o pino RST que possui um Schmitt Triger na entrada. O Reset é realizado quando este pino se mantém em nível alto pelo menos por 2 ciclos de máquina (24 clocks) enquanto o oscilador estiver funcionando. A RAM Interna não é afetada pelo reset. Depois do RESET, a CPU é inicializada com os seguintes dados: ESTADO DOS REGISTROS APÓS O RESET SP = 7 SBUF = ? P0,P1,P2,P3 = FFH OUTROS SFR = 0 Figura 4.7 – Circuito de Reset para o 8051. Um reset automático pode ser obtido quando Vcc é ligado ao pino RST passando por um capacitor de 10μF e ligados ao Vss passando por um resistor de 8.2K, provocando um ascensão de Vcc não superior a 1ms e o start-up do oscilador não superior a 10 ms, sendo mostrado na figura 4.7 o circuito adequado para gerar um power on reset. Quando a alimentação é ligada o pino RST fica no estado alto por um tempo que depende do valor do capacitor e da taxa de carga que é aplicada ao mesmo. Para garantir um bom reset deve-se garantir um tempo alto do pino RST maior que dois ciclos de máquina, o que só ocorre após o start-up do oscilador (normalmente poucos ms). Note que o valor dos pinos fica em estado aleatório antes do oscilador começar a funcionar e durante o período que a rotina interna de reset está em progresso. 5CONJUNTO DE INSTRUÇÕES Todos os componentes da família de microcontroladores Intel MCS-51 executam o mesmo conjunto de instruções, com o auxílio de seu Macro Assembler ASM-51. O conjunto de instruções da família MCS-51 é direcionado para aplicações de controle de 8 bits. Ele permite manipulação de dados de 1 ou 2 bytes, além de fornecer suporte para variáveis de um bit em sistemas lógicos que necessitem de processamento booleano. O 8051 possui 111 instruções distintas; dessas, 49 possuem código de operação de um byte apenas, 45 de dois bytes e 17 de três bytes. Logo abaixo, será feito um levantamento dessas instruções agrupadas nas categorias: transferência de dados, aritméticas, lógicas e transferência de controle. Para a exposição das instruções, utilizar-se-ão as seguintes abreviaturas: Rn direto, dir @Ri #data, #dt #data16, #dt16 adr16 adr11 rel bit A Acc. qualquer registro R0, R1, ...,R7 endereço da RAM interna (8 bits) @R0 ou @R1, usado para endereçamento indireto constante de 8 bits (byte) constante de 16 bits endereço de 16 bits (endereça 64 KB) endereço de 11 bits (endereça 2 KB) deslocamento relativo (complemento a 2: -128 a +127) endereço de um bit da RAM interna acumulador (registro) endereço do acumulador 5.1Modos de Endereçamento De acordo com o "Data Sheet" do MCS-51, existem 6 modos de endereçamento com a seguinte nomenclatura : Imediato Direto Indireto Registrador Registrador Específico Indexado Imediato:O valor da constante é colocado no opcode. MOV A, #100 Carrega 100 no acumulador (Acc=100). O byte 100 é um dado imediato. Deve-se notar a presença do sinal # que indica operação imediata. Direto:O operando especifica um endereço de 8 bits da RAM interna. MOV A, 20 Transfere para o acumulador o conteúdo do endereço 20 da RAM Interna. Todo endereçamento direto usa a RAM Interna. Indireto: Aqui se especifica um registro onde está o endereço do operando. Só pode ser usado para endereçamento indireto: R0, R1 ou DPTR. MOV A, @R0 Coloca no acumulador o conteúdo do endereço que está em R0 Registro: No código de operação da instrução existe um campo de 3 bits (pois são 8 registradores, de R0 a R7) onde é especificado o registro a ser utilizado. Essa forma é eficiente e evita utilizar um byte adicional para indicar o registro. MOV A,R0 Coloca no acumulador o conteúdo de R0. É uma instrução de um só byte. Registro Especifico: Algumas operações são especificas para certos registros. Por exemplo, algumas instruções sempre operam com Acc ou DPTR e não necessitam de espaço no opcode para especificar isto. MOVX A,@DPTR Esta é uma instrução para leitura da Memória de Dados Externa. Coloca no acumulador o conteúdo do endereço da RAM Externa que está no DPTR. Como sempre são usados Acc e DPTR, não é necessário especificá-los, o que faz com que a instrução empregue apenas 1 byte. Indexado: O endereço do operando é formado pela soma de um endereço base com um registro de indexação. Somente a Memória de Programa pode ser endereçada deste modo. MOVC A,@A+DPTR A -índice, DPTR -endereço base. A soma do DPTR com o acumulador forma um endereço da Memória de Programa e o conteúdo deste endereço é transferido para o acumulador. Essa instrução é ótima para "look up table". 5.2Instruções Aritméticas As quatro operações básicas (soma, subtração, multiplicação e divisão) podem ser executadas pelo 8051, com operandos de 8 bits. Entretanto, através dos flags pode-se realizar as duas primeiras operações com números com mais de 8 bits, sinalizados ou não. INC e DEC incrementam e decrementam, respectivamente, o conteúdo do operando. ADD e ADDC efetuam a soma do acumulador com um segundo operando, colocando o resultado no primeiro. A instrução ADDC leva em conta o vai-um nesta operação. SUBB realiza a subtração do acumulador com um segundo operando e com o carry, colocando o resultado no acumulador. DA ajusta o resultado da última operação aritmética para o formato BCD; não converte um número binário em BCD, mas sim ajusta o resultado de uma operação ADD ou ADDC envolvendo valores BCD. MUL e DIV executam as operações de multiplicação e divisão, respectivamente. Os operandos são os registros A e B. O resultado é conduzido aos mesmos registros, conforme a tabela 5.1. Tabela 5.1 – Instruções aritméticas do 8051. Mnemonic Operation Addressing Modes Execution Time (μs) Dir Ind Reg Imm ADD A,<byte> A = A + <byte>X X X X 1 ADDC A,<byte> A = A + <byte> + C X X X X 1 SUBB A,<byte> A = A + <byte> - C X X X X 1 INC A A = A + 1 Accumulator only 1 INC <byte> <byte > = <byte> + 1 X X X 1 INC DPTR DPTR= DPTR + 1 Data Pointer only 2 DEC A A = A – 1 Accumulator only 1 DEC <byte> <byte > = <byte> - 1 X X X 1 MUL AB B:A= B x A ACC and B only 4 DIV AB A= Int [A/B] B= Mod [A/B] ACC and B only 4 DA A Decimal Adjust Accumulator only 4 5.3Instruções Lógicas e Booleanas O 8051 realiza as operações lógicas básicas, tanto com operandos de 1 bit como com operandos de 1 byte. As instruções lógicas podem ser divididas em: Instruções com um único operando CLR: é usado para introduzir o valor zero (0) no registro A, ou no flag CY, ou em qualquer bit diretamente endereçável SETB: introduz o valor ‘1’ no CY ou em qualquer bit endereçável. CPL: realiza o complemento de um. Os operandos são os mesmos da instrução CLR. RL, RLC, RR, RRC, SWAP: realizam as operações de rotação e deslocamento de bits, usando o acumulador como operando. Instruções com dois operandos ANL: realiza a operação lógica AND com operandos de 1 ou 8 bits, e retorna o resultado para o primeiro operando ORL: idem à anterior, sendo que se realiza a operação lógica OR XRL: executa o XOR entre dois operandos de 8 bits e retorna o resultado para o primeiro operando. As instruções lógicas realizam operações booleanas (AND, OR, Exclusive OR e NOT) bit a bit entre dois bytes. Elas também podem endereçar seus operandos por diversos modos como por exemplo, a instrução ANL A, <byte>: ANL A, 7FH (direto) ANL A, @RI (indireto) ANL A, R6 (por registrador) ANL A, #53H (imediato) Tabela 5.2 – Instruções Lógicas do 8051. Todas as instruções desse tipo que utilizam o acumulador como registrador específico tomam 1 μs para serem executadas, enquanto as demais tomam 2 μs. Os modos de endereçamento disponíveis tornam desnecessário carregar qualquer operando que estiver na memória de dados interna para o acumulador. Não utilizar o acumulador economiza o tempo em empilhar seu conteúdo quando do atendimento a uma interrupção. 5.4Instruções de Transferência de Dados Essas instruções são divididas em três subgrupos, conforme a localização do dado: na RAM interna, na RAM externa ou na memória de programa (Lookup Tables). 5.4.1RAM Interna Sob um clock de 12MHz, uma operação desse tipo é realizada em 1 μs ou 2 μs. Esse conjunto de instruções mostrado na tabela 3, conta com a facilidade, por exemplo, de MOV <dest>,<src> que transfere dados entre duas posições de RAM interna ou na região SFR, dispensando qualquer carregamento do Acumulador. PUSH e POP utilizam endereçamento direto para identificar o byte a ser salvo ou restaurado, mas usam endereçamento indireto para acessar a pilha através do registrador SP. Em dispositivos que não contam com a região Upper 128, se a pilha tenta avançar sobre ela, bytes de PUSH são perdidos e de POP são indeterminados. Movimentação de 16 bits é útil para inicializar o DPTR, para acesso a Lookup Tables na memória de programa ou acesso à memória de dados externa. As instruções de transferência de dados em RAM interna podem ser subdivididas em duas categorias: Transferência de propósito geral MOV: realiza a transferência de 1, 8 ou 16 bits do operando fonte para o operando destino. PUSH: incrementa o registro SP, e então, transfere o operando fonte para o topo da pilha. POP: transfere o conteúdo do topo da pilha para o operando destino, e decrementa o SP. Transferência específica com o acumulador XCH: permuta o byte do operando fonte com o do acumulador. XCHD: permuta os 4 bits baixos do operando fonte com os 4 bits baixos do acumulador. MOVX: executa a transferência de um byte entre a memória externa de dados e o registro A. O endereço externo pode ser especificado pelos registros DPTR ou R0 e R1. MOVC: realiza a transferência de um byte da memória de programa para o registro A. Neste caso, usa-se o endereçamento indexado, onde o próprio acumulador é o índice e os registros DPTR ou PC são usados como base do endereço. Tabela 5.3 - Instruções de transferência de dados em RAM interna. 5.4.2RAM Externa A tabela 5.4 mostra a lista de instruções de transferência de dados para acesso à memória externa, onde somente endereçamento indireto pode ser utilizado. Pode-se escolher o uso de endereços de 8 bits, @Ri, onde Ri pode ser o registrador R0 ou o registrador R1, ou endereços de 16 bits, @DPTR. A desvantagem em se usar endereços de 16 bits, quando poucos Kbytes de memória de dados externa estão envolvidos, é o sacrifício de todos os 8 bits da Porta 2 (veja Figura 2). O acumulador é sempre a fonte ou o destino da transferência. Os sinais RD e WR só são gerados quando da execução de uma instrução do tipo MOVX, assim, se uma RAM externa não é disponível, tais sinais podem ser utilizados como linhas de E/S extras. Tabela 5.4 - Instruções de transferência de dados em RAM externa. 5.4.3Memória de Programa A tabela 5.5 mostra as duas únicas instruções disponíveis para ler Lookup Tables (Tabelas de Pesquisa), localizadas na memória de programa. Uma vez que residem na memória de programa, tais tabelas podem apenas ser lidas, nunca atualizadas por tais instruções. Se essas tabelas se encontrarem na memória de programas externa, o sinal de leitura é PSEN . Tabela 5.5 - Instruções para leitura de Lookup Table em memória de programa MOVC é o mnemônico para “Move Constant”. A primeira instrução MOVC pode acomodar uma tabela de 256 entradas (0 a 255). O número da entrada é armazenado no acumulador e o registrador DPTR é carregado com o endereço inicial da tabela. A segunda instrução utiliza o PC como a base da tabela, que é acessada através de subrotina. O acumulador é carregado com o valor da entrada da tabela e a subrotina é chamada: MOV A, #ENTRADA CALL LOOKUP_TABLE Sub-rotina: LOOKUP_TABLE: MOVC A, @A+PC A tabela em si segue imediatamente após a instrução RET. Ela comporta 255 entradas (1 a 255), pois a entrada 0 endereça a instrução RET. 5.5Instruções Booleanas Os dispositivos da família 8051 contam com um conjunto completo de operações booleanas (tabela 9) sob bits únicos. O espaço Lower 128 da RAM interna suporta 128 bits endereçáveis e o espaço SFR pode suportar outros 128 bits endereçáveis. Todas as linhas das portas são bits-endereçáveis e cada uma dessas linhas pode ser tratada como uma porta de um único bit. As instruções que acessam esses bits não são apenas desvios condicionais mas uma completa lista de mov, set, clear, complement, OR e AND. Esse tipo de operações sobre bits não é facilmente obtido em outras arquiteturas sem uma razoável quantidade de código. Todos esses bits são endereçados diretamente. Os bits de endereço entre 00H e 7FH acessam o espaço Lower 128 enquanto entre 80H e FFH acessam o espaço SFR. Note como é fácil um flag interno ser movido para um pino de uma porta: MOV C, FLAG MOV P1.0, C onde FLAG é o nome de qualquer bit endereçável em Lower 128 ou SFR. Nessa seqüência, bit de FLAG é movido para o bit menos significativo da Porta l. O bit Carry do PSW é utilizado como acumulador para operações booleanas. As operações de jump desse conjunto testam um único bit, que possa ser diretamente endereçável, como condição. Uma vez que todos os bits de PSW são endereçados diretamente, pois estão no espaço SFR, pode se utilizá-los como alguma condição de jump. Para jumps relativos, o endereço contido no código é somado ao PC em complemento de dois se o jump é executado. Portanto, à distância de salto pode variar na faixa de –128 a +127 bytes a partir do endereço do byte de desvio. Tabela 5.6 – Instruções booleanas. 5.6Instruções de Transferência de Controle (Desvio) O conjunto de instruções de salto ou desvio pode ser dividido em dois subgrupos: jumps condicionais e jumps incondicionais. 5.6.1Desvios IncondicionaisO conjunto de instruções de salto incondicional (tabela 5.7) possui seis instruções em seu repertório. JMP é apenas um mnemônico genérico utilizado pelo programador que não precisa saber como ele é realmente interpretado pelo assembler. Na realidade, JMP corresponde a três instruções: SJMP, LJMP e AJMP, cada uma indicada a situações de endereço de desvio diferente. Tabela 5.7 – Instruções de desvio incondicional. A instrução SJMP calcula o endereço destino como descrito acima, que pode varrer uma largura de –128 a +127 bytes na memória de programa. A instrução LJMP codifica o endereço destino como uma constante de 16 bits que pode ser qualquer posição nos 64 Kbytes da memória de programas. A instrução AJMP codifica o endereço destino como uma constante de 11 bits; a instrução consiste em 2 bytes: 3 bits do endereço localizam-se no opcode enquanto os outros 8 bits localizam-se no próximo byte. Os 11 bits assim formados simplesmente substituem os 11 bits menos significativos do PC. Em todos os casos, o programador especifica o endereço destino de duas maneiras ou como um label ou como um constante de 16 bits. O assembler se encarrega de colocar o endereço destino para o correto formato de instrução. A instrução JMP @A + DPTR implementa o comando CASE. O endereço destino é computado em tempo de execução como a soma do conteúdo do Acumulador e o registrador DPTR. Tipicamente, DPTR é carregado com o endereço de uma tabela de jumps e, ao acumulador, é dado o valor de um índice dessa tabela. Semelhante à instrução JMP, a instrução CALL, na realidade, é duas: LCALL e ACALL, usadas para ativar uma sub-rotina, que diferem na forma como o endereço da subrotina é dado à CPU. LCALL utiliza o endereço destino em 16 bits (instrução de 3 bytes) que pode ser qualquer localidade dos 64 Kbytes da memória de programas. ACALL utiliza formatos de endereços em 11 bits (instrução de 2 bytes), o que significa que o endereço destino deve estar no mesmo bloco de 2 Kbytes seguintes à instrução. A transparência para o programador de CALL é semelhante à de JMP. As instruções RET e RETI são as clássicas instruções de retorno de sub-rotinas. A diferença entre elas é que RETI informa ao sistema de controle de interrupções que a interrupção em progresso terminou, sendo específica para sub-rotinas de tratamento de interrupção. 5.6.2Desvios Condicionais O conjunto de jumps condicionais só permite endereçamento de destino relativo, o que limita a distância de salto entre –128 e + 127 bytes de distância em relação à instrução jump. É importante notar que o programador especifica o endereço como um label ou uma constante de 16 bits. Não há flag de zero, portanto JZ e JNZ testam o dado do acumulador para tal condição. JC, JNC, JB, JNB, e JBC são outras instruções de salto condicional, que testam flags ou bits endereçáveis antes de efetuar o desvio de execução As instruções DJNZ (Decrementa e Salta se Não Zero) e CJNE (Compara e Salta se Não Igual) são utilizadas para controle de laços. Uma aplicação de CJNE está em comparações "maior que, menor que". Pelo valor do bit de Carry distingue-se entre as duas situações. Se o primeiro é menor que o segundo, o bit de carry é setado. Se o primeiro é maior ou igual ao segundo, o bit de carry é zerado. As duas instruções são usadas para realizar comparação entre operandos de 8 bits e repetições iterativas de um bloco de instruções. Tabela 5.8 - Instruções de desvio condicional. 5.7Look-Up Tables Quando da programação de sistemas utilizando microprocessadores surge muitas vezes a necessidade de se utilizar as look-up tables. Um exemplo é converter um numero numa base num outro noutra base, por exemplo converter um digito no seu correspondente ASCII 0 30h 5 35h 1 31h 6 36h 2 32h 7 37h 3 33h 8 38h 4 34h 9 39h Um modo simples de converter um numero decimal no seu correspondente ASCII, é somar 30h ao numero, pois neste caso existe uma correspondência direta entre o numero convertido e o numero a converter. No entanto podemos utilizar uma tabela com os valores já convertidos em que o valor a converter será o deslocamento na tabela, aqui temos de ter um ponteiro de referência para o inicio da tabela. No 8051 este ponteiro de referência pode ser o PC ou o DPTR. ;***************************************************************************** ;* Nome: converte_ASCII * ;* Descrição: Faz a conversão de um numero de 0-9 para equivalente ASCII * ;* Entradas: Em A numero a converter * ;* Saídas: Em A o seu equivalente em ASCII * ;* Registos utilizados: a,dptr * ;***************************************************************************** converte_ASCII lcall tabela db 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h ;valores para a tabela tabela: pop dph ;coloca o dptr a apontar para o inicio da tabela pop dpl movc a,@a+dptr ;vai à tabela buscar o seu correspondente em ASCII ret Listagem 1- Rotina utilizando look-up table. 6TEMPORIZADORES E CONTADORES 6.1Introdução O 8051 tem dois registros contadores de 16 bits, denominados TIMER0 e TIMER1, dedicados às funções de contagem e temporização (counter/timer-contador/temporizador). Há uma importante distinção entre os conceitos de contador e temporizador. Quando opera como temporizador, o registro é incrementado a cada ciclo de máquina (usa como base o cristal da CPU). O sinal de contagem aparece com 1/12 da freqüência do clock. Quando opera como contador, o registro é incrementado de acordo com o sinal que se coloca nas entradas T1 e T0, ou seja, o contador opera a cada transição de 1 para 0 (borda de descida _) na entrada T0 ou T1. Deve-se ter um cuidado quando em operações em modo contador: já se sabe que as entradas são amostradas durante S5P2 de cada ciclo de máquina. Quando em um ciclo de máquina a entrada é detectada em 1 e depois em 0, no próximo ciclo o contador é incrementado. O incremento acontece em S3P1 do ciclo seguinte ao que foi detectada a transição. Para garantir que o nível correto tenha sido amostrado, é necessário que o sinal de entrada (o sinal que vai acionar os contadores) permaneça pelo menos um ciclo de máquina em nível alto e pelo menos outro ciclo de máquina em nível baixo, quer dizer, a máxima freqüência que responderá o contador é de 1/24 da freqüência de clock. O sinal de entrada pode ter qualquer "duty cycle", desde que se respeite a restrição antes mencionada. 6.2Registros Envolvidos Dois registros SFR são utilizados para controlar as funções e operações do temporizador/contador: em TMOD especifica-se o modo de operação e em TCON controla-se a operação. A figura 6.1 ilustra o registro TMOD e a figura 6.2 ilustra o registro TCON. Figura 6.1. Descrição do registro TMOD. GATE: especifica como será feito o controle: se GATE = 1 - conta somente se TR1=1 e INT1=high, (idem para TR0 e INT0) se GATE = 0 - conta somente se TR1=1 (controle somente por software) (GATE especifica se INT1 será usado para controlar o funcionamento do contador/temporizador Î pode ser usado para medir a largura de pulsos externos ligados a INT0 ou INT1) C/T: seleciona modo contador ou temporizador: se C /T = 1 - modo contador (conta usando a entrada T1) se C /T = 0 - modo temporizador (conta a cada ciclo de máquina) M0 M1 seleciona o modo de operação 0 0 THi é temporizador/contador de 8 bits e TLi é um pre-scaler de 5 bits, 0 1 THi e TLi formam um temporizador/contador de 16 bits, 1 0 contador/temporizador de 8 bits com auto-recarga (TLi conta e THi valor para recarga), 1 1 -TL0 contador/temporizador de 8 bits (usando TR0, *INT0 e TF0) -TH0 contador/temporizador de 8 bits (usando TR1, *INT1 e TF1) -TH1 e TL1 parado (mas pode operar em outros modos) Figura 6.2. Descrição do registro TCON. TF1:flag de transbordamento (overflow) do contador/temporizador 1. Ativado por hardware quando há transbordamento no timer 1. É apagado por hardware quando o processamento é desviado para a rotinade interrupção. TR1:bit de partida/parada (run/stop) do contador/temporizador 1. TF0:flag de transbordamento (overflow) do contador/temporizador 0. Ativado por hardware quando há transbordamento no timer 0. É apagado por hardware quando o processamento é desviado para a rotina de interrupção. TR0:bit de partida/parada (run/stop) do contador/temporizador 0. IE1:flag da interrupção externa 1. Ativada por hardware quando é detectada uma interrupção. Apagado por hardware (somente se for modo borda) quando a interrupção é processada, ou seja, quando se desvia para a rotina de interrupção. IT1:indica se a interrupção externa 1 opera por borda ou por nível: 1 -borda de descida (↓), 0 -nível baixo. E0:flag da interrupção externa 0. Ativada por hardware quando é detectada uma interrupção. Apagado por hardware (somente se for modo borda) quando a interrupção é processada, ou seja, quando se desvia para a rotina de interrupção. IT0:indica se a interrupção externa 0 opera por borda ou por nível: 1 -borda de descida (↓), 0 -nível baixo. 6.3Modos de operação Os dois contadores/temporizadores (timer1 e timer0) podem trabalhar em 4 modos de operação que são selecionados empregando os bits M1 e M0 do registro TMOD. Os modos 0, 1 e 2 são iguais para os 2 contadores/temporizadores mas o modo 3 é diferente. 6.3.1Modo 0 Este modo é idêntico para os dois contadores/temporizadores. Neste modo tem-se um contador de 8 bits com um divisor (pre-scaler) de 5 bits. Resulta então em um contador/temporizador de 13 bits, compatível com o que havia no MCS-48. Os 13 bits são formados pelos 8 bits do registro THi e pelos 5 bits menos significativos do registro TLi. Os outros 3 bits do TLi são indeterminados. O transbordamento (overflow) é gerador quando a contagem faz a transição de 1FFFH para 0000; neste instante ativa-se o bit de overflow (TF1 ou TF0). O controle da contagem é simples: se GATE = 0, TR1 controla o contador/temporizador (controle por software) se GATE = 1, TR1 e INT1 controlam o contador/temporizador (permite também um controle externo por hardware) A figura 6.3 apresenta um diagrama em blocos do contador/temporizador 1 operando em modo 0. A mesma figura é válida para o contador/temporizador 0. Figura 6.3. Diagrama em blocos para o TIMER 1 em MODO 0. 6.3.2Modo 1 Este modo de operação é o mais simples e por isto é muito utilizado. É idêntico ao modo 0, mas os contadores são de 16 bits. A figura 6.4. ilustra o diagrama em blocos para este modo, que é idêntico para os dois timers. Figura 6.4. Diagrama em blocos para o TIMER 1 em MODO 1. 6.3.3Modo 2 Neste modo tem-se um contador/temporizador de 8 bits (TLi) com registro de recarga (THi) para quando ocorre o transbordamento. Neste modo os dois contadores/temporizadores operam de forma idêntica. O transbordamento (overflow) não somente ativa TFi como também recarrega TLi com o valor guardado em THi (este permanece inalterado). O valor de recarga deve ser fornecido por software. Figura 6.5. Diagrama em blocos para o TIMER 1 em MODO 2. 6.3.4Modo 3 Este é o único modo onde os contadores/temporizadores têm um comportamento diferente. Neste modo, o contador/temporizador 1 simplesmente suspende a contagem (é como se estivesse com TR1=0), enquanto o contador/temporizador 0 se divide em dois contadores de 8 bits: TH0 → contador/temporizador de 8 bits usando C/*T, GATE, TR0, *INT0 e TF0, TL0 → contador/temporizador de 8 bits usando TR1 e TF1 (ou seja, provoca a interrupção do timer 1). É como se existissem 2 contadores/temporizadores de 8 bits (TH0 e TL0) e outro de 16 bits (timer 1). O timer 1, entretanto, pode ser usado para operar em qualquer outro modo (0, 1 ou 2) e usa-se o modo 3 para detê-lo. Não há problemas porque os modos são independentes. Também se pode usar o timer 1 (em modo 2) para gerar o "baud rate" da porta serial. Figura 6.6. Diagrama em blocos para o TIMER 0 em MODO 3. EXEMPLO - LED_10HZ Acender os leds vermelho, amarelo e verde a uma freqüência de 10 Hz. Para solucionar esse exercício é necessário gerar um retardo equivalente ao período de 10 Hz. A figura 8.7 ilustra o cálculo do valor do contador para gerar esse retardo. Figura 6.7 – cálculo do valor do contador. Se F=10 Hz e CLOCK=3,575611 Hz, então N=29797. Como este é um contador que conta para cima, temos que subtrair este valor de 65536. Com isto, N=65536-29797=35739 ou 8B9BH. Na realidade, a freqüência gerada não será exatamente 10 Hz mas de um valor muito próximo: F = 3,575611 / 12*29797 = 9,99 Hz Será utilizado o timer 0 no modo 1; a cada interrupção a rotina acende um novo led e recarrega o timer. Figura 6.8. Valor a ser programado em TMOD. Figura 6.9. Valor a ser programado em IE. ;LED_10HZ.ASM ; DEFSEG PROG, CLASS=CODE, START=0 SEG PROG ; DEZ_HZ EQU 35739 ; ORG RESET AJMP INIC ; ORG TIMER0 AJMP TIM0 ; ORG 50H INIC MOV TL0,#LOW DEZ_HZ MOV TH0,#HIGH DEZ_HZ MOV TMOD,#1 ;TIMER 0 EM MODO 1 MOV IE,#82H MOV P1,#0 ;APAGAR TODOS OS LEDS MOV A,#01001001B CLR C SETB TR0 SJMP $ ; ORG 100H TIM0 MOV TL0,#LOW DEZ_HZ ;REINICALIZAR MOV TH0,#HIGH DEZ_HZ ;O CONTADOR RLC A MOV P1,A RETI END Notar que na rotina de interrupção está a recarga dos temporizadores que é feita feita com a instrução "MOV direto,#data" mas que consome 2 ciclos de máquina, ou seja, que há um retardo que se acumula. Para evitar ou corrigir isso, pode-se adicionar ao contador o retardo da instrução; é mais preciso usar "MOV TL0,# LOW (DEZ_HZ+2). Quando existem várias interrupções, não se sabe com certeza quando uma interrupção do temporizador pode ser aceita; isso implica um erro maior que se acumula. Há uma solução simples porque depois do transbordamento o temporizador segue contando e esta contagem é exatamente o tempo que atrasou o serviço da interrupção; basta usar esse valor na recarga. As instruções a seguir ilustram a idéia. MOV A, #LOW (DEZ_HZ+2) ADD A, TL0 ;1 ciclo MOV TL0, A ;1 ciclo MOV TH0, #HIGH (DEZ_HZ+2) 7INTERRUPÇÕES 7.1Introdução O 8051 apresenta 5 tipos de interrupções: 2 externas 2 timers 1 serial Alguns outros membros da família MCS-51 podem apresentar outras interrupções; por exemplo, o 8052 tem uma interrupção adicional dedicada ao timer 2. 7.2Registros Envolvidos Os registros dedicados às interrupções permitem um controle total sobre as mesmas. Cada interrupção pode ser habilitada ou desabilitada individualmente. Também é possível desabilitar todas as interrupções de uma só vez. O registro IE (Interrupt Enable) controla a habilitação das interrupções e é ilustrado na figura 7.1. Figura 7.1. Registro IE - habilitação de interrupções. Cada interrupção pode ter dois níveis de prioridade: prioridade alta ou prioridade baixa. Uma interrupção de alta prioridade pode interromper uma de baixa prioridade mas não acontece o contrário. Uma interrupção não pode interromper uma outra de mesma prioridade. Se forem recebidas interrupções de diferentes prioridades, a de alta prioridade é atendida primeiro. Se forem recebidas duas interrupções de igual prioridade, determina-se por uma seqüência interna de polling (consulta) qual será atendida primeiro. Assim, dentro de um mesmo nível de prioridade, existe uma seqüência de atendimento (a seqüência do polling). O conteúdo do registro IP define as prioridades e é ilustrado na figura 7.2. Figura 7.2. Registro IP - prioridade das interrupções. As duas interrupções externas (INT0 e INT1) podem ser acionadas por nível ou por borda de descida (↓). Isto é definido através de dois bits do registro TCON. Este registro também tem outra finalidade pois cada interrupção indica sua ativação usando um bit do registro TCON. Figura 7.3. Registro TCON - diversas funções para interrupções e timers. TF1:flag de transbordamento (overflow) do contador/temporizador 1. Ativado por hardware quando há transbordamento no contador do timer 1 (timer/counter 1). É apagado por hardware quando o processador é desviado para a rotina de atendimento da interrupção. TR1:bit de partida/parada(run/stop) do contador/temporizador 1. TF0:flag de transbordamento (overflow) do contador/temporizador 0. Ativado por hardware quando há transbordamento no contador do timer 0 (timer/counter 0). É apagado por hardware quando o processador é desviado para a rotina de atendimento da interrupção. TR0: bit de partida/parada (run/stop) do contador/temporizador 0. IE1: flag da interrupção externa 1. É ativado (colocado em um) por hardware quando se detecta uma interrupção externa 1. É apagado (colocado em zero) por hardware (só no modo borda) quando o processador é desviado para a rotina de atendimento da interrupção. IT1:indica se a interrupção externa 1 opera por borda ou por nível: 1 -borda de descida (↓), 0 -nível baixo. IE0:flag da interrupção externa 0. É ativado (colocado um) por hardware quando se detecta uma interrupção externa 0. É apagado (colocado em zero) por hardware (só em modo borda) quando o processador é desviado para a rotina de atendimento da interrupção. IT0:indica se a interrupção externa 0 opera por borda ou por nível: 1 _borda de descida (↓), 0 _nível baixo. O flag de interrupção da porta serial está em outro registro (SCON). Figura 7.4. Esquema das interrupções na família MCS-51. Todos os bits que geram interrupção podem ser ativados por software com os mesmos resultados como se tivessem sido ativados por hardware. Isto quer dizer que uma interrupção pode ser ativada por software e também que as interrupções pendentes podem ser canceladas. Cada interrupção é vetorizada em um endereço pré-definido: RESET 00H Externa 0 IE0 03H Timer 0 TF0 0BH Externa 1 IE1 13H Timer 1 TF1 1BH Serial RI+TI 23H (“+” indica OU) No endereço de vetorização das interrupções há pouco espaço, o suficiente para colocar umas poucas instruções. Portanto é normal colocar nestes endereços um desvio (jump) para um outro local, onde está a rotina que atende à interrupção. 7.3Manejo de Interrupções Os flags das interrupções são amostrados na segunda fase do quinto estado (S5P2) de cada ciclo de máquina. As amostras são submetidas a polling (consulta) durante o próximo ciclo de máquina. A figura 7.5 ilustra a seqüência para atendimento de uma interrupção. Se um dos flags (de interrupção) está ativo durante S5P2, o próximo ciclo de polling vai detectar e identificar a interrupção a ser atendida e será gerada uma instrução LCALL sempre que não seja bloqueada por: uma interrupção de prioridade igual ou mais alta que a que está sendo atendida, não tenha finalizado a instrução que se está processando no ciclo de polling corrente, a instrução em progresso é um RETI ou uma escrita em IP ou IE. Figura 7.5. Seqüência para atendimento a uma interrupção. Na figura 7.5 é ilustrada a resposta mais rápida a uma interrupção. Neste caso CM2 é o final de uma instrução e não é um RETI nem uma escrita em IP ou IE. Quando CM2 é uma instrução RETI ou uma escrita em IP ou IE, uma instrução a mais será executada antes que a interrupção seja vetorizada. A seqüência de polling se repete a cada ciclo de máquina e os valores processados são aqueles que estarão presentes no instante S5P2 do ciclo de máquina anterior. Deve-se observar que se um flag de interrupção foi ativado mas não pôde ser atendido (por uma das condições de bloqueio) e é apagado antes da condição de bloqueio ser removida, a interrupção não será atendida. Quer dizer, o fato de um flag de interrupção estar ativo e não ser atendido, não será gravado. O processador reconhece um pedido de interrupção através da execução de um LCALL gerado por hardware. Normalmente o flag que gerou o pedido é zerado por hardware, exceto para: TI, RI da porta serial, IE0, IE1 quando ativado por nível A instrução RETI é usada para finalizar uma rotina de atendimento a interrupções. Uma instrução RET funciona mas o sistema de controle de interrupções não sabe que a rotina terminou, ou seja, serão bloqueadas todas as demais interrupções de prioridade igual ou inferior. 7.4Interrupções Externas As duas interrupções externas (0 e 1) podem ser programadas para funcionar por nível (ITX=0) ou por borda de descida (↓) (ITX=1). Os pinos das interrupções são amostrados em cada ciclo de máquina (1 ciclo de máquina=12 períodos de clock); assim, uma interrupção externa deve permanecer constante por pelo menos 12 períodos de clock, caso contrário ela pode ser ignorada. Quando a interrupção opera por borda de descida (↓), o pino deve permanecer em alto por pelo menos 12 períodos de clock e depois em baixo por pelo menos 12 períodos de clock; isto garante a ativação do flag de interrupção. Os flags de interrupções externas (IEX0 ou IEX1) serão automaticamente zerados pela CPU quando uma rotina de serviço é chamada. Quando a interrupção opera por nível, o pino deve permanecer ativado (em baixo) até que a interrupção seja atendida; depois disso, o pedido deve ser removido antes que a rotina de serviço de interrupção termine caso contrário uma nova interrupção será gerada. O tempo de latência de uma interrupção depende, entre outras coisas, das condições de bloqueio já vistas. No caso destas condições de bloqueio existirem, leva-se entre 5 a 9 ciclos de máquina. Figura 7.6. Latência para as interrupções. Como os flags de interrupção serial e dos temporizadores/contadores são ativados em S5P2, o que foi estudado é válido para qualquer interrupção. Caso seja necessário, pode-se usar um esquema como o da figura 7.7 para expandir as interrupções externas: Figura 7.7 – Expansão de interrupções externas. 7.5Passo A Passo A estrutura de interrupção do MCS-51 permite, de forma muito simples, uma implementação para a execução de programas passo a passo (single step). Como já foi visto, uma interrupção não será atendida quando uma interrupção de igual prioridade esteja sendo atendida e, quando esta interrupção termina com um RETI, obrigatoriamente uma instrução será executada antes que se aceite a nova interrupção. Uma interrupção não será re-atendida antes de terminar sua rotina. Essa rotina deve terminar com RETI e, depois dessa instrução, uma outra deverá ser executada antes de ser atendida a interrupção. Imagine um sistema onde a interrupção 1 está programada para trabalhar por nível e que a entrada INT1 esteja conectada a terra, ou seja, a interrupção está sempre sendo invocada. Se forem adicionadas a esse sistema uma rotina principal e uma rotina de serviço para a interrupção 1, cria-se o ambiente para executar passo a passo o programa principal. Cada vez que voltar da rotina de interrupção (com um RETI), será executada uma única instrução do programa principal e, em seguida, desviará novamente para a rotina de interrupção. Pode-se usar uma chave para marcar o instante de retorno da rotina de interrupção. O exercício 7.6 ilustra a utilização do recurso de passo a passo. A figura 7.8 mostra uma implementação possível para a execução passo a passo sem bouncing na chave. Figura 7.8 – Implementação do Passo a passo. 7.6Exemplo PASSO_EXE.ASM Escrever um programa que faça acender os leds em seqüência (vermelho, amarelo e verde). Executar esse programa com um controle passo a passo usando a interrupção 1. A solução é muito simples. No programa principal estará somente uma seqüência de instruções que acende os leds segundo a ordem especificada (sem retardo). A interrupção externa 1 estará programada para operar por nível. A rotina de interrupção aguarda que a chave SW3 seja acionada (vá a zero); quando isto ocorre, retorna-se da rotina de interrupção. Ao regressar, a entrada INT1 estará em zero (pela chave SW3) e uma nova interrupção é gerada. Ou seja, a cada acionamento da chave SW3, é executada uma instrução do programa principal. A primeira interrupção, para que o programa entre em controle passo a passo, é provocada por software ao ativar o bit IE1. ;PASSO_EXE.ASM ; ; PROGRAMA PARA ILUSTRAR A EXECUCAO PASSO A PASSO ; SERA USADA A CHAVE SW3 PARA EXECUTAR PASSO A PASSO O LOOP PRINCIPAL ; CADA VEZ QUE SE ACIONA SW3, UMA INSTRUCAO É EXECUTADA ; RTD EQU 100SW3 EQU P3.3 ; DEFSEG PROG, CLASS=CODE, START=0 SEG PROG ; ORG RESET AJMP INIC ; ORG EXTI1 AJMP EXT1 50 ; ORG 50H INIC MOV A,#01001001B ;CODIGO PARA ACENDER CLR C ;LEDS EM SEQUENCIA MOV P1,A SETB EX1 ;HABILITAR INT 1 SETB EA ;HABILITAR GERAL SETB IE1 ;PROVOCAR INT 1 NOP ;AQUI O PROG INTERROMPE PRINCIPAL RLC A ;RODAR CODIGO MOV P1,A ;ACENDER LEDS SJMP PRINCIPAL ;RETORNAR ; ORG 100H EXT1 ACALL RBT_0_1 ;TRANSICAO DE 0 A 1 ACALL RBT_1_0 ;TRANSICAO DE 1 A 0 RETI ; ;ELIMINAR BOUNCING NAS TRANSICOES DE 0 PARA 1 RBT_0_1 MOV R7,#RTD LB1 JNB SW3,RBT_0_1 DJNZ R7,LB1 RET ; ;ELIMINAR BOUNCING NAS TRANSICOES DE 1 PARA 0 RBT_1_0 MOV R7,#RTD LB2 JB SW3,RBT_1_0 DJNZ R7,LB2 RET END 8PORTA PARALELA A família MCS-51 oferece 4 portas paralelas, denominadas P0, P1, P2 e P3 e para cada porta existe um SFR. De acordo com a configuração do hardware, uma ou mais portas estarão totalmente ou parcialmente disponíveis. 8.1Registros Envolvidos Os 4 registros, P0, P1, P2 e P3 são na realidade os latches das portas e não os pinos da CPU. Algumas instruções operam com o conteúdo destes latches e outras com os valores dos pinos. As portas paralelas são utilizadas pela CPU para efetuar várias tarefas: P0 byte inferior de endereços e dados ==> BUS P2 byte superior de endereços P3 0 RXD - entrada serial 1 TXD - saída serial 2 *INT0 - interrupção externa 0 3 *INT1 - interrupção externa 1 4 T0 - entrada externa para o contador 0 5 T1 - entrada externa para o contador 1 6 *WR - strobe para escrita na memória de dados externa 7 *RD - strobe para leitura da memória de dados externa Durante uma operação de escrita ou leitura de memória de dados, por exemplo, os dados das portas P0 e P2 são removidos e por eles se emitem os endereços e dados. Terminadas as operações, o conteúdo do latch reaparece nos pinos da CPU. Existem detalhes sobre a utilização de cada porta como entrada ou saída mas, de uma formageral, pode-se dizer que: Saída: Basta escrever 0 ou 1 na porta que o nível lógico aparece nos pinos corretos. Entrada: todos as portas (exceto P0) possuem um pull-up interno; quando se escreve 1 em um bit da porta, diz-se que este bit está programado como entrada pois dispositivos externos podem colocar (forçar) este 1 em 0. Assim, para ter uma porta como entrada, escreve-se 1 e depois com a leitura será lido 1 ou 0 de acordo com o nível que externamente está aplicado no pino. Devido a isto, as portas são chamadas quasi-bidirecionais. 8.2Descrição Do Funcionamento Cada porta paralela é constituída por três partes: um registro latch (SFR ==> P0,P1,P2,P3) um driver de saída um buffer de entrada Os drivers de saída de P0 e P2 e o buffer de entrada de P0 são usados para acessar a memória externa de programa ou de dados. 8.2.1Porta P1 A figura 8.1 ilustra o esquema elétrico da porta 1. Figura 8.1 - Esquema para um bit da porta P1. O latch de um bit da porta P1 (um bit do SFR P1) é representado por um flip-flop D, no qual se escreve um valor do bus interno através de um pulso Write to Latch gerado pela CPU. A saída do latch é colocada no bus interno através de um sinal Read Latch gerado pela CPU. O nível do pino da porta é colocado no bus interno através do sinal Read Pin, também gerado pela CPU. Algumas instruções que lêem o estado da porta operam com Read Latch enquanto outras operam com Read Pin. Isto será visto com mais detalhes. Quando escreve na porta: 0*Q=1 _FET ON saída=0 1*Q=0 _FET OFF saída=1 (pull-up) Para ser usado como entrada, o latch da porta deve estar em 1; isso desconecta o driver FET da saída. Assim, o pino da porta vai para um nível alto, levado pelo pull-up. Esse pino poderá serlevado para o nível baixo por qualquer elemento externo. Devido ao pull-up interno, essa porta é denominada "quasi-bidirecional". Quando está configurado para entrada, este vai para 1 e, se externamente é levado para baixo, então fornece corrente. Se a porta estivesse em alta impedância quando configurado como entrada, então seria classificado como "bidirecional verdadeiro". Figura 8.2 - Pino do microcontrolador sendo levado a 0 por uma saída TTL. 8.2.2Porta P3 Na figura 8.3 está o esquema elétrico da porta P3. Pela porta P3 têm-se diversas funções alternativas: *RD, *WR, T0, T1, TXD, RXD, *INT0, *INT1. Figura 8.3 - Esquema para um bit da porta P3. Quando AOF=1, tem-se na saída a porta P3. Assim, se AOF=1 e for escrito: 0 - Q=0 - G=1 - FET ON - saída=0 1 - Q=1 - G=0 - FET OFF - saída=1 (pull-up) Quando o latch de P3 contém 1, a saída pode ser controlada pelo sinal "Alternate Output Function - AOF". Já foram estudadas as funções alternativas geradas através de P3. Se o latch de P3 está em 0, o pino da porta estará em zero e as diversas funções alternativas não estarão disponíveis. P3 também é uma porta quasi-bidirecional. 8.2.3Porta P2 O esquema da figura 8.4 ilustra a porta P2. Por esta porta também sai o byte mais significativo dos endereços. Figura 8.4 - Esquema para um bit da porta P2. O funcionamento é muito semelhante aos casos anteriores. Se o CONTROL = 0 e for escrito: 0 - Q=0 - M=0 - G=1 - FET ON - saída=0 1 - Q=1 - M=1 - G=0 - FET OFFsaída=1 (pull-up) Se o CONTROL=1, ADDRESS controla o nível no pino. Assim, com CONTROL=1: ADDR=0 _M=0 _G=1 _FET ON _saída=0 ADDR=1 _M=1 _G=0 _FET OFF _saída=1 (pull-up) De acordo com o nível lógico do sinal de CONTROL, permite-se a saída ao latch de P2 ou ao byte alto de endereço. 8.2.4Porta P0 A figura 8.5 ilustra o esquema elétrico da porta P0. Esta porta é a mais complexa pois atende a três funções: bus de dados da CPU byte menos significativo dos endereços porta paralela (bidirecional verdadeira) Figura 8.5 - Esquema para um bit da porta P0. A porta P0 difere das demais por ser utilizada para transportar dados durante as operações com a memória e portanto necessita ser bidirecional verdadeira. Se ela está sendo utilizada como porta paralela, então CONTROL = 0. Com isso G1=0 e F1 está sempre cortado (não existe pull-up). Se CONTROL=0 e for escrito: 0 - *Q=1 - G2=1 - F2 ON - saída=0 1 - *Q=0 - G2=0 - F2 OFF - a saída flutua (não há pull-up). Note que, quando se escreve 1, a porta pode ser utilizada como uma entrada de alta impedância. Para transformá-la em uma porta quase-bidirecional basta colocar externamente resistores de pull-up. Quando a porta é utilizada para enviar endereços ou dados, CONTROL =1 e a saída depende de ADDRESS/DATA (ADR/DT): ADR/DT=0 - G1=0 - F1 OFF e G2=1 - F2 ON - saída=0 ADR/DT=1 - G1=1 - F1 ON e G2=0 - F2 OFF - saída=1 (nunca se terá F1 ON e F2 ON - curto-circuito). Para que a porta possa ser usada na leitura de memória é necessária alta impedância; nesse caso CONTROL=0 e se força uma escrita (com 1) no latch de P0. Se CONTROL=0 - G1=0 - F1 OFF Se Q=1 - *Q=0 - G2=0 - F2 OFF Se F1 e F2 estão em OFF _alta impedância. A leitura da memória é feita com o sinal READ PIN. 8.3Escrita Nas Portas Na execução de qualquer instrução que altere o latch de uma porta, o novo valor chega ao latch durante S6P2, que é o final do ciclo de instrução. Entretanto, os latches são na realidade enviados até os buffers de saída durante a fase P2 de qualquer período de clock (durante P1 se mantém o mesmo valor). Assim, o novo valor aparecerá no pino durante P1 do próximo ciclo (que é S1P1). Se for necessária uma mudança de 0 para 1 nas portas P1, P2 e P3, o PULL-UP deverá entregar bastante corrente para que essa transição seja rápida. Nas transições de 0 para 1, durante S1P1 e S1P2, entra em atividade um PULL-UP adicional que pode fornecer 100 vezes mais corrente que o PULL-UP normal. Note que os PULL-UP são FETs e não transistores bipolares. O PULL-UP normal é um FET (depletion-mode) com a porta (G) conectada à fonte (S). Quando está conectado à terra, circula por ele uma corrente de 0,25 mA. Figura 8.6 - O FET (depletion mode) usado como PULL-UP para as portas paralelas. (HMOS). Na figura 8.7. está o PULL-UP adicional que acelera as transições de 0 para 1. Note quequando A=B=0, a saída S vai para 1 e com isto o transistor entra no circuito fornecendo até 30 mA. Figura 8.7 - Controle para o FET (enhanced mode). (HMOS). Na figura 8.8 está o esquema completo da saída da porta paralela. Figura 8.8 - Acionamento do FET (enhanced mode) nas transições de 0 _1. (HMOS). Note que se *Q vai de 1 → 0, durante dois períodos de clock a saída (S) da porta NOR será 1, permitindo que o enhancement mode FET entre em paralelo com o FET (pull-up) normal, dando maior capacidade de corrente. Este esquema é utilizado em HMOS. Nas famílias CHMOS o esquema varia um pouco mas a idéia é a mesma. Os buffers de saída das portas P1, P2 e P3 podem acionar até 4 cargas LS TTL. Eles podem ser acionados (trabalhando como entrada) por circuitos TTL e NMOS. Como possuem pull-up interno, essas portas também podem ser acionadas por TTL de coletor aberto mas as transições de 0 → 1 não serão rápidas porque o pull-up tem baixa capacidade de corrente. A porta P0 pode acionar até 8 LS TTL (modo BUS). Quando opera como porta paralela, é necessário pull-up externo para acionar outras entradas. Algumas instruções de leitura utilizam o dado armazenado no latch, enquanto outras usam o estado do pino. As instruções que usam o dado do latch são aquelas que lêem o valor, (possivelmente) o alteram e o escrevem de novo (read-modify-write). Quando o destino do operando é uma porta ou um bit da porta, é utilizado o dado do latch e não o valor do pino. A seguir está uma lista destas instruções que operam com o dado do latch: Instrução Exemplo ANL ANL P1,A ORL ORL P2,A XRL XRL P3,A JBC JBC P1.1,LB (pula se bit=1 e zera o bit) CPL CPL P3.0 INC INC P2 DEC DEC P2 DJNZ DJNZ P3,label MOV PX.Y,C MOV P1.0,C CLR PX.Y CLR P1.2 SETB PX.Y SETB P1.3 Pode parecer que as 3 últimas instruções não são do tipo "read-modify-write". Na realidade, é lido todo o byte da porta, o bit considerado é alterado e o novo byte é devolvido para a porta. Uma razão para usar o dado do latch e não o valor do pino é evitar um equívoco na interpretação do nível de tensão do pino, como por exemplo, quando um bit de uma porta está sendo usado para acionar a base de um transistor. Figura 8.9 - Bit 0 da porta 1 sendo usado para acender um led através de um transistor. Quando P1.0=1 → LED aceso Quando P1.0=0 → LED apagado Sem dúvida quando P1.0=1 a tensão no pino vai estar em 0,7 V, o que é um 0 lógico em nível TTL. Espera-se que a instrução CPL P1.0 inverta o estado do led. Supondo que o led esteja aceso (P1.0=1), se a CPU usa o valor do pino, ela vai obter 0 e isto fará P1.0=1, quer dizer, não vai mudar o estado do led. O melhor é usar o dado do latch, que está em 1. 8.4Exemplo - PISCA1 E PISCA2 Acender os 3 leds em seqüência. Não esquecer de colocar um retardo. O led se acende quando se põe nível alto em um bit da porta. ;PISCA1.ASM ; RTD EQU 60000 ;65536>RTD>256 VERMELHO EQU P1.0 AMARELO EQU P1.1 VERDE EQU P1.2 ; DEFSEG PROG, CLASS=CODE, START=0 SEG PROG ORG RESET INIC MOV P1,#0 ;APAGA OS LEDS AQUI SETB VERMELHO LCALL RETARD CLR VERMELHO SETB AMARELO LCALL RETARD CLR AMARELO SETB VERDE L CALL RETARD CLR VERDE SJMP AQUI ; ;ROTINA PARA GERAR UM RETARDO RETARD MOV R7,# HIGH RTD L1 MOV R6,# LOW RTD L2 DJNZ R6,L2 DJNZ R7,L1 RET END Uma outra solução, muito mais simples, pode ser utilizada. Como não são usados os demais pinos da porta P1, pode-se escrever qualquer coisa neles. Usa-se então o Acc e o CY para obter um total de 9 bits e, através de rotações, consegue-se gerar os códigos para acender os leds em seqüência. A figura 8.10 ilustra a idéia. Figura 8.10 - Uso do Acc e CY para acender leds em seqüência. Se Acc e CY são inicializados com estes valores, basta uma rotação com CY (RLC A) para mudar o led que deve ficar aceso. A cada rotação escreve-se o conteúdo de Acc em P1. ;PISCA2.ASM ; RTD EQU 60000 ;65536>RTD>256 VERMELHO EQU P1.0 AMARELO EQU P1.1 VERDE EQU P1.2 ; DEFSEG PROG, CLASS=CODE, START=0 SEG PROG ORG RESET INIC MOV A,#01001001B ; 01 001 001 CLR C AQUI MOV P1,A ACALL RETARD RLC A SJMP AQUI ; ;ROTINA PARA GERAR UM RETARDO RETARD MOV R7,# HIGH RTD L1 MOV R6,# LOW RTD L2 DJNZ R6,L2 DJNZ R7,L1 RET END 8.5Exemplo - CHAVE1, CHAVE2 E CHAVE3 Usando os três leds como um contador de três bits, construir um programa que conte os acionamentos da chave SW2 (a contagem será observada nos três leds). Note que a chave não necessita de pull-up porque usa o pull-up interno da porta. A figura 8.11 ilustra as conexões. Figura 8.11 - Conexões de leds e chave no circuito de práticas. No primeiro programa será usada uma solução simples, que tem o problema de bouncing. ;CHAVE1.ASM ; SW2 EQU P1.3 ; DEFSEG PROG, CLASS=CODE, START=0 SEG PROG ORG RESET INIC CLR A ; ZERAR CONTADOR MOV P1,A ;APAGAR LEDS SETB SW2 ;PROGRAMAR P1.3 COMO ENTRADA AQUI1 JB SW2,AQUI1 ;AGUARDAR ACIONAMENTO INC A MOV P1,A ;DAR SAÍDA AO CONTADOR SETB SW2 ;GARANTIR P1.3 COMO ENTRADA AQUI2 JNB SW2,AQUI2 ;AGUARDAR LIBERAR CHAVE SJMP AQUI1 END No segundo programa é apresentada uma solução para eliminar o bouncing utilizando retardos. Ao detectar uma transição na chave, o programa aguarda um tempo para que se extinga o bouncing. O tempo que se deve aguardar é determinado de forma empírica. ;CHAVE2.ASM ; ; NESTE PROGRAMA SE PRETENDE ELIMINAR O BOUNCING COM RETARDOS ; O VALOR DO RETARDO É PARTICULAR PARA CADA CIRCUITO ; (DEPENDE DO TAMANHO DOS CABOS, QUALIDADE DA CHAVE, ETC) ; RECOMENDA-SE: DETERMINAR EMPIRICAMENTE O MELHOR RETARDO PARA CADA ; CIRCUITO ; RTD EQU 500 ;RTD>256 SW2 EQU P1.3 ; DEFSEG PROG, CLASS=CODE, START=0 SEG PROG ORG RESET INIC CLR A ;ZERAR CONTADOR MOV P1,A ;APAGAR LEDS SETB SW2 ;PROGRAMAR P1.3 COMO ENTRADA AQUI1 JB SW2,AQUI1 ;AGUARDAR ACIONAMENTO INC A MOV P1,A ;DAR SAÍDA AO CONTADOR SETB SW2 ;GARANTIR P1.3 COMO ENTRADA ACALL RTD ;ELIMINAR BOUNCING AQUI2 JNB SW2,AQUI2 ;AGUARDAR LIBERAR CHAVE ACALL RTD ;ELIMINAR BOUNCING SJMP AQUI1 ; ;ROTINA PARA GERAR UM RETARDO RETARD MOV R7,# HIGH RTD L1 MOV R6,# LOW RTD L2 DJNZ R6,L2 DJNZ R7,L1 RET END A solução de aguardar um tempo depois de detetar uma transição na chave funciona bem, mas oferece duas principais desvantagens. A primeira é que se aguarda um intervalo de tempo fixo, ou seja, se a chave de baixa qualidade é trocada por uma de melhor qualidade e que possua pouco bouncing, tem-se que mudar o programa. A segunda desvantagem é sua vulnerabilidade a ruídos pois estes podem provocar acionamentos indevidos. O programa chave 3, apesar de ser simples, soluciona estes problemas. Usam-se duas rotinas que detectam transições de 0 1 e de 1 0; o que se especifica é quanto tempo a chave deve estar em 0 ou em 1 para que se considere o acionamento válido (para que se considere o fim do bouncing). ;CHAVE3.ASM ; ; SOLUCAO MAIS EFICIENTE PARA ELIMINAR O BOUNCING COM RETARDOS ; USAM-SE ROTINAS QUE AGUARDAM A ESTABILIZACAO DA CHAVE ; HA UMA PARA AS TRANSIÇÕES DE 0 PARA 1 E OUTRA DE 1 PARA 0 ; ESTA TECNICA SE ADAPTA MELHOR AS VARIACOES ENTRE OS CIRCUITOS ; RTD EQU 100 SW2 EQU P1.3 ; DEFSEG PROG, CLASS=CODE, START=0 SEG PROG ORG RESET INIC CLR A ;ZERAR CONTADOR MOV P1,A ;APAGAR LEDS SETB SW2 ;PROGRAMAR P1.3 COMO ENTRADA AQUI ACALL RBT_1_0 ;TRANSICAO LIMPA DE 1 PARA 0 INC A MOV P1,A ;DAR SAÍDA AO CONTADOR ACALL RBT_0_1 ;TRANSICAO LIMPA DE 0 PARA SJMP AQUI ; ;ELIMINAR BOUNCING NAS TRANSIÇÕES DE 0 PARA 1 RBT_0_1 MOV R7,#RTD LB1 JNB SW2,RBT_0_1 DJNZ R7,LB1 RET ; ;ELIMINAR BOUNCING NAS TRANSIÇÕES DE 1 PARA 0 RBT_1_0 MOV R7,#RTD LB2 JB SW2,RBT_1_0 DJNZ R7,LB2 RET END 9PORTA SERIAL 9.1Comunicação Série Síncrona E Assíncrona Uma comunicação série de dados poderá ser efetuada de dois modos, síncrono e assíncrono, na comunicação síncrona simples o transmissor e receptor partilham um mesmo sinal de relógio que permite o sincronismo da transmissão com a recepção, neste tipo de comunicação existem muitos formatos e protocolos.Na comunicação assíncrona os bits de dados são enviados a uma velocidade constante mas com um formato específico, no entanto os dados são transmitidos de um forma assíncrona na linha. As UART’s (universal Assíncrona Recebe e Transmite), dispositivos que permitem implementar uma comunicação série funciona na sua essência como registo de deslocamento de série para paralelo na recepção e ao inverso na transmissão de paralelo para série. O formato da transmissão série é mostrado na figura 9.1, e temos que ter em conta a configuração de vários parâmetros, assim: 9.2Parâmetros da comunicação assíncrona Velocidade de transmissão: indica o numero de bits transmitidos por segundo representa-se em bits/s, é também utilizada a designação inglesa baud-rate, que significa o numero de símbolos transmitidos para a representação de cada bit por segundo. No caso da UART do 8051 o numero de bits/s é igual ao baud-rate (pois para cada bit transmitido é utilizado um símbolo ‘0’ ou ‘1’) , existem contudo situações em que os bits/s é inferiores ao baud-rate, casos de modems e outros mecanismo de transmissão em que se codifica vários bits/s num único símbolo. Como se mostra na figura 9.1, o formato da transmissão assíncrona de uma palavra é: start bit: nível lógico zero, serve para indicar ao receptor que vai iniciar a transmissão de uma palavra. No estado repouso a linha esta a nível lógico ‘1’ (idle state). Para iniciar a transmissão de uma palavra o emissor coloca linha a zero durante o tempo de 1 bit, O start bit é sempre ‘0’ e é só um bit. Numero de bits da palavra: é o numero de bits de dados que constituem a palavra. Aqui o bit menos significativo é transmitido em primeiro lugar, sendo os outros transmitidos consecutivamente até ao mais significativo. Tipicamente são 7 ou 8 bits de dados, no entanto os dispositivos UART’s permitem a configuração de 5, 6, 7 e 8 bits de dados. Bit de paridade: este bit é opcional e poderá indicar paridade par ou impar, recorde-se que o bit de paridade é obtido no caso da paridade par pela soma dos bits 1’s da palavra de dados e do bit de paridade é um numero par, no caso de paridade ímpar a soma de bits 1’s e do bit de paridade é um numero ímpar. Como exemplo se a palavra de dados tiver 3 bits 1’s, o bit de paridade para a paridade par é 1, o que faz na sua totalidade 4 bits 1’s - numero par, e será 0 para paridade ímpar o que faz 3 bits de 1’s –numero ímpar. A utilização deste bit permite a identificação da existência de erros na comunicação. stop bit : é sempre a 1, e poderá ser 1 ou 2 bits, tendo como função guardar margem entre duas palavras transmitidas consecutivamente. Para se estabelecer uma comunicação série entre dois equipamentos é, pois necessário considerar todos os parâmetros anteriormente referidos, velocidade, numero de bits de dados da palavra, bit de paridade e numero de stop bits. Figura 9.1- Formato da transmissão série assíncrona. Uma comunicação série assíncrona entre dois dispositivos nunca utiliza a norma TTL, devido á sua baixa imunidade ao ruído, pois obrigaria a uma curta distância entre equipamentos ( um a dois metros). Devido a esse facto foram institucionalizadas várias normas eléctricas para a transmissão tais como: RS232 ou V24, RS 422... A mais utilizada e universalmente aceite pela esmagadora maioria dos fabricantes é a RS232 ou V24, também utilizada nas portas série dos computadores pessoais PC. Figura 9.2- Exemplo a transmissão do caractere “A”, em código ASCII 01000001b, com o formato de 8 bits de dados, paridade ímpar, e um stop bit, para uma velocidade de transmissão de 300 baud, significa que cada bit é transmitido na razão de 1/300 bits/s. Para estabelecer uma comunicação full-duplex (recepção e transmissão em simultâneo) entre dois dispositivos, são necessárias 3 ou 4 linhas como mostrado na figura 9.3 e 9.4. Figura 9.3- Para a transmissão entre dois equipamentos, são necessárias 3 ligações Tx, Rx, GND, massa serve de referencial (caso de comunicação R232). Figura 9.4- Para a transmissão entre dois equipamentos, no caso de se utilizar uma comunicação diferencial do tipo RS422, são necessários 4 fios 2 para Tx e 2 para Rx. 9.3A Porta Serial no 8051 A porta serial no 8051 é full duplex o que significa que pode transmitir e receber em simultâneo. Existe um buffer de recepção, ou seja pode receber um segundo byte, mesmo antes de o primeiro ser lido. Se, entretanto o byte que se encontra no registro de recepção não for lido enquanto o 2 byte estiver a chegar este perde-se. Os registros de transmissão e recepção, são acedidos através do mesmo registro SBUF. A escrita no SBUF, faz com que se escreva no registro de transmissão podemos chamar-lhe TXD, uma leitura do SBUF, faz com que se leia do registro de recepção RXD. 9.4Registros Envolvidos A porta serial possui um registrador chamado SBUF, o mesmo que se usa para enviar ou receber dados pela porta serial. Na realidade, o nome SBUF se refere a dois registros, um somente para leitura por onde se recebem os dados que chegam pela porta serial e outro somente para escrita por onde se transmitem dados pela porta serial. O modo de operação da porta serial é controlado pelo registro SCON, que é ilustrado na figura 9.6. A tabela 9.1 apresenta um resumo dos modos de operação. Figura 9.5 - Descrição do registro SCON. Tabela 9.1 – Modos de operação O registro PCON também toma parte na geração do baud rate da porta serial. Este registro é ilustrado na figura 9.6 Figura 9.6 - Descrição do registro PCON. 9.5Modos de funcionamento A porta série pode funcionar em 4 modos: MODO 0 Aqui 8 bits são transmitidos através do registo TXD, e são recebidos através do RXD: sendo 8 bits de dados (LSB primeiro). O baud rate é fixo a 1/12 da frequência do relógio. Figura 9.7 - Esquema da porta serial em modo 0. MODO 1 Aqui 10 bits são transmitidos através do registo TXD, e são recebido através do RXD: sendo um start bit (nível lógico ‘0’), 8 bits de dados (LSB primeiro) e um stop bit (nível lógico ‘1’). Na recepção, o stop bit fica no bit RB8 do registo SCON. O baud rate é variável. Figura 9.8. Frame de bits gerado pela porta serial em modo 1. Figura 9.9. Esquema para a geração do baud rate (BR) no modo 1. MODO 2 Aqui 11 bits são transmitidos através do registo TXD, e são recebidos através do RXD: sendo um start bit (nível lógico ‘0’), 8 bits de dados (LSB primeiro), um nono bit programável e um stop bit (nível lógico ‘1’). Na transmissão o nono bit é o bit TB8 do registo SCON, este poderá ser o bit de paridade. Na recepção, o nono bit fica no bit RB8 do registo SCON. O baud rate é configurado para ser 1/32 ou 1/64 da frequência de relógio, dependendo do valor do bit SMOD. Figura 9.10 - Frame de bits gerado pela porta serial no modo 2. Figura 9.11 - Esquema para a geração do baud rate (BR) no modo 2. MODO 3 Aqui 11 bits são transmitidos através do registo TXD, e são recebidos através do RXD: sendo um start bit (nível lógico ‘0’), 8 bits de dados (LSB primeiro), um nono bit programável e um stop bit (nível lógico ‘1’). Na transmissão o nono bit é o bit TB8 do registo SCON, este poderá ser o bit de paridade. Na recepção, o nono bit fica no bit RB8 do registo SCON. O baud rate é variável. Nos quatro modo de funcionamento, a transmissão é habilitada pela escrita no registo SBUF. A recepção é iniciada no modo 0, pelas condições RI=0 e REN=1, nos outros modos a recepção é iniciada por REN=1. REGISTO SCON (Serial CONtrol : 98h – endereçável bit a bit ) Este registo permite a configuração do modo de funcionamento da porta, onde se habilita a recepção onde são configurados os nonos bits da recepção e da transmissão, estão também as flags RI e TI, usadas para indicar a recepção de dado e transmissão de um dados respectivamente, também usadas pela interrupções associadas à porta série. Figura 9.12. Frame de bits e geração do baud rate para a porta serial no modo 9.6Velocidade de Transmissão/Recepção ( baud-rate) O baud rate no Modo 0 é fixo a:Modo 0: Velocidade de transmissão O baud rate no modo 2 depende do valor do bit SMOD no registo de funções especiais PCON. Se SMOD igual a 0 (que é o valor no RESET) o baud rate é 1/64 da frequência de oscilação, se SMOD=1, então o baud rate é 1/32 da frequência de oscilação. Modo 2: Velocidade de transmissão: Nos modos 1 e 3 a velocidade de transmissão é determinada pelos overflow do timer 1 ou timer 2, ou pelos 2, um para a transmissão e outro para a recepção. Modos 1 e 3: O timer 1 é usado para gerar o baud rate, o baud rate nos modos 1 e 3, são determinados pelo overflow do timer 1 e pelo valor do bit SMOD. Velocidade de transmissão: Quando se utiliza o timer 1 para gerar o baud rate, a interrupção associada a este timer deve ser desabilitada. O temporizador pode ser configurado como temporizador ou contador e em qualquer dos seus modos de funcionamento, de qualquer modo é habitual utilizar o modo 2 (auto - recarga), então poderemos rescrever a expressão anterior como: Velocidade de transmissão Tabela 9.2 - REGISTO PCON (Power CONtrol: 87h – não endereçável bit a bit ) 9.6 Exemplos de código O algoritmo de comunicação consiste em: 1) No início, todos os escravos estão com SM2 = 1 2) Quando o mestre quiser enviar dados para algum escravo, ele escreverá 1 em seu bit TB8 e então enviará serialmente o endereço do escravo desejado, e como teremos todos os bits RB8 em 1, todos escravos serão interrompidos para verificar se é seu o endereço enviado. 3) O escravo selecionado zerará o seu bit SM2 e estará preparado para receber os dados, os quais terão agora o nono bit (RB8) em 0. 4) Os demais escravos permanecerão com SM2 em 1 e, dessa forma, não serão mais interrompidos pois os dados têm RB8 = 0. 5) Em resumo, o mestre envia endereços com o nono bit em 1 e os dados com o nono bit em 0, portanto, se o mestre desejar se comunicar com outro escravo basta enviar o novo endereço com o nono bit em 1. Rotina de inicialização da UART para transmissão a 9600,N,8,1. ;********************************************************************** ;** Nome: INIT_UART – considere-se um cristal de 11.0592 MHz ;** Descrição: Inicializa a UART ;** Função: Inicializa a UART para transmitir a 9600,N,8,1 ;** Entradas: Nenhumas ;** Saídas: Nenhumas ;** Registos utilizados: PCON, SCON, TMOD, TH1, TCON ;********************************************************************** INIT_UART: mov SCON,#50H ;* modo 1 setb TI ;* inicializa Tx mov TMOD,#20H ;* configura timer 1 em autorecarga mov TH1,#0FAH ;* constante de recarga para velocidade de 9600 70 orl PCON,#80H ;* coloca bit SMOD activo mov TCON,#40H ;* habilita o timer 1 ret; Rotinas para transmitir e receber pela porta série. ;********************************************************************** ;** Nome: envia_char ;** Descrição: envia caractere para a UART ;** Entradas: A= caractere a enviar ;** Saídas: Nenhumas ;** Registos utilizados: SBUF ;********************************************************************** envia_char: clr TI ; reset à flag de Tx mov SBUF,a ; envia o caractere que lhe é passado em A jnb TI,$ ; espera até acabar a transmissão clr TI ; reset à flag de Tx ret ; retorna da sub-rotina ;********************************************************************* ;** Nome: recebe_char ;** Descrição: recebe caractere para a UART ;** Entradas: Nenhumas ;** Saídas: devolve em A, o caractere recebido ;** Registos utilizados: SBUF ;********************************************************************* recebe_char: jnb RI,$ ; espera até que chegue um dado mov a,SBUF ; lê o caractere da UART, para o registo A clr RI ; reset à flag de Rx ret ; retorna da sub-rotina Rotinas para transmitir uma string (“Microcontroladores”) pela porta série. ;********************************************************************* ;** Nome: envia_string ;** Description: envia um conjunto de caracteres pela porta série ;** Chamadas: envia_char ;** Entradas: Nenhuma ;** Saídas: Nenhuma ;** Registos utilizados: A, DPTR ;********************************************************************* envia_string: mov dptr,#ID_string ;* ponteiro para rotina a transmitir ciclo: clr a ; garante o offset do A=0 movc a,@a+dptr ; lê o valor da tabela jz emvia_string_X ; se for 00h, significa que é o fim da ; string e sai inc dptr ; senão continua, actualiza o ponteiro dptr lcall envia_char ; chama rotina para enviar um caractere ajmp ciclo ; ciclo até acabar envia_string_X: ret ID_string: Db 'Microcontroladores' db 0DH ; caracteres controlo: carriage return db 0AH ; caracteres controlo: line-feed db 00H ; valor 00h, para indicar o fim da sequência ; a transmitir 10COMPARAÇÃO COM OUTROS MICROCONTROLADORES 10.1PIC16 Memória de programa (ROM) A memória de programa dos PICs é bastante diferente da do 8051. Cada endereço de memória tem 14 bits. Ex.: quando se fala que um PIC tem 1K de memória de programa, quer dizer que ele tem 1024 endereços com 14 bits cada. Estes 14 bits contém, além da instrução, os dados a ela associados. Ex.: no 8051 MOV A,#0FF (74,FF) 2 endereços de 8 bits no PIC MOVLW 0xFF (30FF) 1 endereço de 14 bits Em um PIC de 1K de memória poderá ser colocado 1K instruções. Em um 8051 a quantidade e definida pelo número de posições de memória que cada instrução ocupa (entre 1 e 3), mas certamente a quantidade de instruções será bem menor que 1K. O PIC não suporta memória de programa externa. Há modelos de PIC com memória de programa tipo OTPROM, EEPROM e FLASH. Em PICs com memória maior que 2K a memória ROM é dividida em páginas e a troca de páginas não é automática, necessitando muita atenção do programador. Memória RAM Como o 8051 o PIC também possui memória RAM interna. Cada endereço também possui 8 bits. Geralmente os PICs tem sua memória RAM dividida em bancos. EX.: PIC16F84 com 3 bancos. PIC16C924 com 4 bancos. Estes bancos são diferentes dos bancos de registradores do 8051. Entre eles sempre há uma área comum para troca de dados entre os bancos. O PIC não suporta memória RAM externa. I/O Normalmente, como no 8051, os pinos dos PICs podem ser utilizados como entrada ou saída. Porém nos PICs os pinos devem ser configurados. Esta configuração pode ser alterada a qualquer momento de execução do seu software, via software. Assim como no 8051 as portas de I/0 são tratadas como endereços da memória interna. Periféricos Os PICs tem uma grande gama de periféricos. Dependendo do modelo podem ter: EEPROM, interface serial SPI, I2C e CAN, entradas analógicas, driver para LCD, contadores, timers, watchdog, etc. Instruções Os PICs possuem uma quantidade de instruções bem menor que o 8051. Não há instruções de multiplicação e divisão. O PIC tem algo parecido com um cache de instruções fazendo com que a cada ciclo de máquina seja encerrada uma instrução, apesar delas necessitarem de 2 ciclos. Isto só não ocorre com instruções de salto, que realmente utilizam 2 ciclos de máquina. Cada ciclo de máquina leva quatro ciclos de clock. Importante: todos os bits de RAM podem ser acessados pelas instruções de teste e manipulação. No 8031 isto só ocorre com os endereços de 20 a 3F e com os específicos como o Acc, B, portas, TMOD, etc. Custo Um PIC 16F84 U$ 7,00 Um PIC 16C924 U$ 11,00 Ferramentas de Desenvolvimento MPLAB - Software freeware para editar, simular e compilar os programas. GRAVADOR - Vários modelos estão disponíveis na Internet, principalmente para o PIC 16F84, que é um dos mais comuns. MPLAB-C - Compilador C para PIC, NÃO é freeware. C2C - Compilador C freeware para PIC. Está na página: http://www.picant.com/c2c/c.html Outros dados Depois do 8051 a linha PIC é a mais popular, muito devido ao fato de serem os primeiros microcontroladores a possuirem versões com memória de programa flash. A SCENIX (http://www.scenix.com) possui micontroladores compatíveis com os PICs que rodam com até 100MHz de clock. Na figura 10.1,segue o diagrama interno do PIC16F86 Figura 10.1 – Diagrama do PIC 16F86. 10.2Microcontroladores Motorola - HC05 e HC08 Memória a família HC05 existe apenas uma memória, onde o endereço é que determina seu tipo (ROM, RAM, PORTS, TIMERS, etc.). O tamanho máximo da memória principal no família HC05 é 64Kbytes. Um exemplo genérico: 0000h - 001Fh - Portas de I/O , Timers, etc. 0020h - 00BFh - Não usado 00C0h - 00FFh - RAM 0300h - 0700h - ROM 07F0h - 07FFh - Vetores de Partida. No 8051, para cada tipo de dado existe um tipo de memória (ROM, RAM externa, RAM interna). Memória ROM Esta localizada na memória principal. Por exemplo para o 68HC705JK1 está no endereço de 300h até 700h e no 68HC908QY4 de EE00h até FDFFh. Pode suportar ROM externa, dependendo do modelo. A linha HC05 não possui memória rom flash. A linha HC08, mais moderna, tem memória flash. Memória RAM Esta localizada na memória principal. No 68HC705JK1 de C0h até FFh e no 68HC908QY4 de 80h até FFh. A família HC05 e HC08 não suportam memória RAM externa. I/O Normalmente, como no 8051, os pinos dos HC05 e HC08 podem ser utilizados como entrada ou saída. Porém na família HC05 os pinos devem ser configurados. Esta configuração pode ser alterada a qualquer momento de execução do seu software, via software. Assim como no 8051 as portas de I/0 são tratadas como endereços de memória. Periféricos Tanto a família HC05, como a HC08, tem uma grande gama de periféricos. Dependendo do modelo podem ter: EEPROM, interface serial SPI, I2C e CAN, entradas analógicas, contadores, timers, watchdog, driver para LCD, etc. Instruções As família HC05 e HC08 contam com mais instruções que a família MCS51. As instruções são mais amigáveis o que torna o assembler muito fácil de ser programado e entendido. O ciclo de máquina tem apenas 2 pulsos de clock para a linha HC05 e 4 pulsos para HC08 e as instruções levam de 2 a 5 ciclos de máquina para serem executadas. A linha HC05 não conta com divisão em hardware. Custo Um MC68HC705KJ1A U$ 0,90 Um MC68HC705JIACS U$ 25,00 Um MC68HC908QY4 U$ 1,50 Ferramentas de Desenvolvimento A Motorola fornece um software chamado MCUez, que é um ambiente de desenvolvimento completo, contando com assemblador, simulador e programador (para a linha HC05 é necessário comprar o hardware do programador, para a linha HC08 o gravador é simples e há esquemas para o gravador na internet). O software é gratuito. Existem vários ambientes de desenvolvimento disponíveis por terceiros. Alguns freeware e outros comerciais. A Motorola não fornece o protocolo de gravação dos CI’s da linha HC05, assim é necessário adquirir um programador para esta linha, seja ele da Motorola ou de terceiros. Não existe compiladores C grátis para os microcontroladores HC05, mas para a linha HC08 sim. Outros dados Os microcontroladores Motorola são amplamente usados em equipamentos comercias devido a seu baixo custo. A linha HC08 não necessita nem oscilador externo, nem reset externo. Um oscilador e o reset externo podem ser utilizados, mas se não forem seus pinos podem ser usados com I/O. Na Figura 10.2, segue o diagrama interno do MC68HC705J1A. Figura 10.2 – Diagrama do MC68HC705J1A. Na Figura 10.3, segue o diagrama interno do MC68HC908Q. Figura 10.3 – Diagrama do MC68HC908Q. 11REFERENCIAS BIBLIOGRÁFICAS ZELENOVSKY, RICARDO. “Micro Controladores MCS51” . Apostila do Curso de Eletrônica da Escola Politécnica Superior do Exército Equatoriano. INTEL CORPORATION. “MCS 51 Microcontroller Family User’s Manual”. USA. 1994. MARINHO, JOSÉ EDSON DOS SANTOS. MARINHO, EDNALDO DOS SANTOS. “Mini-Curso de Microcontrolador”. Revista Saber Eletrônica Especial No.2. Janeiro de 2001. 89 P rofº. Ricardo Franco www.engricardofranco.kit.net / engricardofranco@gmail.com