Preview only show first 10 pages with watermark. For full document please download

Diário Eletronico

Criacao de um diario eletronico utilizando microcontrolador 8051

   EMBED


Share

Transcript

Universidade Federal de Goiás Escola de Engenharia Elétrica e de Computação REGISTRO DE FREQUÊNCIA MICROCONTROLADO Carlos Renato Borges dos Santos José Lemes de Souza Júnior Orientador: Prof. Dr. José Wilson Lima Nerys Goiânia 2003 Carlos Renato Borges dos Santos José Lemes de Souza Júnior 2 REGISTRO DE FREQUÊNCIA MICROCONTROLADO Dissertação de Projeto Final apresentada ao Curso de Graduação em Engenharia Elétrica da Universidade Federal de Goiás, para obtenção Do título de Engenheiro Eletricista. Área de concentração: Microprocessadores. Orientador: Prof. Dr. José Wilson Lima Nerys. Goiânia 2003 Carlos Renato Borges dos Santos José Lemes de Souza Júnior 3 REGISTRO DE FREQUÊNCIA MICROCONTROLADO Dissertação defendida e aprovada em _____ de _____________ de ________, pela Banca Examinadora constituída pelos professores. __________________________________________ Prof. José Wilson Lima Nerys, PhD __________________________________________ Prof. Sérgio Figueredo __________________________________________ Eng. Wanir José de Medeiros 4 AGRADECIMENTOS Aos nossos pais, familiares e namoradas pelo apoio e dedicação dados. Ao professor, José Wilson Lima Nerys, pela confiança e orientação deste trabalho. Agradecemos, também, aos professores do curso. Um agradecimento especial aos nossos colegas, Eng. Antônio Marcos de Melo Medeiros e ao Eng. Wanir José de Medeiros, que nos auxiliaram no desenvolvimento deste projeto. 5 SUMÁRIO LISTA DE FIGURAS 9 LISTA DE TABELAS 11 SIGLAS UTILIZADAS 12 RESUMO 13 ABSTRACT 14 1 Introdução 15 1.1 Aspectos Gerais 15 1.2 Objetivos 15 1.3 Estrutura de Dissertação 16 2 Manual do Software DiarioClasse 17 2.1 Introdução 17 2.2 Como Instalar o DiarioClasse 17 2.3 Manuseio do Software 20 2.3.1 Inserindo Alunos 20 2.3.2 Editando alunos já inseridos no banco de dados 21 2.3.3 Excluindo alunos já inseridos no banco de dados 21 2.4 Enviando dados ao Circuito 24 2.4.1 A Conexão 21 2.4.2 Enviando dados 23 2.4.3 Configurando o RTC 23 2.4.4 Recebendo dados do Circuito 23 2.5 O banco de dados - Freqüência de Alunos 26 2.5.1 Atualizando o banco de dados 26 2.5.2 Listando dados 27 2.6 Estimando a capacidade da EEprom 28 2.7 Resumo deste capítulo 28 3 Manual do Hardware 29 3.1 Introdução 29 3.2 Ligando e desligando o circuito 29 3.3 Conectando ao PC 30 3.4 O relógio do circuito 31 6 3.4.1 Configurando a data e a hora 31 3.4.2 Verificando a data e hora 31 3.5 O circuito em sala de aula 31 3.6 Verificando o percentual da EEprom usado 32 3.7 Descarregando os dados da RAM no PC 33 3.8 A Expansão de memória 33 3.9 Revisão geral do capítulo 34 4 O Sistema Mínimo 35 4.1 Considerações 35 4.2 O Microcontrolador 35 4.2.1 Características 36 4.2.2 Comunicação com o RTC 37 4.2.3 Comunicação com o PC 37 4.3 EEPROM 37 4.3.1 Características Funcionais 37 4.3.2 Descrição 37 4.4 Decodificador 38 4.4.1 Descrição Geral 38 4.4.2 Características 38 4.5 Sistema com Mapeamento de Memória 40 5 Periféricos 42 5.1 O display LCD 42 5.1.1 Introdução 42 5.1.2 Interface com CPU 44 5.1.3 Inicialização do módulos LCD 45 5.1.4 Roteiro para programação 46 5.2 O Teclado 48 5.2.1 Características 48 5.2.2 Teoria da Operação 49 5.3 RTC - Chip de Armazenamento de tempo 50 5.3.1 Características 50 5.3.2 Descrição 51 5.3.3 Circuito de operação típico 52 5.3.3.1 Operação 52 7 5.3.3.2 Descrições do Sinal 53 5.3.3.3 Exatidão do Clock 54 5.3.3.4 Comando Byte 54 5.3.3.5 Endereçamento\Comando Byte 54 5.3.3.6 Controle de Reset e Clock 55 5.3.3.7 Entrada de Dados 55 5.3.3.8 Saída de Dados 55 5.3.3.9 Modo de estouro 56 5.3.3.10 Clock\Calendário 56 5.3.3.11 Flag de parada do Clock 56 5.3.3.12 Modo AM-PM\12-24 56 5.3.3.13 Bit de Proteção da Escrita 57 5.3.3.14 Registro de Carga Lenta 57 5.3.3.15 Modo de Estouro do Clock\Calendário 58 5.3.3.16 RAM 58 5.3.3.17 Modo de Estouro da RAM 58 5.3.4 Resumo dos Registros 59 5.3.5 Aplicação ao 8051 60 5.4 O chip Max 232 60 5.4.1 Descrição Geral 60 5.5 O chip 4066 61 5.5.1 Descrição Geral 61 6 O armazenamento de dados na EEprom 63 6.1 Introdução 63 6.1.1 A Pilha Controle 64 6.1.2 A Pilha ALUNOS 65 6.1.3 A Pilha "Frequencia" 66 6.2 Uma visão geral da utilização da EEprom 67 7 A comunicação Serial 68 7.1 A Serial do 8051 68 7.1.1 Comunicação com o RTC 68 7.1.2 Comunicação com o PC 68 7.2 O Protocolo de Comunicação Serial 69 7.2.1 Os Conectores 69 8 7.2.2 Verificação e correção de erros 70 7.2.3 Armazenamento de dados na RAM 71 7.2.3.1 Conectando 71 7.2.3.2 Envio de dados 71 7.2.3.3 Configurando a data e a hora 72 7.2.2.4 Recepção de dados 72 8 Conclusão 75 REFERÊNCIAS 76 ANEXO 77 9 LISTA DE FIGURAS Cap II Fig 2.1 Como funciona o Banco de Dados 17 Fig 2.2 Explorando o Database do Delphi 18 Fig 2.3 SQL Explorer 18 Fig 2.4 Criando Database Alias 18 Fig 2.5 O Select Directory 19 Fig 2.6 Salvando o Database Alias 19 Fig 2.7 Mensagem de Confirmação 19 Fig 2.8 Salvando o SQL Explorer 20 Fig 2.9 O banco de dados Alunos Matriculados 20 Fig 2.10 A janela de conexão serial 22 Fig 2.11 Conectado! 22 Fig 2.12 Enviando dados 23 Fig 2.13 Botão Receber habilitado 24 Fig 2.14 Recebendo dados 25 Fig 2.15 O banco de dados de Frequências 25 Fig 2.16 Atualizando o banco de dados 26 Fig 2.17 Salvando o banco de dados no Excel 27 Fig 2.18 O banco de dados das frequências mensais 27 Cap III Fig 3.1 Tela principal 29 Fig 3.2 Pronto para desligar o interruptor 29 Fig 3.3 Cabo conectado 30 Fig 3.4 Mensagem de conectado ao PC 30 Fig 3.5 Recebendo dados 30 Fig 3.6 Recepção de dados terminada 30 Fig 3.7 Pronto para digitar a matrícula 31 Fig 3.8 O nome do aluno aparece no LCD 32 Fig 3.9 O aluno não está matriculado 32 Fig 3.10 Mensagem quando mais de 6 números são digitados 32 Fig 3.11 Quando menos de 6 dígitos são teclados 32 10 Fig 3.12 Percentual de dados armazenados na RAM 33 Fig 3.13 Enviando dados para o PC 33 Fig 3.14 Fim do envio de dados 33 Cap IV Fig 4.1 Configurações dos pinos da EEprom 38 Fig 4.2 Configurações de Conexão do 74138 39 Fig 4.3 Esquema do mapeamento de memória 41 Fig 5.1 Alimentação do LCD 44 Fig 5.2 (A) Escrita no LCD (B) Ciclo de escrita da CPU 8051 44 Fig 5.3 Diagrama de conexão 49 Fig 5.4 Esquema de ligação do chip ao teclado 50 Fig 5.5 Esquema dos pinos do RTC 51 Fig 5.6 Esquema de ligação serial do RTC 52 Fig 5.7 Elementos principais do RTC 53 Fig 5.8 Byte de endereçamento do RTC 54 Fig 5.9 A transferência de dados do RTC 59 Fig 5.10 Os registradores do RTC 59 Fig 5.11 Esquema de funcionamento do MAX232 61 Fig 5.12 Esquema de funcionamento do 4066 62 Cap V Cap VI Fig 6.1 A divisão da EEprom em pilhas 63 Fig 6.2 A Pilha CONTROLEA 64 Fig 6.3 Detalhe dos Ponteiros das pilhas 64 Fig 6.4 A pilha ALUNOS 65 Fig 6.5 A Pilha FREQUENCIAS 66 Cap VII Fig 7.1 Esquema dos conectores DB9 69 Fig 7.2 Os bytes da recepção de dados no PC 73 11 LISTA DE TABELAS Cap V Tabela 5.1 Módulos LCD disponíveis 42 Tabela 5.2 Pinagem dos módulos LCD 43 Tabela 5.3 Relação de Clock da CPU x temporização do módulo LCD 45 Tabela 5.4 Endereçamento do módulo LCD 45 Tabela 5.5 Inicialização para sistemas de 8 bits de dados 46 Tabela 5.6 Comandos úteis do LCD 47 Tabela 5.7 Bits de configuração do registrador de Carga Lenta 57 Tabela 5.8 Descrição dos pinos do 4066 61 12 SIGLAS UTILIZADAS KB: KiloByte m: mili µ: micro η: nano W: Watt A: Ampere V: Volt GND: 0V Vcc: 5V RD: Bit Read do 8051 WR: Bit Write do 8051 OE: Output Enable ALE: Address Latch Enable CI: Circuito Integrado LCD: Liquid Cristal Display RTC: Real Time Count 13 RESUMO Este projeto consiste na implementação de um circuito que faz o controle de frequência microcontrolado para ser usado em sala de aula na disciplina Microprocessadores e Microcomputadores do curso de Engenharia Elétrica da Universidade Federal de Goiás – UFG. O sistema deve permitir o registro de data completa e hora de chegada do aluno em sala de aula. O registro de presença deve ser via matrícula, seguindo de tecla de confirmação do aluno. O registro deve permitir a listagem posterior dos alunos presentes em cada uma das aulas ministradas ao longo de um mês e ainda a listagem das aulas assistidas pelo aluno. A transferência dos dados do sistema para o computador deve ser via porta serial. Foram utilizados alguns equipamentos e componentes, dos quais os principais são: Microcontrolador da família 8051, display LCD, memória EEprom, teclado, RTC (real time clock), MAX232, Chip 4066, Chip 74LS373, Chip 74LS138, Chip 74C922, 2 Chips 7400 e microcomputador. O sistema registra todas as freqüências dos alunos, apenas digitando sua matrícula, salvando a data completa do dia da aula. Este acesso é feito via teclado através da digitação da matrícula. Os registros ficarão gravados na EEPROM e só serão apagados no momento em que esses dados forem retirados pelo microcomputador via porta serial. Durante o acesso, matrícula e nome poderão ser visualizados através do display LCD. 14 ABSTRACT This project consists of the implementation of a circuit that makes the microcontrolled control of frequency to be used in classroom in disciplines Microprocessors and Microcontrollers of the course of Electric Engineering of the UFG. The system must allow to the register of complete date and hour of arrived pupil in classroom. The presence register must be saw school registration, following of keyboard key of confirmation of the pupil. The register must still allow to the posterior listing of the pupils gifts in each one of the lessons given throughout one month and the listing of the lessons attended for pupil. The transference of the data of the system for the computer must be saw door serial. Some equipment had been used and component, of which the main ones are: Microcontroller of family 8051, display LCD, EEprom memory, keyboard, RTC (real teams clock), MAX232, Chip 4066, Chip 74LS373, Chip 74LS138, Chip 74C922, 2 7400 Chips and microcomputer. The system registers all the frequencies of the pupils, typing its only registers, saving the complete date of the day of the lesson. This access is made way keyboard through the type of the school registration. The registers will be recorded in the EEPROM and alone they will be extinguished at the moment where these data will be removed by the microcomputer saw door serial. During the access, school registration and name could be visualized through display LCD. 15 CAPITULO I 1 Introdução 1.1 Aspectos Gerais Atualmente, os microcontroladores são partes integrantes na sociedade. É cada vez maior a aplicação destas ferramentas em empresas e até no uso doméstico. O Registro de Freqüência Microcontrolado é um sistema que mostra a importância e a aplicação dos microcontroladores aos alunos de engenharia elétrica ou qualquer outra pessoa interessada no assunto. Com apenas o teclado, os alunos poderão efetuar a sua presença em sala de aula de forma automática e eficiente, reduzindo o tempo do professor em conferir e contar as freqüências dos alunos nas listas de chamada a cada mês. 1.2 Objetivos Este projeto tem como objetivo a implementação de um sistema microcontrolado de controle de freqüência dos alunos da disciplina Microprocessaderes e Microcomputadores. Ele facilita o controle de freqüência dos alunos, que é realizado pelo professor. Depois da implantação do sistema os alunos deverão ser previamente cadastrados, para então registrar suas freqüências. Esses acessos serão gravados na memória do sistema e permitirão ao professor descarregar os mesmos no microcomputador identificando assim todas as freqüências dos alunos em sala de aula. Esses acessos serão descarregados no microcomputador via porta serial, e serão tratados por um programa na linguagem Delphi. O programa irá converter todos esses dados recebidos em informações, e as salvará no Excel, que poderá ser usado pelo professor para impressão dos dados. O programa também tem a função de acrescentar e excluir alunos, e estimar o tempo total que o sistema pode ficar sem descarregar os dados nele armazenados. O projeto prevê o alerta sonoro quando o aluno efetuar sua presença em sala de aula. 16 O projeto prevê ainda, a possibilidade de expansão de capacidade de armazenamento de 8KB a 56KB, podendo ser utilizado para mais de um professor, e mais de uma turma. A expansão poderá informar ao microcontrolador e ao programa a capacidade de armazenamento disponível, evitando que seja enviado mais dados do que a capacidade de armazenamento. Outro objetivo do projeto é despertar o interesse dos alunos na disciplina de Microprocessadores e Microcomputadores, mostrando a vasta gama de aplicações de sistemas microcontrolados. 1.3 Estrutura da Monografia Com vista a atingir as metas supra citadas, este trabalho apresenta-se desenvolvido com a seguinte estrutura: – Capítulo II - Descreve o funcionamento do software, desde a instalação até a recepção dos dados pela serial. – Capítulo III - Descreve o funcionamento do hardware, desde a transferência de dados pela serial , até seu uso em sala de aula . – Capítulo IV - Descreve o sistema mínimo, com seus componentes básicos, e a função de cada um no sistema, assim como seu funcionamento e o modo de usar de cada um. – Capítulo V - Destinado a interface homem-máquina, esta parte explica como podemos entrar dados, receber informações pelo visor. – Capítulo VI - Descreve como os dados são armazenados na EEPROM. – Capítulo VII - Descreve o protocolo de comunicação entre o PC e o 8051. 17 CAPITULO II 2 Manual do Software DiarioClasse 2.1 Introdução Este software foi desenvolvido com a ferramenta Delphi, versão 4.0, ligado ao banco de dados Paradox, do próprio Delphi. 2.2 Como Instalar o DiarioClasse No CD, clique duas vezes o programa Setup da pasta Install e o programa será instalado automaticamente. Porém, se tiver algum problema com o instalador, desinstale-o e siga os seguintes passos a seguir: O software, para funcionar, precisa de um servidor de banco de dados. No software DiarioClasse, foi usado o Database, instalado juntamente com o Aplicativo Delphi. Arquivos do Banco de Dados Servidor do Banco de Dados Software DiarioClasse Figura 2.1 Como funciona o Banco de Dados Conforme visto na Figura 2.1, o DiarioClasse, assim como qualquer software que utiliza banco de dados, acessa os arquivos do banco de dados apenas com o servidor do banco de dados. Para que o software funcione corretamente, copie a pasta “Diario de Classe” no diretório “Arquivos de Programas”. Após isso, abra o Delphi e, no menu Database, clique em Explore (veja Figura 2.2) . 18 Figura 2.2 Explorando o Database do Delphi Após isso, aparecerá uma nova janela chamada SQL Explorer. No menu Object, clique em New, para criar um novo banco de dados (veja Figura 2.3). Figura 2.3 SQL Explorer O novo banco de dados deverá ser chamado “Banco_DiarioClasse” (veja Figura 2.4). Figura 2.4 Criando Database Alias Agora, na tela Definition, existe alguns parâmetros a serem preenchidos. No parâmetro PATH, clique no botão cinza. Aparecerá a seguinte janela: 19 Figura 2.5 O Select Directory Agora, apenas clicando duas vezes, vá para o caminho ‘C:\Arquivos de Programas\Diario de Classe\DB’. Agora clique em OK. Figura 2.6 Salvando o Database Alias Agora, na janela SQL Explorer, você precisa salvar as alterações, então clique no botão onde aparece a mensagem ‘Apply’ mostrada na Figura 2.6. Figura 2.7 Mensagem de Confirmação Aparecendo a mensagem de confirmação da Figura 2.7, clique em OK. Agora feche o SQL Explorer. Aparecerá a mensagem da Figura 2.8; clique em Yes. Agora 20 quando o DiarioClasse procurar pelo banco de dados “Banco_DiarioClasse”, o servidor do banco de dados informa em que diretório estão as tabelas do banco de dados que o software precisa. Figura 2.8 Salvando o SQL Explorer Agora o software está pronto para ser executado! 2.3 Manuseio do Software 2.3.1 Inserindo Alunos Abra o Software DiarioClasse. Aparecerá a janela de acordo com a figura 2.9: Figura 2.9 O banco de dados Alunos Matriculados Agora siga os seguintes passos: – Clique no Campo de texto ‘Nome Completo’ e digite o nome completo do aluno; 21 – O campo ‘Nome’ será preenchido automaticamente. Este será o nome que aparecerá no display LCD, portanto, retire caracteres especiais, letras acentuadas ou “ç”, pois estes caracteres não aparecerão no LCD. – No campo Matrícula, digite 6 números que correspondam à matrícula do aluno. Nunca deixe menos de 6 números neste campo. – Após digitar os seis dígitos da matrícula, o botão Inserir será habilitado automaticamente; clique neste botão e o aluno será inserido no banco de dados. 2.3.2 Editando alunos já inseridos no banco de dados Para editar algum campo de algum aluno já inserido no banco de dados, clique na linha em que o aluno estiver na lista de alunos. Após isso, os dados do aluno aparecerão nos campos de texto, onde você poderá editar qualquer campo em questão. Após isso, clique no botão Editar e as alterações serão armazenadas no banco de dados. 2.3.3 Excluindo alunos já inseridos no banco de dados Para excluir algum aluno, clique no aluno que você queira excluir da lista e clique no botão Menos ( – ). 2.4 Enviando dados ao Circuito 2.4.1 A Conexão Após inserir todos os alunos, clique no botão Conexão Serial. Aparecerá a seguinte tela: 22 Figura 2.10 A janela de conexão serial Siga agora os seguintes passos para conectar o PC ao Sistema de Armazenamento de Freqüências em Sala de Aula: – Escolha a porta serial em que o sistema esteja conectado. – Clique no botão onde o mouse da figura está em cima, mostrando a mensagem Conectar ao PC. Se não mudar a tela, clique novamente. A nova tela será a que aparece na figura abaixo: Figura 2.11 Conectado! 23 Se a memória EEprom estiver com dados armazenados, o botão Receber estará habilitado, mas se não tiver dados sobre freqüência de alunos armazenados, o botão Receber estará desabilitado, como na Figura 2.11, acima. 2.4.2 Enviando dados Para enviar os dados ao Sistema de Armazenamento de Freqüências em Sala de Aula, basta simplesmente clicar no botão Enviar. Figura 2.12 Enviando dados 2.4.3 Configurando o RTC O RTC (Real – Time Clock) do Sistema, assim como qualquer relógio, precisa ser atualizado a hora; para isto o programa possui duas maneiras práticas de se atualizar a hora do RTC. O primeiro modo é atualizar a hora juntamente com os dados dos alunos, selecionando a opção Atualizar. Na Figura 2.11, esta opção já está selecionada de forma que quando o botão Enviar for clicado, a hora será atualizada juntamente com o envio dos dados dos alunos. O segundo modo serve para atualizar a hora sem alterar os dados armazenados na EEprom. Para isto, clique no desenho Calendário no lado direito da opção Atualizar. 24 2.4.4 Recebendo dados do Circuito A recepção de dados será possível somente quando houver dados armazenados na EEprom. Quando o programa conecta ao Sistema, este por sua vez, informa ao programa se a EEprom está com informações para serem transmitidas. Quando não houver, o botão Receber ficará desabilitado (Figura 2.11), senão estará habilitado (Figura 2.13). Figura 2.13 Botão Receber habilitado Se o botão Receber estiver habilitado (ver Figura 2.13). Clique nele e o envio de informações se iniciará (ver Figura 2.14). Após isso, o Sistema apagará somente os dados de freqüência dos alunos na RAM, deixando somente os dados de nome, código e matrícula dos alunos ali armazenados anteriormente. Todos os dados recebidos do Sistema ficarão armazenados no banco de dados, chamado “Freqüência”, mostrado na figura 2.14. 25 Figura 2.14 Recebendo dados Figura 2.15 O banco de dados de Frequências Neste banco de dados ficam armazenados todos os dados recebidos do Sistema. Será visto no item 2.5 como relacionar a quantidade de freqüências de cada aluno e enviá-las ao Excel. 26 2.5 O banco de dados – Frequência de Alunos 2.5.1 Atualizando o banco de dados Como anteriormente discutido, todos os dados que chegam da EEprom são armazenados no banco de dados “Freqüência”. Para saber qual é a freqüência de cada aluno, o programa associa a lista de alunos matriculados com o banco de dados “Freqüência”, e guardando estes dados no banco de dados “FrequênciaAlunos”. Para atualizá-lo e salvá-lo no banco de dados, siga os seguintes procedimentos: – Clique no botão Freqüência Mensal e aparecerá a tela da Figura 2.16 abaixo; – No canto inferior direito da tela, escolha o mês e o ano que se quer que o banco de dados seja atualizado; – Selecione a opção próxima ao botão Atualizar (este botão está desabilitado) para habilitá-lo; – Clique no botão Atualizar, aparecerá a mensagem ‘Atualizando banco de dados, por favor aguarde’. Agora é só esperar que o banco de dados de freqüência de alunos seja atualizado. Após isso, será guardado uma cópia do banco de dados em um arquivo do Excel ( Na pasta: C:\Arquivos de Programas\Diario de Classe\Excel). Figura 2.16 Atualizando o banco de dados Na Figura 2.16 acima, o banco de dados “Freqüência Mensal” está sendo atualizado. 27 Figura 2.17 Salvando o banco de dados no Excel Na Figura 2.17 acima, o programa está salvando uma cópia do banco de dados no Excel. 2.5.2 Listando dados Para listar dados já atualizados do banco de dados, basta selecionar o mês e o ano. Após isso, clique no botão Listar no canto inferior direito da tela (ver Figura 2.18). Figura 2.18 O banco de dados das frequências mensais Figura 2.18 O banco de dados das frequências mensais 28 2.6 Estimando a capacidade da EEprom Para saber qual é o tempo máximo que o a EEprom pode suportar sem estourar a capacidade de armazenamento, clique no Menu: Ferramentas → Estimativa da RAM, digitando o número de alunos, o número de aulas por semana, a capacidade da RAM e clique em calcular. Aparecerá o tempo em semanas e meses que a RAM suportará armazenar os dados. 2.7 Resumo deste capítulo Este software é bastante simples. Na parte superior direita existe quatro botões que definem: – A conexão serial. Nesta tela é onde software conecta com o Sistema. Aqui há a configuração da data e da hora, o envio e a recepção de dados. – O banco de dados dos Alunos Matriculados. Nesta tela é onde todos os alunos matriculados devem ser inseridos, editados ou excluídos. São os dados desta tela que serão enviados para o Sistema. – Freqüência Mensal. É nesta tela onde o número total de freqüências mensais são atualizados. – Freqüências. Nesta tela ficam armazenados todos os dados recebidos do Sistema. 29 CAPITULO III 3 Manual do Hardware 3.1 Introdução Este hardware tem como finalidade armazenar as freqüências dos alunos em sala de aula e, no final do mês (ou sempre que a EEprom estiver quase toda preenchida), descarregar os dados armazenados no circuito para o computador. Para registrar a data e horário em que se iniciou a aula, o circuito possui um CI responsável por conservar a hora, minuto, segundo, dia do mês, mês, dia da semana e ano, mesmo com o circuito desligado. Outro tópico importante é a capacidade de armazenamento de dados, que é de 8 KB, mas o circuito possui expansão para até 56 KB. 3.2 Ligando e desligando o circuito Para ligar o circuito, basta ligar o interruptor. Aparecerá no display a seguinte mensagem: Diario de Classe Eletronico – EEE Figura 3.1 Tela principal Para economizar energia e preparar o circuito para desligar, aperte o botão “Desligar”. Quando o botão for pressionado, aparecerá, por alguns segundos, a seguinte tela: O sistema pode ser desligado! Figura 3.2 Pronto para desligar o interruptor Após a tela mostrada acima, o display apagará a mensagem, entrando no modo “desliga”. Além disso, o microcontrolador do circuito entrará no estado de “Power Down”, economizando energia e garantido que o circuito possa ser desligado no 30 interruptor com segurança. Se você apertar este botão sem querer, você pode apertar o botão “Reset”, sem precisar desligar e ligar o interruptor novamente. 3.3 Conectando ao PC Para carregar os dados dos alunos no circuito, conecte o cabo serial no PC e no circuito. Aparecerá a seguinte tela: Conectando ao PC Figura 3.3 Cabo conectado OBS: Note que quando o cabo serial está conectado, você pode apertar qualquer tecla do teclado e o botão “Desliga” que não fará efeito algum. Agora abra o Software DiarioClasse e conecte o PC ao circuito (leia o manual do Software DiarioClasse). Quando isto for feito, aparecerá a seguinte tela: PC conectado! 8051 <------> PC Figura 3.4 Mensagem de conectado ao PC No software, clique em Enviar e os dados começarão a serem recebidos pelo hardware. Aparecerá a seguinte mensagem no display: Recebendo... 8051 <------- PC Figura 3.5 Recebendo dados Quando todos os dados forem recebidos, aparecerá no display: Fim de Recepcao! 8051 <------> PC Figura 3.6 Recepção de dados terminada 31 Agora o cabo serial pode ser desconectado do circuito. O display voltará à tela inicial. 3.4 O relógio do circuito 3.4.1 Configurando a data e a hora Quando o circuito estiver conectado ao PC, veja o manual do Software DiarioClasse. 3.4.2 Verificando a data e hora: Sempre que possível, verifique se o relógio do circuito está devidamente configurado. Para isto, basta ligar o circuito e pressionar a tecla 3. Quando apertar a tecla 3, aparecerá todos os dados relacionados à data e a hora atuais por alguns segundos, após isso, o display voltará à sua tela inicial. ATENÇÃO: Nunca desligue o interruptor do circuito quando o display estiver mostrando a data e a hora atuais, pois se for desligado, o relógio do circuito será desconfigurado! Se for preciso desligar o circuito quando estiver mostrando a data e a hora, aperte o botão “Desligar” antes de desligar o interruptor. 3.5 O circuito em sala de aula Antes de ir à sala de aula, verifique se o relógio do circuito está devidamente configurado. Após isso, desligue o circuito de forma conveniente e vá para a sala de aula. Quando entrar em sala de aula, aperte a tecla ∗ e veja a figura abaixo. Matricula _ Figura 3.7 Pronto para digitar a matrícula Quando a tecla * foi apertada, o circuito armazenou na EEprom a data e a hora em que a aula começou. A partir daí, os alunos poderão digitar a sua matrícula (de 6 32 dígitos) e a tecla # para confirmar; se o aluno errar alguma tecla, basta apertar a tecla ∗ para cancelar e digitar novamente a sua matrícula. Quando a presença for confirmada, aparecerão na tela a confirmação da presença e o nome do aluno, como por exemplo: Presença OK! Carlos Renato B. Figura 3.8 O nome do aluno aparece no LCD Se a matrícula do aluno não for encontrada, como por exemplo a matrícula 777777, aparecerá a seguinte tela: Matricula 777777 Não Encontrado! Figura 3.9 O aluno não está matriculado Se o aluno teclar mais de 6 teclas, aparecerá a seguinte tela: Digite apenas 6 numeros Figura 3.10 Mensagem quando mais de 6 números são digitados Se o aluno teclar menos de 6 teclas, aparecerá a seguinte tela: Digite 6 numeros Para matricula Figura 3.11 Quando menos de 6 dígitos são teclados 3.6 Verificando o percentual da EEprom usado Para evitar que se perca dados ou que o circuito seja conectado ao computador sem necessidade, o circuito pode mostrar o percentual da EEprom usada. Quando o display estiver mostrando a tela inicial, aperte a tecla 1. Aparecerá o porcentual aproximado do total da EEprom usada, como no exemplo: 33 Total RAM usado: 25% Figura 3.12 Percentual de dados armazenados na RAM 3.7 Descarregando os dados da RAM no PC Conecte o circuito ao PC e veja se no software o botão Receber está habilitado. Se estiver, clique nele e se iniciará a descarga de dados da EEprom para o PC. No display, aparecerá a seguinte mensagem: Transmitindo... 8051 ------- >PC Figura 3.13 Enviando dados para o PC Quando terminado, os dados de freqüência dos alunos serão apagados da EEprom, porém, os dados de matrícula, código e nome dos alunos permanecerão intactos. O display mostrará a seguinte tela: Fim Transmissao! 8051 <------> PC Figura 3.14 Fim do envio de dados 3.8 A Expansão de memória O hardware pode expandir dos 8 KB iniciais para até 56 KB, com o slot que existe na placa. Atualmente, apenas 8 KB são suficientes para registrar as freqüências de todos os alunos de uma turma. Porém, futuramente, se o sistema se mostrar eficiente e for preciso aumentar o número de alunos, com apenas alguns implementos nos softwares do 8051 e do PC, o circuito poderá informar ao software DiarioClasse quantos KB de RAM estarão disponíveis, evitando que o DiarioClasse envie mais dados do que o suportado pela EEprom do circuito. 34 3.9 Revisão geral do capítulo O circuito do projeto foi devidamente implementado, de forma a ter suporte para futuros implementos de software e de hardware, aproveitando totalmente a placa do circuito. Futuramente, se for necessário, o hardware poderá suportar: – Expansão de RAM ou periféricos mapeados por endereçamento; – Alerta sonoro quando a presença do aluno for efetuada; – Capacidade de detecção de expansão de RAM ou Hardware, informando ao software se há mais hardware mapeado por endereço. 35 CAPITULO IV 4 O Sistema Mínimo 4.1 Considerações O sistema mínimo é a parte central do Projeto e é responsável pela execução das principais funções disponíveis. O sistema mínimo é composto por um microcontrolador 8051 da família Intel, de uma memória EEprom, além de conter um decodificador 74HC138 que faz aumentar a possibilidade de se usar mais periféricos de 8 bits, podendo ser acionados até 8 periféricos de 8 bits pelo microcontrolador. Assim há um mapa de memória a ser seguido, tem-se então o endereço 0000h a FFFFh para endereçamento, e portanto uma variação de 1FFFh para a seleção de cada periférico desejado. 4.2 O Microcontrolador O microcontrolador AT89C52 é de baixo consumo, alto desempenho, tecnologia CMOS8-bits com bytes de Flash e 2K bytes de EEPROM. O dispositivo é fabricado com memória não volátil e é compatível com o padrão 80C51, tanto no conjunto de instruções quanto nos pinos de saída. O chip permite também a gravação do programa seja feita através de uma interface serial, possibilitando a gravação do programa sem a necessidade de retirar o microcontrolador da placa de circuito impresso. O AT89C52 provê as seguintes características padrões: 8K bytes de memória Flash, 2 KB de EEPROM, 256 Bytes de RAM, 32 pinos de I/O, timer watchdog programável, dois ponteiros de dados, três contadores/temporizadores de 16-bits,etc. O modo inativo trava a CPU enquanto permite a RAM, timer/counters, porta serial, e sistema de interrupção continuarem funcionando. No modo power-down os conteúdos de RAM são salvos e o oscilador é travado, assim todas as outras funções do chip até a próxima interrupção ou reset. 36 4.2.1 Características – Compatível com a família 8051 de microprocessadores; – 8 KB de memória flash; – Interface serial (SPI) para carregar o programa; – 100.000 ciclos de escreve/apaga; – Variação de 4V à 6V na tensão de alimentação; – 256 x 8 bits de memória RAM interna; – 32 pinos de I/O programáveis; – Três Timers/Counters 16 bits; – Nove possibilidades de interrupção; – Unidade supervisora programável (Wachdog). Neste projeto foram usados dois modos de comunicação serial do 8051, onde cada modo de configuração serial é utilizado para a comunicação com elementos diferentes, em tempos distintos, separados fisicamente pelo chaveador CI 4066. Modo 0: Síncrono – usado para o 8051 se comunicar com o RTC; Modo 1: Assíncrono de 8 bits, com baud-rate de 19200 – usado para o 8051 se comunicar com o PC. As portas P0 e P2 foram utilizadas no mapeamento por endereçamento. A porta P1 foi utilizada como entrada de dados, sendo que os seus pinos foram utilizados da seguinte forma: – P1.0 ao P1.3: Leitura do teclado; – P1.4 ao P1.6: Poderá ser utilizado na placa de expansão de RAM; – P1.7: Bit que desliga o display LCD e coloca o microcontrolador no modo PowerDown. Na porta P3, todos os pinos foram utilizados: – P3.0 e P3.1: Comunicação serial; – P3.2: Monitora o conector DB9 da serial; – P3.3: Habilita a comunicação com o RTC, quando a serial está em modo 0; – P3.4: Responsável por conectar a serial no RTC ou no DB9; – P3.5: Bit que será responsável pelo alerta sonoro; – P3.6 e P3.7: WR e RD, usado no mapeamento por endereçamento. 37 4.2.2 Comunicação com o RTC A comunicação com o RTC consiste em ler e escrever (configurar) a data e hora no RTC. O manuseio deste CI está detalhado no Capítulo III. 4.2.3 Comunicação com o PC A comunicação com o PC consiste em: descarregar e recuperar dados armazenados na EEPROM (CI 28C64B). configurar a data e hora no RTC. 4.3 EEPROM 4.3.1 Características Funcionais – Leitura de acesso rápido (150 ηs); – Operação automática de leitura de página; – 64 bytes para endereçamento e dados; – Ciclos de escrita rápida; – Baixo consumo de corrente; – Proteção de hardware e software. 4.3.2 Descrição O AT28C64B é uma memória elétrico-apagável e programável de alta performance (EEPROM). Seus 64 KB de memória são organizados em 8.192 palavras de 8 bits. Fabricado com alta tecnologia CMOS, os tempos de acesso são de 150 ηs, com dissipação de apenas 220 mW. A corrente no modo de espera do CMOS é de menos de 100µA. O AT28C64B é uma RAM estática para leitura ou escrita, sem a necessidade de componentes externos. O dispositivo tem um registo de 64 Bytes para permitir simultaneamente a escrita de até 64 Bytes. Durante o ciclo da escrita, os endereços de 1 a 64 Bytes dos dados são trancados internamente, livrando o barramento de endereçamento de dados para outras operações. Depois da iniciação de um ciclo da 38 escrita, o dispositivo escreverá automaticamente os dados trancados usando um temporizador interno de controle. A extremidade de um ciclo da escrita pode ser detectada pela seleção de DADOS de I/O7. Uma vez que a extremidade de um ciclo da escrita foi detectada, um novo acesso para leitura ou escrita pode começar. Figura 4.1 Configurações dos pinos da EEprom 4.4 Decodificador 4.4.1 Descrição Geral O decodificador MM74HC138 é um chip de tecnologia CMOS e é bem adequado à decodificação de endereço de memória. O chip apresenta alta imunidade a ruídos e um baixo consumo de potência. O 74HC138 é um decodificador de 3 para 8, ou seja, ele possui três entradas A, B, e C que acionam uma das oito saídas, dependendo da combinação de níveis altos e baixos nos pinos A, B e C. 4.4.2 Características – Atraso de propagação típica de 20 ηs; – Faixa admissível de tensão de alimentação de 2V a 6V; – Baixa corrente 80µA; 39 – Fanout de 10 cargas de LS-TTL Figura 4.2 Configurações de Conexão do 74138 40 4.5 Sistema com Mapeamento de Memória O sistema mínimo com o decodificador 74HC138 faz com que a memória seja dividida em 8 partes diferentes, cada parte sendo responsável por acionar um dispositivo diferente. Os endereços de memória disponíveis vão de 0000h a FFFFh. Assim para podermos usar qualquer um dos periféricos devemos endereçar corretamente o módulo desejado dando uma instrução MOVX e utilizando o registrador de 16 bits (DPTR), para o endereçamento. Os três pinos de seleção do decodificador (A, B e C) são ligados respectivamente nos pinos P2.5, P2.6 e P2.7 do microprocessador (que são os pinos de endereçamento de memória de mais alta ordem, de endereços A13, A14 e A15). Como o microcontrolador vê um periférico como uma posição de memória é necessário utilizarmos a instrução MOVX (neste caso, no endereço XXXXh). Cada periférico tem um endereço específico e o periférico pode somente ser do tipo de entrada ou saída de dados. O decodificador e implementado com lógica fixa. Endereços utilizados: 0000h a 1FFFh – EEprom 2000h a 3FFFh – Expansão 4000h a 5FFFh – Expansão 6000h a 7FFFh – Expansão 8000h a 9FFFh – Expansão A000h a DFFFh – Expansão E000h a FFFFh – LCD 41 Figura 4.3 Esquema do mapeamento de memória 42 CAPITULO V 5 Periféricos 5.1 O display LCD 5.1.1 Introdução Os módulos LCD são interfaces de saída muito útil em sistemas microprocessados. Estes módulos podem ser gráficos e a caracteres. Os módulos LCD gráficos são encontrados com resoluções de 122x32, 128x64, 240x64 e 240x128 dots pixel, e geralmente estão disponíveis com 20 pinos para conexão. Tabela 5.1 Módulos LCD disponíveis Os LCD comuns (tipo caractere) são especificados em número de linhas por colunas e são encontrados nas configurações previstas na Tabela 5.1 Os módulos podem ser encontrados com LED backlight (com uma iluminação de fundo) para facilitar as leituras durante a noite. Neste caso, a alimentação deste led faz-se normalmente pelos pinos 15 e 16 para os módulos comuns e 19 e 20 para os módulos gráficos, sendo os pinos 15 e 19 para 43 ligação ao anodo e os pinos 16 e 20 para o catodo. A corrente de alimentação deste led varia de 100 a 200mA, dependendo do modelo. Estes módulos utilizam um controlador próprio, permitindo sua interligação com outras placas através de seus pinos, onde deve ser alimentado o módulo e interligado o barramento de dados e controle do módulo com a placa do usuário. Naturalmente que além de alimentar e conectar os pinos do módulo com a placa do usuário deverá haver um protocolo de comunicação entre as partes, que envolve o envio de bytes de instruções e bytes de dados pelo sistema do usuário. Assim como em um rádio relógio todo módulo LCD permite um ajuste na intensidade da luz emitida ou ajuste de contraste, isto é possível variando-se a tensão no pino 3. A Figura mostra um circuito típico e recomendado pela maioria dos fabricantes para efetuar este ajuste. Alguns fabricantes recomendam o uso de um resistor de 4K7 em série com o potenciômetro de 10K. A Tabela 5.2 descreve cada pino do módulo ou do display para conexão deste a outras placas: Tabela 5.2 Pinagem dos módulos LCD 44 Figura 5.1 Alimentação do LCD 5.1.2 Interface com CPU Os módulos LCD são projetados para conectar-se com a maioria das CPU’s disponíveis no mercado, bastando para isso que esta CPU atenda as temporizações de leitura e escrita de instruções e dados, fornecido pelo fabricante do módulo. A Figura 5.1 mostra um exemplo de diagrama de tempos típico requeridos para operação de escrita no módulo LCD, estes tempos variam em função do clock da CPU do usuário. Figura 5.2 (A) Escrita no LCD (B) Ciclo de escrita da CPU 8051 A Tabela 5.3 a seguir mostra a relação entre a freqüência da CPU e a temporização de leitura/escrita da maioria dos módulos LCD. 45 Em geral, pode-se conectar o barramento de dados da CPU ao barramento do módulo, mapeando-o convenientemente na placa de usuário, efetuando assim, uma operação normal de leitura/escrita sem mais problemas. Tabela 5.3 Relação de Clock da CPU x temporização do módulo LCD Ocorre que o módulo LCD quando alimentado necessita de algumas instruções de inicialização que identificará qual a forma de transmissão de dados que será estabelecida entre a CPU e o módulo. Tabela 5.4 Endereçamento do módulo LCD 5.1.3 Inicialização do módulo LCD Toda vez que se alimenta o módulo LCD deve ser executado o procedimento de inicialização, que consiste no envio de uma seqüência de instruções para configurar o modo de operação para execução de um dado programa de interfaceamento. Em muitos display este procedimento ocorre automaticamente, dentro de condições específicas que envolve temporizações mínimas referente a transição do nível lógico 0 para 1, ao ligar a fonte. Em caso de dúvidas, recomenda-se o envio destas instruções após o reset do sistema. Inicialização para sistemas 8 bits de dados (5 instruções). 46 Entre as duas primeiras instruções recomenda-se um delay de 15 ms. As demais instruções podem ser escritas após checar o Busy Flag. Tabela 5.5 Inicialização para sistemas de 8 bits de dados 5.1.4 Roteiro para programação A seguir passaremos a descrever um resumo dos procedimentos para utilização de um módulo ou display LCD: 1. Ao energizar o módulo ajuste o potenciômetro de controle do brilho ou contraste até obter a visualização da matriciação na primeira linha para módulo de duas linhas ou até a matriciação de meia linha para módulos de uma linha. 2. Alguns módulos de uma linha só funcionam com a instrução 38 ao invés de 30, conforme instruções de inicialização. 3. O sinal de Enable (pino 6) deverá ser gerado conforme a temporização mostrada na Figura 2. Os códigos de dados ou de instruções só serão processados pelo processador do módulo após a descida do sinal do Enable. 4. Para ajustar a velocidade de comunicação entre a CPU do usuário e o módulo LCD existem duas possibilidades: § Intercalar uma rotina de atraso de aproximadamente 15 ms entre as instruções. § Fazer a leitura do Busy Flag antes do envio de cada instrução e só enviar quando o mesmo for 0. Neste caso, a única exceção será durante a inicialização. 5. Durante a inicialização enviar a seqüência correta das instruções de inicialização. 47 6. Para programar caracteres na CGRAM, faça inicialmente o endereçamento da mesma. 7. Após a escrita de dados na CGRAM envie a instrução 01, para posicionar o cursor. 8. Para escrever os caracteres especiais previamente gravados na CGRAM, utilize os códigos de 00 até 07 correspondente aos endereços bases de 40, 48 até 78 em hexa. 9. Comandos úteis: Tabela 5.6 Comandos úteis do LCD 48 Obs: Após o endereçamento da CGRAM, o cursor se desloca para a primeira posição da segunda linha (ou metade), portanto é recomendado enviar a instrução 01 ou “limpa display e cursor home”. 5.2 O Teclado Para acionar o teclado utilizou-se o chip MM74922,este codificador fornece toda a lógica necessária para codificar teclados de até 32 teclas. A varredura do teclado pode ser executada por clock externo ou pelo capacitor externo ligado ao codificador. Estes codificadores têm também dispositivos internos que permitem interruptores com até 50kΩ serem usadas. Não é necessário o uso de diodos supressores de surto no arranjo de chaves para eliminar ruídos. Normalmente os pinos de saída desse chip permanecem em estado baixo, somente indo para o estado alto quando alguma tecla for pressionada, retornando novamente a nível baixo assim que a chave é liberada, mesmo se outra chave é pressionada. Os pinos de saídas retornarão ao nível alto para indicar a aceitação da nova tecla após período normal de saída. Um registro interno memoriza a última chave pressionada outra tecla. 5.2.1 Características – Resistência máxima suportável do teclado: 50 KΩ; – Chaves com memória temporária; – Eliminação ruído da chave com simples capacitor; – Registrador da última chave pressionada; – Saída de tri-state; – Ampla faixa de tensão: 3V a 15V; – Baixo consumo. 49 Figura 5.3 Diagrama de conexão 5.2.2 Teoria da Operação O codificador do teclado MM74C922 / MM74C923 implementa toda lógica necessária para a interface de 16 ou 32 teclas para um sistema digital. O codificador converterá uma tecla pressionada para 4 bits no caso 16 teclas ou para 5 bits no caso de 32 teclas. O projeto pode ser controlado pela taxa de varredura do teclado e pelo período de supressão da chave pela alteração do valor do capacitor, Cose. O codificador do teclado deverá ser conectado a matriz do teclado, que nesse caso é um teclado de 4 linhas por colunas. Quando nenhuma tecla é apertada, as linhas de caracteres de entrada são colocadas em nível alto e assim os pinos de saída ficam em nível baixo. Estas saídas são drenos abertos e são baixadas então para 25% do tempo e caso contrário desliga. A freqüência de varredura do teclado é controlada pelo oscilador de entrada, que consiste de um oscilador disparador Schmitt, um de 2 bits e um decodificador 2 – 4 bit. Quando uma tecla é apertada, a chave 0 por exemplo, nada acontecerá quando a entrada X1 estiver desligada, desde que Y1 permaneça alto. Quando a coluna X1 é varrida, X1 tornará baixo. Isto incapacita o contador e mantém X1 baixo. Y1 também irá a nível baixo iniciando a cronometragem do circuito de varredura e o bloqueio da entrada de Y.O código para ser de entrada é a combinação do valor do contador desligado e da decodificação da entrada Y. Uma vez que o intervalo de contato 50 contínuo, os dados são permanentes, e a avaliação dos dados de saída irão para o nível alto. Se durante o pressionamento da chave, a varredura da chave e a entrada Y1 retornarão ao nível alto. A chave pode saltar várias vezes , mas assim que a tecla abaixe para um período curto o fechamento é assumido como válido e os dados são armazenados. Uma chave também pode saltar quando é despressionada. Para assegurar que o codificador não reconheça este salto como outro fechamento de chave, o circuito de contato contínuo deve permanecer inativo por um curto período de tempo antes que outro fechamento seja reconhecido. Figura 5.4 Esquema de ligação do chip ao teclado 5.3 RTC – Chip de Armazenamento de tempo 5.3.1 Características – Contador de tempo (RTC) conta segundos, minutos e horas, dia do mês, dia da semana, e ano com compensação de ano bissexto válido até 2100. – 31 bytes de RAM não volátil para armazenamento de dados. – Serial I/O para o uso do mínimo de pinos. 51 – Operação de 2,0 V a 5,5 V. – Usa menos que 300 ηA a 2,0 V. – Modo de estouro para leitura/escrita sucessivos endereçados em clock/RAM. – 8 pinos DIP ou opcionalmente 8 pinos SOICs para escala de superfície. – Interface simples com 3 fios. – TTL compatível (Vcc=5V). – Opcional escala para temperatura industrial: -40°C a +85°C. – Compatível com o DS1202. Figura 5.5 Esquema dos pinos do RTC 5.3.2 Descrição O Chip de Armazenamento de Tempo DS1302 possui um RTC/calendário e 31 bytes de RAM estática. Comunica-se com um microprocessador através de uma serial simples. O RTC/calendário fornece segundos, minutos, horas, dia, data, mês, e informação do ano. A extremidade da data do mês é ajustada automaticamente para meses com menos de 31 dias, incluindo correções para ano bissexto. O clock opera no formato de 24 ou em 12 horas, com um indicador de AM/PM. Conectar o DS1302 a um microprocessador é simples usando uma comunicação de série síncrona. Somente três fios são requeridos para comunicar-se com o clock/RAM: 1° RST (restauração), 2° I/O (linha de dados), e 3° SCLK (clock de série). Os dados podem ser transferidos do byte de clock/RAM 1 em um momento ou em um estouro de até 31 bytes. O DS1302 é projetado operar sobre força muito baixa e reter dados e informação do clock em menos de 1 µW. O DS1302 é o sucessor do DS1202. Além das funções de guardar tempo básicas do DS1202, o DS1302 tem as características adicionais dos pinos de dupla-força para fontes de alimentação preliminares e alternativas, o carregador programável para VCC1, e sete bytes adicionais da memória scratchpad. 52 5.3.3 Circuito de operação típico Figura 5.6 Esquema de ligação serial do RTC 5.3.3.1 Operação Os elementos principais do armazenador de tempo de série (isto é, registro de deslocamento, lógica de controle, oscilador, RTC, e RAM) são mostrados na Figura 5.7. 53 Figura 5.7 Elementos principais do RTC 5.3.3.2 Descrições do Sinal VCC1-VCC1 fornece a operação de baixa carga na única fonte e em sistemas operados com bateria assim como o apoio da bateria de baixa carga. Nos sistemas usando o carregador de gotejamento, a fonte de energia recarregável é conectada a este pino. VCC2- VCC2 é o pino preliminar da fonte de alimentação na configuração fornecimento duplo. VCC1 é conectado a uma fonte backup para manter a hora e a data na ausência da fonte preliminar. O DS1302 irá operar com a maior tensão VCC1 ou VCC2. Quando VCC2 é maior do que VCC1 + 0.2V, o DS1302 usará VCC2. Quando VCC2 é menos do que VCC1, o DS1302 usará VCC1. SCLK (Entrada de clock serial)- SCLK é usado para sincronizar o movimento de dados na interface serial. Este pino tem um resistor 40kΩ de pull-down interno. I/O (Input/Output de Dados)- O pino de I/O é o pino bidirecional dos dados para a interface de 3 fios. Este pino tem um resistor de 40kΩ de pull-down interno. 54 RST (Reset) – O reset pode ser usado na leitura ou escrita. Este pino tem um resistor de 40kΩ de pull-down interno. X1, X2- Conexões para um cristal padrão de quartzo 32.768kHz. O oscilador interno é projetado para a operação com um cristal que tem uma capacitância de 6pF. O DS1302 pode também ser dirigido por um oscilador 32.768kHz externo. Nesta configuração, o pino X1 é conectado ao sinal externo do oscilador e o pino X2 é flutuante. 5.3.3.3 Exatidão do Clock A exatidão do clock depende da exatidão do cristal, da exatidão do fósforo entre a carga capacitiva do circuito do oscilador e da carga capacitiva para que o cristal foi preparado. O erro adicional será adicionado pela tração de freqüência de cristal causada por mudanças de temperatura. O ruído de circuito externo acoplado no circuito do oscilador pode resultar em pulsos que atuam rapidamente. 5.3.3.4 Comando Byte O comando byte é mostrado na figura 2. Cada dado é transferido inicialmente por um comando byte. O MSB (Bit 7) deve ser o valor lógico 1. Se este for 0, o DS1302 estará desabilitado. São 6 bits específicos de dados clock\calendário, se for o nível lógico 0 ou RAM se for o nível lógico 1. Bits 1 dos 5 especificam os registradores usados para entrada ou saída, e o LSB (bit 0) especifica uma operação de escrita (entrada), se for o valor lógico 0 ou operação de leitura se for o valor lógico 1. 5.3.3.5 Endereçamento\Comando Byte Figura 5.8 Byte de endereçamento do RTC 55 5.3.3.6 Controle de Reset e Clock Todas as transferências de dados são iniciados dirigindo a entrada alta RST. A entrada de RST tem duas funções. Primeiramente, RST gira sobre a lógica de controle, que permite o acesso ao registro de deslocamento para a seqüência de endereçamento/comando. Em segundo, o sinal de RST fornece um método de terminar o único byte ou transferência de dados múltipla do byte. Um ciclo de pulso de disparo é uma seqüência de uma borda de descida seguida por uma borda de subida do clock. Para entradas de dados, os dados devem ser válidos durante a borda de subida do pulso do clock, e os bits de dados saem na borda de descida do clock. Se a entrada de RST for baixa, toda a transferência de dados terminar, e o pino de I/O vai a um estado de alta impedância. Transferência de dados é ilustrada na figura 3. Na ligação inicial, RST deve ter o valor lógico 0 até VCC>2,0V. Também SCLK deve ter o valor lógico 0 quando RST é levado para o valor lógico 1. 5.3.3.7 Entrada de Dados Depois de oito ciclos de SCLK que a entrada de um comando de escrita, um byte de entrada de dados na borda de subida dos oito ciclos seguintes de SCLK. Os ciclos adicionais de SCLK são ignorados se ocorrerem inadvertidamente. Os dados irão começar com entradas de bits 0. 5.3.3.8 Saída de Dados Depois dos oito ciclos de SCLK que a entrada de um byte do comando lido, um byte de saída de dados na borda de descida dos oito ciclos seguintes de SCLK. Note que o primeiro bit de dados a ser transmitido ocorre na primeira borda de descida depois que o último bit do byte do comando é escrito. Os ciclos adicionais de SCLK retransmitirão os bytes de dados se ocorrerem inadvertidamente pelo tempo que RST permanece elevado. Esta operação permite a leitura contínua na modalidade de estouro. Também, o pino de I/O tri-stated é indicado em cima de cada borda de subida de SCLK. Dados de saída são iniciados com bit 0. 56 5.3.3.9 Modo de estouro O modo de estouro pode ser especificado para o clock/calendário ou os registros da RAM dirigindo-se ao decimal da posição 31 (bits de 1 a 5 de endereçamento/comando = lógica 1). Como antes, o bit 6 especifica o clock ou a RAM e bits 0 especificam leitura ou escrita. Não há nenhuma capacidade do armazenamento de dados de nas posições 9 a 31 nos registros de Clock/Calendário ou a posição 31 na RAM registra. Lê ou escreve no começo da modalidade de estouro com bit 0 do endereço 0. Ao escrever aos registros de pulso de disparo na modalidade de estouro, os primeiros oito registros devem ser escritos para que os dados sejam transferidos. Entretanto, ao escrever à RAM na modalidade de estouro não é necessário escrever todos os 31 bytes para os dados da transferência. Cada byte que é escrito será transferido para RAM independentemente se todos os 31 bytes estão escritos ou não. 5.3.3.10 Clock\Calendário O clock/calendário é contido em sete registros de escrita\leitura como mostrado em figura 4. Os dados contidos nos registros do clock/calendário estão no formato do decimal codificado binário (BCD). 5.3.3.11 Flag de parada do Clock O bit 7 de registro dos segundos é definido como a flag da parada do clock. Quando este bit é ajustado à lógica 1, o oscilador do clock está parado e o DS1302 é colocado em uma modalidade à espera carga baixa no modo de espera com uma corrente de dreno menor que 100 ηA. Quando este bits é escrito à lógica 0, o pulso de disparo começará. O fonte estado inicial não é definida. 5.3.3.12 Modo AM-PM\12-24 O bit 7, registrador de horas é definido como modo 12 ou 24 horas. Quando alto, o modo 12 horas é selecionado. No modo 12 horas, o bit 5 é o bit de AM/PM bit com lógica alta para PM. No modo de 24 horas, o bit 5 é o segundo, bit 10-hour (horas 2023). 57 5.3.3.13 Bit de Proteção da Escrita O bit 7 é o bit de controle de registro e de proteção da escrita . Os primeiros sete bits (bits 0 a 6) são forçados a 0, e serão lidos sempre 0. Antes da operação de escrita o clock ou a RAM, o bit 7 deve ser 0. Quando alto, a escrita protege o bit, impede uma operação de escrita e qualquer outro registro. O estado da fonte inicial não é definido. Consequentemente o bit do WP deve ser limpo antes de tentar escrever ao dispositivo. 5.3.3.14 Registro de Carga Lenta Este registro controla as características de carga lenta do DS1302. O diagrama esquemático simplificado de Figura 5.7 mostra os componentes básicos do carregador lento. As cargas lentas selecionadas (TCS) (bits 4-7) controlam a seleção do carregador lento. A fim de impedir acidentes, somente um teste padrão de 1010 permitirá o carregador lento. Todos testes padrões restantes incapacitarão o carregador lento. Os recursos do DS1302 desabilitam carregador lento. Os bits de seleção de diodos (DS) (bits 2-3) selecionam se um diodo ou dois diodos estão conectados entre VCC2 e VCC1. Se o DS for 01, um diodo está selecionado ou se o DS for 10, dois diodos são selecionados. Se o DS for 00 ou 11, o carregador lento está incapacitado independentemente do TCS. Os bits de RS (bits 0-1) selecionam o resistor que é conectado entre VCC2 e VCC1. O resistor selecionado pelos bits de resistor selecionados (RS) é como segue: Tabela 5.7 Bits de configuração do registrador de Carga Lenta A seleção do diodo e do resistor é determinada pelo usuário de acordo com a corrente máxima desejada para a bateria ou fonte. A corrente máxima de carregamento pode ser calculada como ilustrada no seguinte exemplo. Suponha que uma fonte de alimentação do sistema de 5V está aplicada a VCC2 e uma fonte está conectado a 58 VCC1. Também suponha que o carregador lento permitiu diodo e resistor R1 entre VCC2 e VCC1. A corrente máxima IMAX, consequentemente, seria calculada como segue: IMAX = (5.0V - diodo drop)/R1 ≈ (5.0V - 0.7V)/2kΩ ≈ 2.2mA. Como as cargas da fonte, a queda de tensão entre VCC1 e VCC2 diminuirá e, consequentemente, a corrente de carga diminuirá. 5.3.3.15 Modo de Estouro do Clock\Calendário O byte do comando de clock/calendário especifica a operação do modo de estouro. Nesta modalidade os primeiros oito registros de clock/calendário podem consecutivamente ser lidos ou escrito a começar com bit 0 do endereço 0. Se o bit de proteção da escrita estiver alto quando uma modalidade de estouro da escrita clock/calendário está especificada, nenhuma transferência de dados ocorrer a alguns dos oito registros de clock/calendário (esta inclui o registro de controle). O carregador lento não é acessível na modalidade de estouro. No começo de um estouro clock lido, o tempo atual é transferido a um segundo jogo dos registros. A informação do tempo está lida destes registros secundários, quando o clock puder continuar a funcionar. Isto elimina a necessidade de reler os registros em caso de uma atualização dos registros principais lidos. 5.3.3.16 RAM A RAM estática é de 31 x 8 bytes endereçados consecutivamente no espaço de endereço da RAM. 5.3.3.17 Modo de Estouro da RAM O byte do comando da RAM especifica a operação do modo de estouro. Nesta modalidade, os 31 registros da RAM podem consecutivamente ser lidos ou escrito começando com bits 0 do endereço 0. 59 Figura 5.9 A transferência de dados do RTC 5.3.4 Resumo dos Registros O resumo de registro é mostrado na figura abaixo: Figura 5.10 Os registradores do RTC 60 5.3.5 Aplicação ao 8051 Foram obtidos resultados satisfatórios, foi realizada a comunicação entre o DS1302 e o microcontrolador depois de vários testes, pois houve um problema de compatibilidade entre eles. Notamos que o bit de clock do RTC permanece em nível baixo quando não existe a comunicação, enquanto esse mesmo bit no microcontrolador (para o pino TXD) permanece em nível alto. Portanto houve a necessidade de usar um inversor na saída de clock do microcontrolador (TXD) para solucionar o problema. 5.4 O chip Max 232 5.4.1 Descrição Geral A família MAX220/MAX249 da linha drivers/receivers é usada para todas as relações de comunicações EIA/TIA-23E e V.28/V.24, particularmente aplicações onde ±12V não está disponível. Estes componentes são especialmente úteis em sistemas alimentados por baterias, desde que seu modo de baixa carga, seja programada para potência menor que 5µW. O uso dos MAX225, MAX233, MAX235, e os MAX245/MAX246/MAX247 nenhum componente externo e recomendado para as aplicações onde o espaço da placa de circuito impressa é crítico. – O conector de nove pinos é utilizado na comunicação serial. Tal como os outros microcontroladores da família 8051, o 89C52 possui um circuito UART interno que pode ser ligado através de um integrado conversor de amplitudes (MAX 232) à porta serial (COM) de um computador PC. – Tal como é usual nas comunicações seriais , utiliza-se um circuito integrado MAX232 para executar a adaptação necessária da amplitude dos sinais. – Os sinais gerados na porta serial do PC possuem uma amplitude teórica RS232 de ±12 volts, embora em muitos computadores seja apenas da ordem de ±10 volts, ou mesmo menos, como acontece em muitos computadores portáteis. O integrado MAX232 converte para 0 volts/+5 volts a amplitude dos sinais das linhas dos pinos 11 e 12 deste CI. 61 Figura 5.11 Esquema de funcionamento do MAX232 5.5 O chip 4066 5.5.1 Descrição Geral O 74HC/HCT4066 são de alta velocidade e compatíveis com os 4066 da série 4000. O 74HC/HCT4066 possui quatro interruptores analógicos independentes. Cada interruptor possui dois terminais de entrada/saída e um interruptor habilitável ativo alto. Tabela 5.8 Descrição dos pinos do 4066 62 Figura 5.12 Esquema de funcionamento do 4066 Este CI tem como objetivo alternar a conexão serial entre o PC - 8051, e entre o RTC-8051, pois no 8051 só possui um canal serial. 63 Capítulo VI 6 O armazenamento de dados na EEprom 6.1 Introdução A Figura 6.1 abaixo mostra como a EEprom foi dividida: Figura 6.1 A divisão da EEprom em pilhas Conforme, a figura, a memória EEprom foi dividida em três partes, são elas: – Pilha “Controle”; – A posição do último byte da Pilha “ALUNOS”; – Pilha “Frequencia”. Cada parte será detalhada a seguir: 64 6.1.1 A Pilha Controle Figura 6.2 A Pilha CONTROLE A pilha “Controle” é formada por 5 bytes separados da seguinte forma: – 2 bytes que armazenam a parte Low e High da Posição Final da pilha “ALUNOS”; – 2 bytes que armazenam a parte Low e High da Posição Final da pilha “Frequencias”; – 1 byte que armazena a informação que indica se a pilha está vazia ou cheia. Figura 6.3 Detalhe dos Ponteiros das pilhas 65 A Figura 6.3 acima mostra que os ponteiros que identificam o último byte das pilhas “ALUNOS” e “Frequencias” ficam armazenados na Pilha “Controle” 6.1.2 A Pilha ALUNOS Figura 6.4 A pilha ALUNOS Conforme visto na Figura 6.4, a pilha “ALUNOS” é composta por unidades. Os dados de cada aluno são guardados nessas unidades. Cada unidade, chamada de Unidade “ALUNO”, ocupa 24 bytes da EEProm, e é constituída pelo campo “Nome”, um campo “Codigo” e um campo “Matricula”. O campo “Nome” guarda o nome do aluno, que é mostrado no display LCD. Este campo ocupa 16 bytes da EEprom. – “Codigo” → guarda o código do aluno. Este campo ocupa 2 bytes da EEProm. – “Matricula” → guarda a matrícula do aluno. Este campo ocupa 6 bytes da EEProm. 66 6.1.3 A Pilha “Frequencia” Figura 6.5 A Pilha FREQUENCIAS Esta pilha armazena os acessos dos alunos em sala de aula. Ela é formada por unidades chamadas Unidades “Diarias”. Cada Unidade “Diaria” contém 3 campos, são eles: – IniUnidade → Define o início da Unidade “Diaria”. Ocupa apenas um byte, com o símbolo #14 da tabela ASCII. – Data/Hora → Armazena os dados do momento em que se começou a registrar as frequências; são 2 bytes para minuto, 2 bytes para hora, 2 bytes para dia do mês, 2 bytes para o mês, 1 byte para o dia da semana e 2 bytes para o ano. Este campo ocupa o total de 11 bytes. – Codigos → Armazena os códigos de cada aluno que registra a sua presença no circuito. O tamanho deste campo depende apenas do número de alunos que vieram no dia (Por isso é necessário um campo IniUnidade para identificar cada Unidade “Diaria”). 67 6.2 Uma visão geral da utilização da EEprom Quando o circuito é conectado ao PC, o circuito lê na pilha “Controle” o byte que informa se a RAM está cheia ou vazia. Quando o professor descarrega os dados dos alunos na EEprom, a pilha ALUNOS é criada, onde cada aluno ocupa uma “Unidade Aluno”. Quando o envio de dados para a EEprom é terminada, fica armazenada na Pilha “Controle” a posição final da Pilha “ALUNO”. Após isso, o ponteiro da posição final da Pilha “Frequencia” recebe o mesmo valor da Pilha “ALUNO” (pois nenhum dado de freqüência ainda não foi registrado). Ainda na Pilha “Controle”, ficará armazenado que não há dados a serem transmitidos, assim, se alguém conectar novamente o PC ao circuito, verá que o botão Receber do software estará desativado. Quando o professor inicia o registro de alunos, será criado na EEprom uma Unidade “Diaria”, e na Pilha “Controle”, o byte que registra se há dados na EEprom informará que há dados a serem transmitidos. Quando o aluno digita a sua matrícula, o programa do 8051 varre toda a Pilha “ALUNOS” no campo “Matricula”. Se o programa encontrar algum campo “Matricula” igual à matrícula digitada, este armazenará na Pilha “Frequencia” o campo “Codigo” do aluno. 68 CAPITULO VII 7 A comunicação Serial 7.1 A Serial do 8051 Neste projeto, foram usados dois modos de comunicação serial do 8051, onde cada modo de configuração serial é usado para a comunicação com elementos diferentes, em tempos distintos, separados fisicamente pelo chaveador CI 4066. – Modo 0: Síncrono – usado para o 8051 se comunicar com o RTC; – Modo 1: Assíncrono de 8 bits, com baud-rate de 19200 – usado para o 8051 se comunicar com o PC; 7.1.1 Comunicação com o RTC A comunicação com o RTC consiste em ler e escrever (configurar) a data e hora no RTC. O manuseio deste CI foi detalhado no Capítulo V. 7.1.2 Comunicação com o PC A comunicação com o PC consiste em: – Descarregar e recuperar dados armazenados na EEPROM (CI 28C64B). – Configurar a data e hora no RTC (CI 1302). 69 7.2 O Protocolo de Comunicação Serial 7.2.1 Os Conectores O conector utilizado na placa para a conexão serial com o PC foi um DB9 Fêmea. No cabo, consequentemente, utilizou-se o DB9 Macho. Na figura abaixo, estão detalhes do conector da placa e o do cabo. (a) placa (b) cabo Figura 7.1 Esquema dos conectores DB9 Como a serial é usada para dois eventos, e em instantes distintos, foi aterrado o pino 1 e ligou-se o pino 4 do conector DB9 do circuito ao pino p3.2 do 8051. No cabo serial, existe um curto entre os pinos 1 e 4 do conector DB9. Dessa forma, o circuito microcontrolador monitora constantemente o pino p3.2 para verificar se o cabo serial está conectado ou não ao circuito. Quando conectado, o microcontrolador finaliza a sua ligação serial com o RTC e se prepara para a comunicação com o PC. Quando o cabo é desconectado, o 8051 percebe a desconexão e se prepara para conectar novamente ao RTC. Este chaveamento é intermediado pelo CI 4066. Para a comunicação serial com o PC, foi desenvolvido um protocolo de comunicação serial para que enviasse e retornasse dados e que atualizasse a data e a hora do RTC, com segurança e velocidade. 70 7.2.2 Verificação e correção de erros Para verificar todos os bytes, a melhor maneira de solucionar o problema de erro, é que para cada byte enviado, outro retorna ao transmissor, ou seja, se o transmissor envia um byte, o receptor retornará um byte de resposta. Este protocolo de checagem de erros parece obsoleto, porém, foi a melhor forma encontrada para compatibilizar a comunicação entre o PC e o 8051, pois o buffer do 8051 é de apenas um byte. Além disso, se fosse enviado um pacote do PC para o 8051, onde cada byte fosse enviado com um intervalo, haveriam problemas com a velocidade de processamento dos PCs, pois se um pacote fosse enviado corretamente de um PC de 500 MHz, esse mesmo pacote poderia perder bytes se enviado por um PC de 1 GHz, uma vez que um LOOP de espera depende do processador. Porém, o Windows permite usar um intervalo de espera baseado em tempo, não em um LOOP de processamento, só que o problema é que este intervalo é de 1 ms. Hora, se fosse enviado um pacote em que o intervalo entre cada byte desse pacote é enviado em intervalos de 1 ms, melhor seria se o microcontrolador já mandasse um byte de confirmação para cada byte deste pacote, pois o tempo gasto para que o microcontrolador receba um byte, analisá-lo e enviar uma resposta é de microsegundos, atraso este muito menor do que 1 ms. Outro argumento que nos leva a adotar esse protocolo de checagem de erros foi no controle de bytes enviados e recebidos, que aparecem no editor de texto no software DiarioClasse, pois facilitou bastante o fato de saber com detalhes todos os passos executados pelo 8051 e pelo DiarioClasse. Assim sendo, vários erros de programação foram rapidamente corrigidos em virtude desse protocolo. Sendo assim, o protocolo de checagem de erros adotado foi o melhor para que a comunicação entre o PC e o 8051 fosse compatível com qualquer processador, desde um processador 100 MHz até os recentemente lançados no mercado. Se um byte for checado e considerado um erro de transmissão, a transmissão é iniciada novamente. 71 7.2.3 Armazenamento de dados na RAM 7.2.3.1 Conectando As funções básicas do byte de conexão são a de verificar se o cabo serial está devidamente conectado e a de informar ao software DiarioClasse a situação da EEprom, se ela está vazia ou com alguma informação a ser transmitida. Na conexão há, na realidade, uma pergunta que o PC faz ao circuito. Quando o software DiarioClasse envia o byte de conexão, o 8051 lê o valor guardado no registrador da EEprom chamado Var_IniPilha_Eeprom (veja ANEXO). De acordo com esse valor, o 8051 retorna uma resposta que informa ao software DiarioClasse se há dados na EEProm a serem transmitidos. O símbolo da tabela ASCII que o PC envia ao 8051 é o #15. Se a EEProm tiver dados armazenados, a resposta será #15, senão, será enviado o símbolo #13. 7.2.3.2 Envio de dados O primeiro byte enviado do PC para o 8051 corresponde ao símbolo de início de transmissão (o caractere #17). Quando este sinal chega ao microcontrolador, este guarda no registrador Var_IniPilha_Eeprom um valor que significa símbolo de pilha vazia, ou seja, limpa a EEProm. Para cada aluno matriculado, são enviados ao circuito, 6 bytes que correspondem à matrícula do aluno, 2 bytes que correspondem ao código (do banco de dados), 16 bytes que correspondem ao nome do aluno. Fica opcional configurar a data e a hora durante a transmissão. O fim de transmissão se dá quando o PC envia o caractere #19. Quando este caractere chega ao 8051, este armazenará na EEprom a posição do último byte da Pilha ALUNOS. Como o código do aluno é de apenas 2 bytes, inicialmente se poderia enviar apenas 99 alunos. Porém, foi feita uma sub-rotina que converte um número decimal para transformá-lo em um número numa base 40, onde nenhum valor do caractere pode assumir algum valor dos símbolos reservados para o controle da comunicação, totalizando, então, em pouco mais de 1500 alunos que podem ser enviados à EEProm pelo protocolo de comunicação. 72 7.2.3.3 Configurando a data e a hora O símbolo de início de configuração da data e da hora é o caractere #27. Quando este símbolo é enviado para o 8051, este armazenará os próximos 13 bytes em sua RAM interna. Após armazenado, o 8051 desconecta-se temporariamente com o PC para conectar-se com o RTC e configurar a data e a hora. Depois disso, o 8051 volta a se comunicar com o PC, enviando o símbolo de fim de configuração de hora, o caractere #11. Se houver algum erro na configuração da data e da hora, o 8051 retorna ao PC o caractere #12. 7.2.2.4 Recepção de dados Na recepção de dados, os dados que chegam ao PC são somente os dados da Pilha “Frequencia”, ou seja, apenas as datas, horas e os códigos dos alunos que efetuaram a sua presença em sala de aula. Antes de se receber os dados da pilha, é enviado o símbolo que pede o tamanho da pilha, o caractere #16, após isso, são recebidos 4 bytes, contendo os valores dos ponteiros que indicam o final da pilha “ALUNOS” (2 bytes) e da pilha “Frequencia” (2 bytes). Subtraindo-se os ponteiros, tem-se o tamanho da pilha “Frequencia”, consequentemente, a quantidade de dados a serem recebidos. Logo após, o PC recebe a pilha “Frequencia”, composta pelas unidades “Diarias”. Cada unidade é formada por: um byte que significa o início de um novo dia de aula (#25), o minuto, hora, dia, mês, semana e ano em que houveram as freqüências, seguidamente do código dos alunos. Após a recepção, é enviado ao 8051 o símbolo que apagará a pilha “Frequencia” (caractere #25), assim, não se corre o risco de receber dados duplicados. 73 Figura 7.2 Os bytes da recepção de dados no PC 74 CAPITULO VIII 8 Conclusão Esse projeto foi relizado com o objetivo de construir um Registro de Freqüência Microcontrolado. Durante o decorrer da montagem, deparamo-nos com muitas dificuldades, pois não estávamos acostumados com o manuseio de alguns periféricos do sistema, tais como: teclado, LCD e o RTC. Além disso não sabíamos como seria feito o armazenamento dos dados na EEPROM, e nem como seria a comunicação serial. Outra grande dificuldade com a qual nos deparamos foi com a implementação do endereçamento de memória, com a qual é possível expandir o número de periféricos comandados pelo Microcontrolador, pois encontramos pouca literatura a respeito do assunto. Essas dificuldades aos poucos foram superadas à medida em que fomos nos familiarizando com os componentes e programas. Esperamos que esse sistema seja de grande valia para a Escola de Engenharia Elétrica, facilitando o controle de freqüência dos alunos para o professor. Esperamos que o sistema seja uma referência para os estudantes de Engenharia Elétrica que forem utilizar sistemas microcontrolados. 75 Referências 1 Markenzie, I.Scott.; The 8051 Microcontroller – 2 Ed., Prentience. 2 Douglas, V. Hall, Micro Processors and Digital Systems, McGraw – Hill, International Student, 1994. 3 Tub, Herbet, Eletronica Digital, - São Paulo: Makon, McGraw – Hill. 4 National Semicondutor, Data Acquisition Linear Devices, 1986. 5 Cláudio A. Fleury e Ilton Barbacena; Apostila de Microcontroladores – ETFGo, Goiânia, 1996. 6 Dallas Semicondutor; TimeKeeping & NVSRAM DataBook – Dallas Semicondutor, 1996. 76 ANEXO ;============================================================================== ;============================================================================== ;=== Software: Diario de Classe Eletrônico === ;=== By: Carlos Renato Borges dos Santos === ;=== José Lemes de Souza Júnior === ;=== Version: 1.0 === ;=== Last Revision: 17/02/03 === ;============================================================================== ;============================================================================== $mod51 ;-----------------------------------------------------------------------------; --------------------- Variaveis da RAM INTERNA do 8051 ----------------;-----------------------------------------------------------------------------VarTime equ 0Ah ; Valor do CLOCK enviado ou recebido VarDezena equ 0Bh ; Var que armaz a dezena do CLOCk VarUnidade equ 0Ch ; Var que armaz a unidade do CLOCK VarSegDez equ 0Dh ; Var que armaz o valor do 2o digito do segundo VarSegUnid equ 0Eh ; Var que armaz o valor do 1o dig segundo VarMinDez equ 0Fh ; Var que armaz o valor do 2o dig minuto VarMinUnid equ 10h ; Var que armaz o valor do 1o dig minuto VarHoraDez equ 11h ; Var que armaz o valor do 2o dig hora VarHoraUnid equ 12h ; Var que armaz o valor do 1o dig hora VarDiaDez equ 13h ; Var que armaz o valor do 2o dig dia VarDiaUnid equ 14h ; Var que armaz o valor do 1o dig dia VarMesDez equ 15h ; Var que armaz o valor do 2o dig mes VarMesUnid equ 16h ; Var que armaz o valor do 1o dig mes VarSemana equ 17h ; Var que armaz o valor do 1o dig semana VarAnoDez equ 18h ; Var que armaz o valor do 2o dig ano VarAnoUnid equ 19h ; Var que armaz o valor do 1o dig ano Var_DPTR_Low equ 1Ah ; Var que armaz a parte Low do DPTR p/ subrotinas de escrita LCD Var_DPTR_High equ 1Bh ; Var que armaz a parte Higth do DPTR p/ subrotinas de escrita LCD Var_RAM equ 1Ch ; Var intermediaria de acesso a RAM Var_FimPilha_High equ 1Dh ; Var que armaz a parte alta do end. da pilha Var_FimPilha_Low equ 1Eh ; Var que armaz a parte baixa do end. da pilha Var_Digito1 equ 1Fh ; Var que armaz o 1o digito Var_Digito2 equ 20h ; Var que armaz o 2o dig Var_Digito3 equ 21h ; Var que armaz o 3o dig Var_Digito4 equ 22h ; Var que armaz o 4o dig Var_Digito5 equ 23h ; Var que armaz o 5o dig Var_Digito6 equ 24h ; Var que armaz o 6o dig Var_Tecla equ 25h ; Var que armaz a tecla Var_IniPilhaAluno_High equ 26h ; Var que armaz a pos atual da pilha(na busca matricula) Var_IniPilhaAluno_Low equ 27h ; Var que armaz a pos atual da pilha(na busca matricula) Var_UltCodigHigh equ 28h ; Var que armaz a parte baixa da ult. pos RAM Var_UltCodigLow equ 29h ; Var que armaz a parte alta da ult. pos RAM ;-----------------------------------------------------------------------------; --------------------- Pinos do 8051 usados no Programa ----------------;-----------------------------------------------------------------------------Bit_Serial equ 7Eh ; Bit relac a inic da serial ;-----------------------------------------------------------------------------; --------------------- Pinos do 8051 usados no Programa ----------------;-----------------------------------------------------------------------------PinoSerial equ p3.4 ; Def qual o perif conect com a serial PinoRST_RTC equ p3.3 ; Pino que hab comunic com RTC PinoModoSer equ p3.2 ; Pino que verif a conexao Serial ;-----------------------------------------------------------------------------; --------------------- Enderecamento dos Perifericos ----------------;-----------------------------------------------------------------------------End_EscrevaInstrucao_LCD equ 0E000h ; End de escrita de instruc no LCD End_EscrevaDado_LCD equ 0E001h ; End de escrita de dados no LCD End_LeiaInstrucao_LCD equ 0E002h ; End de leitura de instruc no LCD End_LeiaDado_LCD equ 0E003h ; End de leitura de dados no LCD 77 ;-----------------------------------------------------------------------------; --------------------- Enderecos de Registradores EEProm ----------------;-----------------------------------------------------------------------------Var_InicioPilha_EEProm equ 04h ; Pos de inic da pilha da EEProm Var_UltCodigHigh_EEProm equ 03h ; Ult pos da pilha de codig da EEProm Var_UltCodigLow_EEProm equ 02h ; Ult pos da pilha de codig da EEProm Var_FimPilha_EEPromHigh equ 01h ; End que armaz a parte High da pilha Var_FimPilha_EEPromLow equ 00h ; End que armaz a parte Low da pilha ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> <><><><><><> org 00h jmp Inicio ; Inicia o Hardware org 30h Inicio: mov SP,#30h ; SP aponta p/ o reg. 30h clr Bit_Serial ; Bit relac à inic da serial lcall Inicia_SerSinc ; Inic serial mod Sinc ContInicio: lcall Inicia_LCD ; Configura o display jmp main ;============================================================================== ;=== *** Main *** === ;=== Information: Programa Principal === ;=== Destroys: SCON, RI, TI === ;=== Calls: Inicia_SerSinc, Inicia_SerAssinc, === ;=== Recebe_SerAssinc, Recebe_SerSinc === ;=== === ;=== In: --=== ;=== Out: --=== ;============================================================================== main: jb PinoModoSer,Desconecta_PC ; Se PinoModoSer estiver set, PC desconect jmp Conecta_PC ; Se PinoModoSer estiver reset, PC conect MensagemTelaInicial: db 'Diario de Classe',0FFh MensagemTelaInicial2: db 'Eletronico - EEE',0FFh ;============================================================================== Desliga: jnb p1.7,ContDesliga ; Verifica se o bit 7 foi zerado ret ContDesliga: clr PinoRST_RTC ; Desab comunic c/ RTC lcall EscreveLinha1_LCD mov DPTR,#MensagemDesliga1_LCD lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#MensagemDesliga2_LCD lcall EscreveEstatico_LCD mov R4,#12h ; Carregando R4 c/ atraso lcall EsperaTeclado ; Chamando atraso lcall Desliga_LCD mov PCON,#02h ; Modo PowerDown do microcontrolador MensagemDesliga1_LCD: db ' O sistema pode ',0FFh MensagemDesliga2_LCD: db ' ser desligado! ',0FFh ;============================================================================== Conecta_PC: jnb Bit_Serial,ChamaInicSerAssinc ; Verifica se ja foi inicializado no modo assinc lcall Recebe_SerAssinc ; Verifica se recebeu algum Byte sjmp main ;============================================================================== Desconecta_PC: jb Bit_Serial,ChamaInicSerSinc ; Verifica se ja foi inicializado no modo sincrono mov A,P1 78 lcall Desliga anl A,#0Fh ; Filtra a parte baixa de A mov B,A xrl A,#01100b ; Verifica se igual a TeclaCANCELA jz Teclado ; Se igual, pula lcall Recebe_SerSinc jmp main ;============================================================================== ChamaInicSerSinc: clr Bit_Serial ; Para nao ser mais inicializado neste modo lcall Inicia_SerSinc ; Sub-rotina para inicializar a serial modo sincrono jmp main ;============================================================================== ChamaInicSerAssinc: lcall EscreveLinha1_LCD mov DPTR,#Mensagem_Conectando lcall EscreveEstatico_LCD lcall LimpaLinha2_LCD setb Bit_Serial ; Para nao ser mais inicializado neste modo lcall Inicia_SerAssinc ; Sub-rotina para inicializar a serial modo assincrono jmp main ;============================================================================== ;=== Sub-rotinas: 1 - IniciaTeclado === ;=== 2 - LeiaTeclado === ;=== 3 - EsperaTeclado === ;=== Information: 1 - Inicializa a entrada de dados pelo teclado === ;=== 2 - Le os pinos do teclado === ;=== 3 - Sub-rotina de atraso p/ evitar trepidacoes === ;=== Destroys: R1, R4, A, DPTR, Var_Tecla, Var_Digito1, === ;=== Var_Digito2, Var_Digito3, Var_Digito4, === ;=== Var_Digito5, Var_Digito6 === ;=== Calls: EscreveLinha1_LCD, EscreveLinha2_LCD, === ;=== EscreveEstatico_LCD, MensagemMatricula_LCD, === ;=== LimpaLinha1, LimpaLinha2, EsperaTeclado, === ;=== MensagemOK_LCD, ErroFaltaTecla1_LCD, === ;=== ErroFaltaTecla2_LCD === ;=== In: 1 - --=== ;=== 2 - --=== ;=== 3 - R4 === ;=== Out: --=== ;============================================================================== Teclado: mov DPTR,#Var_UltCodigHigh_EEProm movx A,@DPTR mov Var_UltCodigHigh,A mov DPTR,#Var_UltCodigLow_EEProm movx A,@DPTR mov Var_UltCodigLow,A mov DPL,Var_UltCodigLow mov DPH,Var_UltCodigHigh inc DPTR mov Var_RAM,#14d lcall Escreva_RAM lcall ArmazDPTR lcall LeiaTudo_RTC lcall RecupDPTR mov R1,#VarMinDez mov B,#VarAnoUnid LoopTeclado: mov A,@R1 mov Var_RAM,A inc DPTR lcall Escreva_RAM mov A,R1 inc R1 xrl A,B jz ContTeclado 79 jmp LoopTeclado ContTeclado: mov Var_UltCodigLow,DPL mov Var_UltCodigHigh,DPH mov DPTR,#Var_UltCodigLow_EEProm mov Var_RAM,Var_UltCodigLow lcall Escreva_RAM mov DPTR,#Var_UltCodigHigh_EEProm mov Var_RAM,Var_UltCodigHigh lcall Escreva_RAM mov R0,#Var_InicioPilha_EEProm mov Var_RAM,#55h ; Simbolo de pilha cheia lcall EscrevaR0_RAM ; Var_InicioPilha_EEProm recebe o valor 55h IniciaTeclado: lcall LimpaLinha1_LCD lcall LimpaLinha2_LCD lcall EscreveLinha1_LCD mov DPTR,#MensagemMatricula_LCD lcall EscreveEstatico_LCD mov R1,#Var_Digito1 ; Para inicializar a busca da matricula ;============================================================================== LeiaTeclado: mov A,p1 jnb Acc.7,Desl ; Pula se for desligar jmp ContinuaLeiaTeclado ; Pula se nao for desligar Desl: jmp Desliga ; Desliga o circuito ContinuaLeiaTeclado: anl A,#0Fh ; Apenas os dados do teclado sao armazenados mov Var_Tecla,A xrl A,#0Fh ; Compara se nao houve tecla apertada jz LeiaTeclado ; Volta se nao houve tecla apertada mov A,Var_Tecla ; A recebe o valor do teclado xrl A,#00h ; Compara se pressionou tecla 1 jz Tecla1 ; Pula p/ tecla 1 mov A,Var_Tecla xrl A,#01h jz Tecla2 mov A,Var_Tecla xrl A,#02h jz Tecla3 mov A,Var_Tecla xrl A,#0100b jz Tecla4 mov A,Var_Tecla xrl A,#0101b jz Tecla5 mov A,Var_Tecla xrl A,#0110b jz Tecla6 mov A,Var_Tecla xrl A,#01000b jz Tecla7 mov A,Var_Tecla xrl A,#01001b jz Tecla8 mov A,Var_Tecla xrl A,#01010b jz Tecla9 mov A,Var_Tecla xrl A,#01101b jz Tecla0 mov A,Var_Tecla xrl A,#01100b jz TeclaRESET 80 mov A,Var_Tecla xrl A,#01110b jz TeclaCONFIRMA jmp LeiaTeclado ; Se houver ruido, volta p/ nova leitura ;============================================================================== Tecla1: mov @R1,#31h jmp TecladoDigitado ;============================================================================== Tecla2: mov @R1,#32h jmp TecladoDigitado ;============================================================================== Tecla3: mov @R1,#33h jmp TecladoDigitado ;============================================================================== Tecla4: mov @R1,#34h jmp TecladoDigitado ;============================================================================== Tecla5: mov @R1,#35h jmp TecladoDigitado ;============================================================================== Tecla6: mov @R1,#36h jmp TecladoDigitado ;============================================================================== Tecla7: mov @R1,#37h jmp TecladoDigitado ;============================================================================== Tecla8: mov @R1,#38h jmp TecladoDigitado ;============================================================================== Tecla9: mov @R1,#39h jmp TecladoDigitado ;============================================================================== Tecla0: mov @R1,#30h jmp TecladoDigitado ;============================================================================== TeclaRESET: jmp IniciaTeclado ;============================================================================== TeclaCONFIRMA: mov A,R1 dec A xrl A,#Var_Digito6 ; Verifica se foram pressionados 6 digitos jz ContTeclaCONFIRMA ; Se foi, pula lcall EscreveLinha1_LCD ; Senao, escreve na linha 1 do LCD mov DPTR,#ErroFaltaTecla1_LCD lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#ErroFaltaTecla2_LCD lcall EscreveEstatico_LCD jmp ContTeclaCONFIRMA2 ContTeclaCONFIRMA: lcall ComparaMatricula ContTeclaCONFIRMA2: mov R4,#12h ; Carrega R4 p/ espera lcall EsperaTeclado ; Chama a sub-rotina de espera lcall IniciaTeclado ; Chama iniciar o teclado jmp LeiaTeclado ; Pula p/ ler novamente o teclado 81 ErroFaltaTecla1_LCD: db 'Digite 6 numeros',0FFh ErroFaltaTecla2_LCD: db 'para matricula ',0FFh MensagemOK_LCD: db ' Presenca OK! ',0FFh ;============================================================================== ;=== In R4 === ;============================================================================== EsperaTeclado: mov R3,#256d EsperaTeclado1: mov R2,#256d djnz R2,$ ; Dec R2 ate zerar djnz R3,EsperaTeclado1 ; Dec R3 ate zerar djnz R4,EsperaTeclado ; Dec R4 ate zerar ret ;============================================================================== TecladoDigitado: clr cy mov A,#Var_Digito6 ; Move p/ A o endereco VarDigito6 subb A,R1 jb cy,TecladoExcessoDigito ; Verifica se o carry setou, pois se sim, pula mov A,@R1 lcall EscrevaDado_LCD mov R4,#03h ; Carrega R4 com Atraso lcall EsperaTeclado ; Chama o atraso inc R1 ; Inc o ponteiro R1 jmp LeiaTeclado ; Pula p/ ler novamente o teclado TecladoExcessoDigito: lcall EscreveLinha1_LCD mov DPTR,#MensagemExcessoDigito1_LCD lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#MensagemExcessoDigito2_LCD lcall EscreveEstatico_LCD mov R4,#10h ; Carrega atraso lcall EsperaTeclado ; Chama o atraso jmp IniciaTeclado MensagemExcessoDigito1_LCD: db 'Digite apenas 6 ',0FFh MensagemExcessoDigito2_LCD: db 'numeros ',0FFh ;============================================================================== ComparaMatricula: mov R0,#Var_FimPilha_EEPromHigh lcall LeiaR0_RAM mov Var_FimPilha_High,A mov R0,#Var_FimPilha_EEPromLow lcall LeiaR0_RAM mov Var_FimPilha_Low,A mov DPTR,#Var_InicioPilha_EEProm mov R0,#Var_Digito1 inc DPTR IniBusca: mov R0,#Var_Digito1 mov Var_IniPilhaAluno_Low,DPL mov Var_IniPilhaAluno_High,DPH Busca: mov B,@R0 movx A,@DPTR xrl A,B jz ContBusca jmp PulaAluno ContBusca: mov A,R0 xrl A,#Var_Digito6 82 jz FimBuscaAluno inc R0 inc DPTR jmp Busca FimBuscaAluno: inc DPTR lcall Codigo inc DPTR lcall Codigo mov R1,#16d lcall ArmazDPTR lcall EscreveLinha2_LCD lcall RecupDPTR LoopEscreveNome: inc DPTR lcall ArmazDPTR movx A,@DPTR lcall EscrevaDado_LCD lcall RecupDPTR djnz R1,LoopEscreveNome lcall EscreveLinha1_LCD mov DPTR,#MensagemOK_LCD lcall EscreveEstatico_LCD RetornaAluno: ret PulaAluno: mov DPL,Var_IniPilhaAluno_Low mov DPH,Var_IniPilhaAluno_High mov R2,#24d Inc_DPTR: inc DPTR djnz R2,Inc_DPTR mov A,Var_FimPilha_High mov B,DPH clr cy subb A,B jc NaoEncontrado jz ParteLow jmp IniBusca ParteLow: mov A,Var_FimPilha_Low mov B,DPL clr cy subb A,B jc NaoEncontrado jz NaoEncontrado jmp IniBusca NaoEncontrado: lcall EscreveLinha2_LCD mov DPTR,#MensagemNaoEncontrado lcall EscreveEstatico_LCD mov R4,#05h lcall EsperaTeclado jmp RetornaAluno MensagemNaoEncontrado: db 'Nao Encontrado! ',0FFh ;============================================================================== ArmazDPTR: mov Var_DPTR_Low,DPL mov Var_DPTR_High,DPH ret RecupDPTR: mov DPL,Var_DPTR_Low mov DPH,Var_DPTR_High ret Codigo: lcall ArmazDPTR ; Armaz a pos atual da leitura na RAM 83 mov DPTR,#Var_UltCodigHigh_EEProm ; Recup a ult pos da RAM movx A,@DPTR mov Var_UltCodigHigh,A mov DPTR,#Var_UltCodigLow_EEProm movx A,@DPTR mov Var_UltCodigLow,A lcall RecupDPTR ; Recup a pos. atual da RAM movx A,@DPTR mov Var_RAM,A mov DPH,Var_UltCodigHigh mov DPL,Var_UltCodigLow inc DPTR lcall Escreva_RAM mov Var_UltCodigHigh,DPH mov Var_UltCodigLow,DPL mov Var_RAM,Var_UltCodigHigh mov DPTR,#Var_UltCodigHigh_EEProm lcall Escreva_RAM mov Var_RAM,Var_UltCodigLow mov DPTR,#Var_UltCodigLow_EEProm lcall Escreva_RAM lcall RecupDPTR ret ;============================================================================== ;=== Sub-rotinas: 1 - Inicia_SerAssinc === ;=== Information: 1 - Inicia a transmissao serial assincrona === ;=== Destroys: TMOD, TH1, TR1, TR1, IE, SCON, PCON, === ;=== RI, TI === ;=== Calls: --=== ;=== In: --=== ;=== Out: --=== ;============================================================================== Recebe_SerSinc: mov A,B xrl A,#02h ; Compara se tecla 3 jz EscreveCLOCK_LCD mov A,B xrl A,#00h ; Compara se tecla 3 jz EscreveCapacidadeRAM_LCD lcall EscreveLinha1_LCD mov DPTR,#MensagemTelaInicial lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#MensagemTelaInicial2 lcall EscreveEstatico_LCD jmp FimRecebe_SerSinc EscreveCLOCK_LCD: mov R4,#05h LoopEscreveCLOCK_LCD: mov R3,#0FFh LoopEscreveCLOCK_LCD2: mov R2,0FFh lcall LeiaTudo_RTC lcall TelaCLOCK_LCD lcall Desliga ; Verifica se o bit 7 foi zerado djnz R2,$ djnz R3,LoopEscreveCLOCK_LCD2 djnz R4,LoopEscreveCLOCK_LCD jmp FimRecebe_SerSinc FimRecebe_SerSinc: ret ;------------------------------------------------------------EscreveCapacidadeRAM_LCD: mov R0,#Var_UltCodigHigh_EEProm lcall LeiaR0_RAM mov B,A mov A,B 84 clr cy subb A,#00h jc ZeroPorCento jmp ContEscreveCapacidadeRAM_LCD1 ZeroPorCento: mov Var_Digito1,#30h mov Var_Digito2,#30h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD1: mov A,B clr cy subb A,#02h jc DezPorCento jmp ContEscreveCapacidadeRAM_LCD2 DezPorCento: mov Var_Digito1,#31h mov Var_Digito2,#30h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD2: mov A,B clr cy subb A,#04h jc QuinzePorCento jmp ContEscreveCapacidadeRAM_LCD3 QuinzePorCento: mov Var_Digito1,#31h mov Var_Digito2,#35h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD3: mov A,B clr cy subb A,#06h jc VintePorCento jmp ContEscreveCapacidadeRAM_LCD4 VintePorCento: mov Var_Digito1,#32h mov Var_Digito2,#30h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD4: mov A,B clr cy subb A,#08h jc VinteCincoPorCento jmp ContEscreveCapacidadeRAM_LCD5 VinteCincoPorCento: mov Var_Digito1,#32h mov Var_Digito2,#35h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD5: mov A,B clr cy subb A,#0Ah jc TrintaCincoPorCento jmp ContEscreveCapacidadeRAM_LCD6 TrintaCincoPorCento: mov Var_Digito1,#33h mov Var_Digito2,#35h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD6: mov A,B clr cy subb A,#0Ch jc QuarentaPorCento jmp ContEscreveCapacidadeRAM_LCD7 QuarentaPorCento: mov Var_Digito1,#34h mov Var_Digito2,#30h 85 jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD7: mov A,B clr cy subb A,#0Eh jc QuarentaCincoPorCento jmp ContEscreveCapacidadeRAM_LCD8 QuarentaCincoPorCento: mov Var_Digito1,#34h mov Var_Digito2,#35h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD8: mov A,B clr cy subb A,#10h jc CinquentaPorCento jmp ContEscreveCapacidadeRAM_LCD9 CinquentaPorCento: mov Var_Digito1,#35h mov Var_Digito2,#30h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD9: mov A,B clr cy subb A,#12h jc CinquentaCincoPorCento jmp ContEscreveCapacidadeRAM_LCD10 CinquentaCincoPorCento: mov Var_Digito1,#35h mov Var_Digito2,#35h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD10: mov A,B clr cy subb A,#14h jc SessentaCincoPorCento jmp ContEscreveCapacidadeRAM_LCD11 SessentaCincoPorCento: mov Var_Digito1,#36h mov Var_Digito2,#30h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD11: mov A,B clr cy subb A,#16h jc SetentaPorCento jmp ContEscreveCapacidadeRAM_LCD12 SetentaPorCento: mov Var_Digito1,#37h mov Var_Digito2,#30h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD12: mov A,B clr cy subb A,#18h jc OitentaPorCento jmp ContEscreveCapacidadeRAM_LCD13 OitentaPorCento: mov Var_Digito1,#38h mov Var_Digito2,#30h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD13: mov A,B clr cy subb A,#1Ah jc OitentaCincoPorCento jmp ContEscreveCapacidadeRAM_LCD14 86 OitentaCincoPorCento: mov Var_Digito1,#38h mov Var_Digito2,#35h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD14: mov A,B clr cy subb A,#1Ch jc NoventaPorCento jmp ContEscreveCapacidadeRAM_LCD15 NoventaPorCento: mov Var_Digito1,#39h mov Var_Digito2,#30h jmp FimCapacidadeRAM ContEscreveCapacidadeRAM_LCD15: mov A,B clr cy subb A,#1Eh jc NoventaCincoPorCento jmp CemPorCento NoventaCincoPorCento: mov Var_Digito1,#39h mov Var_Digito2,#35h jmp FimCapacidadeRAM CemPorCento: lcall EscreveLinha1_LCD mov DPTR,#MensagemRAMCheia lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#MensagemRAMCheia2 lcall EscreveEstatico_LCD mov R4,#10h lcall EsperaTeclado jmp FimRecebe_SerSinc MensagemRAMCheia: db ' Capacidade RAM ',0FFh MensagemRAMCheia2: db ' Esgotada!!!!!! ',0FFh EscreveCapacidade_LCD: lcall EscreveLinha1_LCD mov DPTR,#MensagemCapacidade lcall EscreveEstatico_LCD lcall LimpaLinha2_LCD lcall EscreveLinha2_LCD mov A,Var_Digito1 lcall EscrevaDado_LCD mov A,Var_Digito2 lcall EscrevaDado_LCD mov A,#25h lcall EscrevaDado_LCD ret MensagemCapacidade: db 'Total RAM usado:',0FFh FimCapacidadeRAM: lcall EscreveCapacidade_LCD mov R4,#10h lcall EsperaTeclado jmp FimRecebe_SerSinc ;------------------------------------------------------------Inicia_SerAssinc: setb PinoSerial ; Conect 8051 ao PC mov TMOD,#00100000b ; Timer 1 em modo 2 mov TH1,#0FDh ; Recarga do Timer 1 para 19200 bauds setb TR1 ; Lig Timer 1 mov IE,#90h ; Hab serial mov SCON,#01010000b ; Serial em mod 1 e já libera bit REN mov PCON,#80h ; Dobra a relaç de div freq serial 87 clr RI ; Hab SBuf a receb dados clr TI clr 7Fh mov R1,#00h ret ;============================================================================== ;=== Sub-rotinas: 1 - Escreva_RAM === ;=== Information: 1 - Escreve o byte na RAM === ;=== Destroys: A === ;=== Calls: --=== ;=== In: Var_RAM, DPTR, R0 === ;=== Out: --=== ;============================================================================== Escreva_RAM: mov A,Var_RAM movx @DPTR,A ; Env dado p/ pos na RAM apont por DPTR LoopEscreva_RAM: movx A,@DPTR cjne A,Var_RAM,LoopEscreva_RAM ; Verif se dado ja foi armaz na RAM ret ;============================================================================== EscrevaR0_RAM: mov Var_DPTR_Low,DPL mov Var_DPTR_High,DPH mov DPH,#00h mov DPL,R0 lcall Escreva_RAM mov DPL,Var_DPTR_Low mov DPH,Var_DPTR_High ret ;============================================================================== LeiaR0_RAM: mov Var_DPTR_Low,DPL mov Var_DPTR_High,DPH mov DPH,#00h mov DPL,R0 movx A,@DPTR mov DPL,Var_DPTR_Low mov DPH,Var_DPTR_High ret ;============================================================================== ;=== Sub-rotinas: 1 - Recebe_SerAssinc === ;=== Information: 1 - Recebe dados pela serial modo assincrono === ;=== Destroys: A, RI, R0, R1, R2, DPTR, Sbuf, Var_DPTR_Low, === ;=== Var_DPTR_High, Var_InicioPilha_EEProm, === ;=== Var_FimPilha_EEPromHigh, Var_FimPilha_EEPromLow === ;=== Calls: EnviaByte, EscreveLinha1_LCD, EscreveLinha2_LCD,=== ;=== EscreveEstatico_LCD === ;=== In: --=== ;=== Out: --=== ;============================================================================== Recebe_SerAssinc: jb RI,RecebidoSerAssinc ; Verifica se recebeu algum Byte VoltaRecebidoSerAssinc: ret IniTamanhoRAM: mov R1,#53h mov R0,#Var_FimPilha_EEPromLow lcall LeiaR0_RAM lcall EnviaByte ljmp VoltaRecebidoSerAssinc TamanhoRAM: inc R0 mov A,R0 xrl A,#Var_InicioPilha_EEProm jz FimTamanhoRAM lcall LeiaR0_RAM 88 lcall EnviaByte jmp VoltaRecebidoSerAssinc FimTamanhoRAM: mov A,#18d mov R1,#00h lcall EnviaByte jmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina RecebidoSerAssinc ; Destroys: A, R2 ;-----------------------------------------------------------------------------RecebidoSerAssinc: clr RI ; Se recebeu byte mov R2,SBuf mov A,R1 ; A recebe o valor de R1 xrl A,#53h jz TamanhoRAM mov A,R2 xrl A,#16d ; Simb de EnviaTamanhoRAM jz IniTamanhoRAM mov A,R2 xrl A,#15d ; Simb de conexao jz Conecta mov A,R2 xrl A,#21d ; Simb de Inicio de Transmissao jz IniTransm mov A,R2 xrl A,#31d ; Símb de 2 inicio de Transmissao jz Ini2Transm mov A,R2 xrl A,#17d ; Simb de Inicio de Recepcao jz IniRecep mov A,R2 xrl A,#29d ; Simb de nome jz Nome mov A,R2 xrl A,#27d ; Simb de ConfiguraHora jz ConfigHora mov A,R2 xrl A,#11d ; Simb de FimConfiguraHora jz FimConfigHora mov A,R2 xrl A,#25d ; Simb de Limpa Acesso jz LimpaAcesso mov A,R2 xrl A,#19d ; Simb Fim de Recepcao jz TermRecep jmp Dado ;############################################################################## ; Subrotinas de Salto ; Destroys: --;############################################################################## Conecta: jmp CConecta IniTransm: jmp CIniTransm Ini2Transm: jmp CIni2Transm IniRecep: jmp CIniRecep Nome: jmp CNome ConfigHora: jmp CConfigHora LimpaAcesso: jmp CLimpaAcesso TermRecep: 89 jmp CTermRecep Transm: jmp CTransm FimConfigHora: jmp CFimConfigHora ;-----------------------------------------------------------------------------; Subrotina CConecta ; Destroys: A, R0, DPTR ;-----------------------------------------------------------------------------CConecta: lcall EscreveLinha1_LCD mov DPTR,#MensagemLinha1_Conectado lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#MensagemLinha2_Conectado lcall EscreveEstatico_LCD mov R0,#Var_InicioPilha_EEProm ; R0 recebe o endereco do registrador lcall LeiaR0_RAM ; Var_RAM recebe o valor do reg. Var_InicioPilha_EEProm cjne A,#55h,CConectaVazio ; Compara se Var_IniciPilha_EEProm esta com o valor 55h mov A,#15d ; Simbolo de pilha cheia sjmp ContCConecta CConectaVazio: mov A,#13d ; Simbolo de pilha vazia sjmp ContCConecta ContCConecta: lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CIniTransm ; Destroys: DPTR, R1, A ;-----------------------------------------------------------------------------CIniTransm: mov R0,#Var_UltCodigHigh_EEProm ; R0 recebe o endereco do ponteiro High posicao final da pilha lcall LeiaR0_RAM ; A recebe o valor do endereco da posicao final da pilha mov Var_UltCodigHigh,A ; Var_FimPilha_High recebe a parte alta da pos. da pilha mov R0,#Var_UltCodigLow_EEProm ; R0 recebe o endereco do ponteiro Low posicao final da pilha lcall LeiaR0_RAM ; A recebe o valor do endereco da posicao final da pilha mov Var_UltCodigLow,A ; Var_FimPilha_Low recebe a parte baixa da pos. da pilha lcall EscreveLinha1_LCD mov DPTR,#Mensagem_IniTx lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#Mensagem_IniTx2 lcall EscreveEstatico_LCD mov R0,#Var_FimPilha_EEPromHigh lcall LeiaR0_RAM mov Var_FimPilha_High,A mov R0,#Var_FimPilha_EEPromLow lcall LeiaR0_RAM mov Var_FimPilha_Low,A mov DPH,Var_FimPilha_High mov DPL,Var_FimPilha_Low mov R1,#00h ; Modo TRANSMITE mov A,#21d lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CIni2Transm ; Destroys: R0, A 90 ;-----------------------------------------------------------------------------CIni2Transm: inc DPTR movx A,@DPTR lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CIniRecep ; Destroys: R0,R4,R1,A ;-----------------------------------------------------------------------------CIniRecep: lcall EscreveLinha1_LCD mov DPTR,#Mensagem_IniRx lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#Mensagem_IniRx2 lcall EscreveEstatico_LCD mov DPTR,#Var_InicioPilha_EEProm ; DPTR aponta p/ o inicio da pilha mov Var_RAM,#00h ; Simbolo para Pilha Vazia lcall Escreva_RAM ; Preparando p/ esvaziar a pilha mov R1,#55h ; Modo RECEBE mov A,#17d lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CNome ; Destroys: A ;-----------------------------------------------------------------------------CNome: mov A,#29d lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CConfigHora ; Destroys: A ;-----------------------------------------------------------------------------CConfigHora: mov R0,#VarSegDez ; Inicia R0 com a pilha do Clock mov R1,#22h ; Modo recebe Clock mov A,#27d ; Carrega A com valor que será enviado p/ SBuff lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CMatricula ; Destroys: A ;-----------------------------------------------------------------------------CLimpaAcesso: mov DPTR,#Var_InicioPilha_EEProm mov Var_RAM,#00h lcall Escreva_RAM mov DPTR,#Var_FimPilha_EEPromHigh movx A,@DPTR mov Var_RAM,A mov DPTR,#Var_UltCodigHigh_EEProm lcall Escreva_RAM mov DPTR,#Var_FimPilha_EEPromLow movx A,@DPTR mov Var_RAM,A mov DPTR,#Var_UltCodigLow_EEProm lcall Escreva_RAM mov A,#25d lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CTermRecep ; Destroys: A, R0, DPTR ;------------------------------------------------------------------------------ 91 CTermRecep: mov Var_RAM,DPH ; A recebe a parte HIGH de DPTR mov R0,#Var_FimPilha_EEPromHigh ; R0 recebe o endereco do registrador lcall EscrevaR0_RAM ; O endereco apontado por R0 recebe A mov R0,#Var_UltCodigHigh_EEProm lcall EscrevaR0_RAM mov Var_RAM,DPL ; A recebe a parte LOW de DPTR mov R0,#Var_FimPilha_EEPromLow ; R0 recebe o endereco do registrador lcall EscrevaR0_RAM ; O endereco apontado por R0 recebe A mov R0,#Var_UltCodigLow_EEProm lcall EscrevaR0_RAM lcall EscreveLinha1_LCD mov DPTR,#Mensagem_FimRx lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#MensagemLinha2_Conectado lcall EscreveEstatico_LCD mov A,#19d lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CRecep ; Destroys: DPTR, A ;-----------------------------------------------------------------------------CRecep: inc DPTR ; Atualiza o endereco da pilha mov A,R2 ; A recebe o valor de recepcao do SBuff movx @DPTR,A ; Acumula o byte recebido da serial na pilha lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CTermTransm ; Destroys: A, DPTR ;-----------------------------------------------------------------------------CTermTransm: lcall EscreveLinha1_LCD mov DPTR,#Mensagem_FimTx lcall EscreveEstatico_LCD lcall EscreveLinha2_LCD mov DPTR,#MensagemLinha2_Conectado lcall EscreveEstatico_LCD mov A,#23d ; Simbolo de fim de transmissao lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;-----------------------------------------------------------------------------; Subrotina CTransm ; Destroys: A, B ;-----------------------------------------------------------------------------CTransm: mov B,R2 movx A,@DPTR xrl A,B ; Compara se o byte receb é = ao byte env jz CTransm2 ; Se for =, continua a transmissao ljmp CIniTransm ; Byte Env <> byte receb, reinic transm ;-----------------------------------------------------------------------------; Subrotina CTransm2 ; Destroys: cy, A, R0, DPTR ;-----------------------------------------------------------------------------CTransm2: clr cy mov A,Var_UltCodigHigh ; A recebe o endereco do ponteiro High posicao final da pilha mov B,DPH ; B recebe a posicao High atual do DPTR subb A,B ; Subtrai os dois enderecos jc Erro ; Se o carry for 1, houve erro jz CTransm2_VerEndLow jmp CTransm2_Cont CTransm2_VerEndLow: 92 clr cy mov A,Var_UltCodigLow mov B,DPL subb A,B jc Erro jz CTermTransm ; Se o resultado da sub. = 0, fim de transmissao CTransm2_Cont: inc DPTR movx A,@DPTR lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Subrotina Erro ; Destroys: A ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Erro: mov A,#168d ; Se houve erro, enviar o sinal de erro lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Subrotina Dado ; Destroys: A ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Dado: mov A,R1 ; A recebe o valor de R1 xrl A,#55h ; Compara se está no modo RECEBE jz CRecep ; Se zerar, está no modo RECEBE mov A,R1 ; Move valor Modo p/ A xrl A,#00h ; Compara se modo Transmissao jz CTransm ; Se zerar, está no modo TRANSMITE mov A,R1 ; Move valor Modo p/ A xrl A,#22h ; Compara com Modo Recepcao Hora jz CRecepHora ; Pula p/ recepcao da hora jmp Erro ; Se nenhum modo foi encontrado ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CRecepHora: mov A,R2 ; A recebe o byte recebido mov @R0,A ; O valor recebido do SBuf vai p/ a pilha mov B,R0 ; Mov valor da posicao final da pilha Clock p/ B mov A,#VarAnoUnid ; Mov valor inicial da pilha Clock p/ A inc A xrl A,B jz Erro ; Se Ini > Fim, Erro inc R0 ; Incrementa o ponteiro mov A,R2 ; A recebe o byte recebido lcall EnviaByte ; Envia o Byte recebido ljmp VoltaRecebidoSerAssinc ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CFimConfigHora: mov B,R0 ; Mov o valor da pos final da pilha Clock p/ B mov A,#VarAnoUnid ; Mov o valor inic da pilha Clock p/ A inc A ; Atualiza A com relacao a R0 xrl A,B jz ContCFimConfigHora mov A,#12d ; Simb de erro de config de hora lcall EnviaByte ContCFimConfigHora: lcall Inicia_SerSinc ; Inic mod sinc p/ conexao com RTC lcall Inicia_RTC ; Config RTC lcall EscreveTudo_RTC ; Escrev valores de Clock no RTC lcall Inicia_SerAssinc ; Conect 8051 novamente ao PC mov A,#11d ; Fim de config Data lcall EnviaByte ljmp VoltaRecebidoSerAssinc ;============================================================================== ;=== Sub-rotinas: 1 - Inicia_SerSinc === ;=== Information: 1 - Inicia a transmissao serial assincrona === 93 ;=== Destroys: SCON, RI, TI === ;=== Calls: --=== ;=== In: --=== ;=== Out: --=== ;============================================================================== Inicia_SerSinc: clr PinoSerial ; Hab serial com RTC mov SCON,#00h ; Serial em modo 0 clr TI ; Hab o SBuf a transm dados ret ;============================================================================== ;=== Sub-rotinas: 1 - Inicia_RTC === ;=== Information: 1 - Inicia a habilitacao de escritas no RTC === ;=== Destroys: DPTR, PinoRST_RTC, VarTime === ;=== Calls: Escreve_RTC === ;=== In: --=== ;=== Out: --=== ;============================================================================== Inicia_RTC: clr PinoRST_RTC ; Desab PinoRST_RTC mov DPTR,#EscreveControl_RTC mov VarTime,#00h ; VarTime recebe 00h, configuracao inicial lcall Escreve_RTC ; Escreve no RTC mov DPTR,#EscreveTCS_RTC mov VarTime,#10101001b ; VarTime recebe A7h, configura carga de Back-up lcall Escreve_RTC ret ;============================================================================== ;=== Sub-rotinas: 1 - LeiaTudo_RTC === ;=== 2 - SubLeiaTudo_RTC === ;=== Information: 1 - Le dados do RTC e acumula nos registradores === ;=== 2 - """ === ;=== Destroys: A, VarTime === ;=== Calls: Leia_RTC, Conv_ASCII_to_BCD === ;=== In: --=== ;=== Out: VarSegUnid, VarSegDez, VArMinUnid, VarMinDez, === ;=== VarHoraUnid, VarHoraDez, VarDiaUnid, VarDiaMin, === ;=== VarMesUnid, VarMesDez, VarSemana, VarAnoUnid, === ;=== VarAnoDez === ;============================================================================== LeiaTudo_RTC: mov DPTR,#LeiaSegundo_RTC ; Lendo Segundo lcall Leia_RTC lcall SubLeiaTudo_RTC ; Lendo do RTC o segundo mov VarSegUnid,VarUnidade ; Recebendo Unidade segundo mov VarSegDez,VarDezena ; Recebendo Dezena segundo mov DPTR,#LeiaMinuto_RTC ; Lendo Minuto lcall Leia_RTC lcall SubLeiaTudo_RTC ; Lendo no RTC o minuto mov VarMinUnid,VarUnidade ; Recebendo Unidade minuto mov VarMinDez,VarDezena ; Recebendo Dezena minuto mov DPTR,#LeiaHora_RTC ; Lendo Hora lcall Leia_RTC lcall SubLeiaTudo_RTC ; Lendo no RTC a hora mov VarHoraUnid,VarUnidade ; Recebendo Unidade hora mov VarHoraDez,VarDezena ; Recebendo Dezena hora mov DPTR,#LeiaDia_RTC ; Lendo Dia lcall Leia_RTC lcall SubLeiaTudo_RTC ; Lendo no RTC o dia mov VarDiaUnid,VarUnidade ; Recebendo Unidade dia mov VarDiaDez,VarDezena ; Recebendo Dezena dia mov DPTR,#LeiaSemana_RTC ; Lendo Semana lcall Leia_RTC lcall SubLeiaTudo_RTC ; Lendo no RTC a semana mov VarSemana,VarUnidade ; Recebendo Unidade semana mov DPTR,#LeiaMes_RTC ; Lendo Mes lcall Leia_RTC 94 lcall SubLeiaTudo_RTC ; Lendo no RTC o mes mov VarMesUnid,VarUnidade ; Recebendo Unidade mes mov VarMesDez,VarDezena ; Recebendo Dezena mes mov DPTR,#LeiaAno_RTC ; Lendo Ano lcall Leia_RTC lcall SubLeiaTudo_RTC ; Lendo no RTC o ano mov VarAnoUnid,VarUnidade ; Recebendo Unidade ano mov VarAnoDez,VarDezena ; Recebendo Dezena ano ret ;============================================================================== SubLeiaTudo_RTC: mov A,VarTime ; A receba VarTime anl A,#00001111b ; A recebe apenas os 4 bits menos significativos lcall Conv_BCD_to_ASCII ; Converte BCD p/ ASCII mov VarUnidade,A ; VarUnidade recebe A mov A,VarTime ; A recebe VarTime anl A,#11110000b ; A recebe apenas os 4 bits mais significativos swap A ; Troca de Nibbles lcall Conv_BCD_to_ASCII ; Converte BCD p/ ASCII mov VarDezena,A ; VarDezena recebe A ret ;============================================================================== ;=== Sub-rotinas: 1 - Leia_RTC === ;=== 2 - LoopLeia_RTC === ;=== Information: 1 - Le o dado escrito no CLOCK do RTC === ;=== 2 - """ === ;=== Destroys: RI, A, DPTR, PinoRST_RTC, sbuf, VarTime === ;=== Calls: EnviaByte === ;=== In: DPTR === ;=== Out: VarTime === ;============================================================================== Leia_RTC: clr PinoRST_RTC ; Desab a comun entre 8051 e o RTC clr TI ; Hab a transm do 8051 setb PinoRST_RTC ; Hab a comun entre 8051 e o RTC mov A,#00h ; 1a pos da pilha movc A,@A+DPTR ; Valor a ser lido armaz na ROM lcall EnviaByte ; Env qual CLOCK sera lido no RTC clr RI ; Hab a serial a receber dados setb REN ; Hab o pino RX LoopLeia_RTC: jnb RI,LoopLeia_RTC ; Loop que espera a recep de dados mov VarTime,sbuf ; Recebe o valor para ser lido clr REN ; Desab o pino RX clr RI ; Desab a serial a receber dados clr PinoRST_RTC ; Desab transm de dados com RTC ret ;============================================================================== LeiaSegundo_RTC: db 10000001b ;============================================================================== LeiaMinuto_RTC: db 10000011b ;============================================================================== LeiaHora_RTC: db 10000101b ;============================================================================== LeiaDia_RTC: db 10000111b ;============================================================================== LeiaMes_RTC: db 10001001b ;============================================================================== LeiaSemana_RTC: db 10001011b ;============================================================================== LeiaAno_RTC: 95 db 10001101b ;============================================================================== LeiaClockBurst: db 10111111b ;============================================================================== ;=== Sub-rotinas: 1 - EscreveTudo_RTC === ;=== 2 - SubEscreveTudo_RTC === ;=== Information: 1 - Escreve dados no endereco apontado por === ;=== DPTR no RTC === ;=== 2 - """ === ;=== Destroys: A, VarTime === ;=== Calls: Escreve_RTC, Conv_ASCII_to_BCD === ;=== In: DPTR, VarDezena, VarUnidade === ;=== Out: VarTime === ;============================================================================== EscreveTudo_RTC: mov DPTR,#EscreveSegundo_RTC ; Escrevendo Segundo mov VarUnidade,VarSegUnid ; Recebendo Unidade segundo mov VarDezena,VarSegDez ; Recebendo Dezena segundo lcall SubEscreveTudo_RTC ; Escreve no RTC o segundo mov DPTR,#EscreveMinuto_RTC ; Escreve Minuto mov VarUnidade,VarMinUnid mov VarDezena,VarMinDez lcall SubEscreveTudo_RTC ; Escreve minuto no RTC mov DPTR,#EscreveHora_RTC ; Escrevendo Hora mov VarUnidade,VarHoraUnid mov VarDezena,VarHoraDez lcall SubEscreveTudo_RTC ; Escreve Hora no RTC mov DPTR,#EscreveDia_RTC ; Escrevendo Dia mov VarUnidade,VarDiaUnid mov VarDezena,VarDiaDez lcall SubEscreveTudo_RTC mov DPTR,#EscreveSemana_RTC ; Escrevendo semana mov VarUnidade,VarSemana mov VarDezena,#30h ; Escreve zero, porque semana so possui unidade lcall SubEscreveTudo_RTC mov DPTR,#EscreveMes_RTC ; Escrevendo Mes mov VarUnidade,VarMesUnid mov VarDezena,VarMesDez lcall SubEscreveTudo_RTC mov DPTR,#EscreveAno_RTC ; Escrevendo Ano mov VarUnidade,VarAnoUnid mov VarDezena,VarAnoDez lcall SubEscreveTudo_RTC ret ;============================================================================== SubEscreveTudo_RTC: lcall DezUnid_to_VarTime lcall Escreve_RTC ; Escreve VarTime no RTC ret ;============================================================================== DezUnid_to_VarTime: mov A,VarDezena ; A recebe dezena lcall Conv_ASCII_to_BCD ; Converte AscII em BCD swap A ; Troca de Nibbles mov VarTime,A ; VarTime recebe A mov A,VarUnidade ; A recebe VarUnidade lcall Conv_ASCII_to_BCD ; Converte unidade em BCD orl A,VarTime ; Junta Dezena e unidade mov VarTime,A ; VarTime recebe A ret ;============================================================================== ;=== Sub-rotinas: 1 - Escreve_RTC === ;=== Information: 1 - Escreve dados no endereco apontado por === ;=== DPTR no RTC === ;=== Destroys: A, Pino_RST === ;=== Calls: EnviaByte === 96 ;=== In: DPTR, VarTime === ;=== Out: --=== ;============================================================================== Escreve_RTC: clr PinoRST_RTC ; Desab comun serial setb PinoRST_RTC ; Hab a transf de dados no RTC clr TI mov A,#00h ; 1a posicao da pilha movc A,@A+DPTR ; Valor a ser configurado armaz na ROM lcall EnviaByte ; Envia qual CLOCK sera config no RTC mov A,VarTime ; Dado a ser escrito no CLOCK do RTC lcall EnviaByte ; Envia o dado ao RTC clr TI clr PinoRST_RTC ; Term a transf de dados com o RTC ret ;============================================================================== EscreveSegundo_RTC: db 10000000b ;============================================================================== EscreveMinuto_RTC: db 10000010b ;============================================================================== EscreveHora_RTC: db 10000100b ;============================================================================== EscreveDia_RTC: db 10000110b ;============================================================================== EscreveMes_RTC: db 10001000b ;============================================================================== EscreveSemana_RTC: db 10001010b ;============================================================================== EscreveAno_RTC: db 10001100b ;============================================================================== EscreveControl_RTC: db 10001110b ;============================================================================== EscreveTCS_RTC: db 10010000b ;============================================================================== EscreveClockBurst: db 10111110b ;============================================================================== ;=== Sub-rotinas: 1 - TelaCLOCK_LCD === ;=== Information: 1 - Escreve dados nos enderecos do CLOCK === ;=== armazenados na RAM do 8051 === ;=== Destroys: Porta_LCD === ;=== Calls: EscreveLinha1_LCD, EscreveLinha2_LCD, ModoDado, === ;=== EscreveEstatico_LCD, Escreve_40 === ;=== In: DPTR, VarAnoUnid, VarAnoDez, VarMesDez, === ;=== VarMesUnid, VarDiaDez, VarDiaUnid, VarHoraDez, === ;=== VarHoraUnid, VarMinDez, VarMinUnid, VarSegDez, === ;=== VarSegUnid, VarSemana === ;=== Out: Porta_LCD === ;============================================================================== TelaCLOCK_LCD: lcall EscreveLinha1_LCD mov DPTR,#MensagemEEE lcall EscreveEstatico_LCD mov A,VarDiaDez ; Carrega Porta_LCD com VarDiaDez lcall EscrevaDado_LCD lcall Espera_LCD mov A,VarDiaUnid ; Carrega Porta_LCD com VarDiaUnid lcall EscrevaDado_LCD 97 lcall Espera_LCD lcall Espaco_LCD ; Escreve Caractere de Esapaco no LCD lcall EscreveMes_RTC_to_LCD ; Escreve o mes no LCD lcall Espaco_LCD ; Escreve Caractere de Esapaco no LCD mov DPTR,#Ano20 lcall EscreveEstatico_LCD mov A,VarAnoDez ; Porta_LCD recebe VarAndoDez lcall EscrevaDado_LCD lcall Espera_LCD mov A,VarAnoUnid ; Porta_LCD recebe VarAnoUnid lcall EscrevaDado_LCD lcall Espera_LCD lcall EscreveLinha2_LCD lcall Espaco_LCD ; Escreve Caractere de Esapaco no LCD lcall EscreveSemana_RTC_to_LCD ; Escreve semana no LCD lcall Espaco_LCD ; Escreve Caractere de Esapaco no LCD lcall Espaco_LCD ; Escreve Caractere de Esapaco no LCD mov A,VarHoraDez ; Porta_LCD recebe VarHoraDez lcall EscrevaDado_LCD lcall Espera_LCD mov A,VarHoraUnid ; Porta_LCD recebe VarHoraUnid lcall EscrevaDado_LCD lcall Espera_LCD mov DPTR,#SimboloHora lcall EscreveEstatico_LCD mov A,VarMinDez ; Porta_LCD recebe VarMinDez lcall EscrevaDado_LCD lcall Espera_LCD mov A,VarMinUnid ; Porta_LCD recebe VatMinUnid lcall EscrevaDado_LCD lcall Espera_LCD mov DPTR,#SimboloMinuto lcall EscreveEstatico_LCD mov A,VarSegDez ; Porta_LCD recebe VarSegDez lcall EscrevaDado_LCD lcall Espera_LCD mov A,VarSegUnid ; Porta_LCD recebe VarSegUnid lcall EscrevaDado_LCD lcall Espera_LCD mov DPTR,#SimboloSegundo lcall EscreveEstatico_LCD lcall Espaco_LCD ; Escreve Caractere de Esapaco no LCD ret ;|EEE, 30 Out 2002| ;| Ter 09:40'14" | ;============================================================================== ;=== Sub-rotinas: 1 - EscreveSemana_RTC_to_LCD === ;=== Information: 1 - Escreve o dia da semana no LCD === ;=== Destroys: A === ;=== Calls: EscreveEstaico_LCD === ;=== In: --=== ;=== Out: --=== ;============================================================================== EscreveSemana_RTC_to_LCD: mov A,VarSemana xrl A,#31h ; Compara se e 31h jz DomingoFeira ; Desvia se for igual mov A,VarSemana ; A recebe VarSemana xrl A,#32h ; Compara se 32h jz SegundaFeira ; Desvia se for igual mov A,VarSemana ; A recebe VarSemana xrl A,#33h ; Compara se 33h jz TercaFeira ; Desvia se for igual mov A,VarSemana ; A recebe VarSemana xrl A,#34h ; Compara se 33h jz QuartaFeira ; Desvia se for igual mov A,VarSemana ; A recebe VarSemana 98 xrl A,#35h ; Compara se 33h jz QuintaFeira ; Desvia se for igual mov A,VarSemana ; A recebe VarSemana xrl A,#36h ; Compara se 33h jz SextaFeira ; Desvia se for igual jmp SabadoFeira ; Desvia se nao for os demais ;============================================================================== SabadoFeira: mov DPTR,#DB_Sabado jmp ContEscreveSemana_RTC_to_LCD ;============================================================================== SextaFeira: mov DPTR,#DB_Sexta jmp ContEscreveSemana_RTC_to_LCD ;============================================================================== QuintaFeira: mov DPTR,#DB_Quinta jmp ContEscreveSemana_RTC_to_LCD ;============================================================================== QuartaFeira: mov DPTR,#DB_Quarta jmp ContEscreveSemana_RTC_to_LCD ;============================================================================== TercaFeira: mov DPTR,#DB_Terca jmp ContEscreveSemana_RTC_to_LCD ;============================================================================== SegundaFeira: mov DPTR,#DB_Segunda jmp ContEscreveSemana_RTC_to_LCD ;============================================================================== DomingoFeira: mov DPTR,#DB_Domingo jmp ContEscreveSemana_RTC_to_LCD ;============================================================================== ContEscreveSemana_RTC_to_LCD: lcall EscreveEstatico_LCD ret ;============================================================================== DB_Domingo: db 'Dom',0FFh ;============================================================================== DB_Segunda: db 'Seg',0FFh ;============================================================================== DB_Terca: db 'Ter',0FFh ;============================================================================== DB_Quarta: db 'Qua',0FFh ;============================================================================== DB_Quinta: db 'Qui',0FFh ;============================================================================== DB_Sexta: db 'Sex',0FFh ;============================================================================== DB_Sabado: db 'Sab',0FFh ;============================================================================== ;=== Sub-rotinas: 1 - EscreveMes_RTC_to_LCD === ;=== Information: 1 - Escreve o dia do mes no LCD === ;=== Destroys: A === ;=== Calls: EscreveEstaico_LCD === ;=== In: --=== ;=== Out: --=== 99 ;============================================================================== EscreveMes_RTC_to_LCD: mov VarDezena,VarMesDez mov VarUnidade,VarMesUnid lcall DezUnid_to_VarTime ; Converte Dezena e Unidade em Byte p/ RTC mov A,VarTime xrl A,#01h jz MesJaneiro mov A,VarTime xrl A,#02h jz MesFevereiro mov A,VarTime xrl A,#03h jz MesMarco mov A,VarTime xrl A,#04h jz MesAbril mov A,VarTime xrl A,#05h jz MesMaio mov A,VarTime xrl A,#06h jz MesJunho mov A,VarTime xrl A,#07h jz MesJulho mov A,VarTime xrl A,#08h jz MesAgosto mov A,VarTime xrl A,#09h jz MesSetembro mov A,VarTime xrl A,#10h jz MesOutubro mov A,VarTime xrl A,#11h jz MesNovembro jmp MesDezembro ;============================================================================== MesDezembro: mov DPTR,#DB_Dezembro jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesJaneiro: mov DPTR,#DB_Janeiro jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesFevereiro: mov DPTR,#DB_Fevereiro jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesMarco: mov DPTR,#DB_Marco jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesAbril: mov DPTR,#DB_Abril jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesMaio: mov DPTR,#DB_Maio jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesJunho: mov DPTR,#DB_Junho jmp ContEscreveMes_RTC_to_LCD 100 ;============================================================================== MesJulho: mov DPTR,#DB_Julho jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesAgosto: mov DPTR,#DB_Agosto jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesSetembro: mov DPTR,#DB_Setembro jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesOutubro: mov DPTR,#DB_Outubro jmp ContEscreveMes_RTC_to_LCD ;============================================================================== MesNovembro: mov DPTR,#DB_Novembro jmp ContEscreveMes_RTC_to_LCD ;============================================================================== ContEscreveMes_RTC_to_LCD: lcall EscreveEstatico_LCD ret ;============================================================================== DB_Janeiro: db 'Jan',0FFh ;============================================================================== DB_Fevereiro: db 'Fev',0FFh ;============================================================================== DB_Marco: db 'Mar',0FFh ;============================================================================== DB_Abril: db 'Abr',0FFh ;============================================================================== DB_Maio: db 'Mai',0FFh ;============================================================================== DB_Junho: db 'Jun',0FFh ;============================================================================== DB_Julho: db 'Jul',0FFh ;============================================================================== DB_Agosto: db 'Ago',0FFh ;============================================================================== DB_Setembro: db 'Set',0FFh ;============================================================================== DB_Outubro: db 'Out',0FFh ;============================================================================== DB_Novembro: db 'Nov',0FFh ;============================================================================== DB_Dezembro: db 'Dez',0FFh ;============================================================================== ;=== Sub-rotinas: 1 - Conv_ASCII_to_BCD === ;=== 2 - Conv_BCD_to_ASCII === ;=== Information: 1 - Converte o valor ASCII em BCD === ;=== 2 - Converte o valor BCD em ASCII === ;=== Destroys: A, B === ;=== Calls: --=== 101 ;=== In: A === ;=== Out: A === ;============================================================================== Conv_ASCII_to_BCD: mov B,#30h ; Valor padrao ASCII para '0' subb A,B ; Subtrai valor ASCII, convertendo em BCD ret ;============================================================================== Conv_BCD_to_ASCII: mov B,#30h ; Valor padrao ASCII para '0' add A,B ; Converte formato BCD para ASCII ret ;============================================================================== ;=== Sub-rotinas: 1 - EnviaByte === ;=== 2 - LoopEnviaByte === ;=== Information: 1 - Envia dados para a serial === ;=== 2 - """ === ;=== Destroys: A === ;=== Calls: --=== ;=== In: A === ;=== Out: sbuf === ;============================================================================== EnviaByte: mov sbuf,A ; Envia Byte contido no acumulador pela serial LoopEnviaByte: jnb TI,LoopEnviaByte ; Espera até SBuf esvaziar , ou seja TI=1 clr TI ; Habilita TI para a nova tranmissão ret ;============================================================================== ;=== Sub-rotinas: 1 - Inicia_LCD === ;=== 2 - Escreve_2000 === ;=== 3 - LoopEscreve_1200 === ;=== 4 - Escreve_40 === ;=== 5 - EscreveLinha1_LCD === ;=== 6 - EscreveLinha2_LCD === ;=== 7 - LimpaLinha1_LCD === ;=== 8 - LimpaLinha2_LCD === ;=== 9 - Deliga_LCD === ;=== Information: 1 - Inicializa o LCD === ;=== 2 - Escreve no LCD com o tempo de 1.7ms === ;=== 3 - """" === ;=== 4 - Escreve no LCD com o tempo de 40us === ;=== 5 - Aponta o dado p/ 1a posicao linha 1 no LCD === ;=== 6 - Aponta o dado p/ 1a posicao linha 2 no LCD === ;=== 7 - Limpa a linha 1 do LCD === ;=== 8 - Limpa a linha 2 do LCD === ;=== 9 - Desliga o LCD === ;=== Destroys: Porta_LCD, R2, R3, DPTR === ;=== Calls: ModoInstrucao === ;=== ModoDado === ;=== Habilita_LCD === ;=== Escreve_2000 === ;=== Escreve_40 === ;=== In: --=== ;=== Out: Porta_LCD === ;============================================================================== Inicia_LCD: mov A,#38h ; Subrotina de config do lcd call EscrevaInstrucao_LCD call Tempo_LCD mov A,#38h ; ( Verificar manual e alterar call EscrevaInstrucao_LCD ; conforme o tipo de LCD ) call Tempo_LCD mov A,#06h call EscrevaInstrucao_LCD call Espera_LCD mov A,#0Eh ; Cursor inativo 102 call EscrevaInstrucao_LCD call Espera_LCD mov A,#01h ; Limpa display call EscrevaInstrucao_LCD call Espera_LCD ret ;============================================================================== Tempo_LCD: mov DPTR,#15536 mov TH0,DPH mov TL0,DPL setb TR0 jnb TF0,$ clr TR0 clr TF0 ret ;============================================================================== Espera_LCD: call LeiaInstrucao_LCD rlc A jc Espera_LCD ret ;============================================================================== EscrevaInstrucao_LCD: mov DPTR,#End_EscrevaInstrucao_LCD movx @DPTR,A ret ;============================================================================== EscrevaDado_LCD: mov DPTR,#End_EscrevaDado_LCD movx @DPTR,A call Espera_LCD ; Espera o dado ser escrito no LCD ret ;============================================================================== LeiaInstrucao_LCD: mov DPTR,#End_LeiaInstrucao_LCD movx A,@DPTR ret ;============================================================================== LeiaDado_LCD: mov DPTR,#End_LeiaDado_LCD movx A,@DPTR ret ;============================================================================== ;=== Sub-rotinas: 1 - EscreveEstatico_LCD === ;=== 2 - LoopEscreveEstatico_LCD === ;=== 3 - ContLoopEscreveEstatico_LCD === ;=== Information: 1 - Escreve tela padrao no LCD === ;=== 2 - """" === ;=== 3 - """" === ;=== Destroys: A, R7, DPL, DPH, (DPTR) === ;=== Calls: EscreveDado_LCD, Espera_LCD === ;=== In: Var_DPTR_Low, Var_DPTR_High === ;=== Out: --=== ;============================================================================== EscreveEstatico_LCD: mov Var_DPTR_Low,DPL ; O endereco apontado por DPTR é armaz mov Var_DPTR_High,DPH ; para uso na subrotina mov R7,#0FFh LoopEscreveEstatico_LCD: inc R7 ; Registrador que armaz a posicao da pilha mov A,R7 ; A recebe o registrador mov DPL,Var_DPTR_Low ; DPL recebe a parte baixa do end da pilha mov DPH,Var_DPTR_High ; DPH recebe a parte alta do end da pilha movc A,@A+DPTR ; A recebe o byte armaz na pilha cjne A,#0FFh,ContLoopEscreveEstatico_LCD ; Comp se fim da pilha ret 103 ContLoopEscreveEstatico_LCD: call EscrevaDado_LCD ; Escreve o dado no LCD jmp LoopEscreveEstatico_LCD ;============================================================================== EscreveLinha1_LCD: mov A,#80h ; Primeira posicao da Linha 1 lcall EscrevaInstrucao_LCD ; Escreve no LCD lcall Espera_LCD ; Espera até escrever no LCD ret ;============================================================================== EscreveLinha2_LCD: mov A,#0C0h ; Primeira posicao da Linha 2 lcall EscrevaInstrucao_LCD ; Escreve no LCD lcall Espera_LCD ; Espera até escrever no LCD ret ;============================================================================== LimpaLinha1_LCD: lcall EscreveLinha1_LCD ; Vai para a primeira linha no LCD mov DPTR,#LimpaLinha lcall EscreveEstatico_LCD lcall Espera_LCD ; Espera até escrever no LCD ret ;============================================================================== LimpaLinha2_LCD: lcall EscreveLinha2_LCD ; Vai para a segunda linha no LCD mov DPTR,#LimpaLinha lcall EscreveEstatico_LCD lcall Espera_LCD ; Espera até escrever no LCD ret ;============================================================================== Espaco_LCD: mov DPTR,#Espaco lcall EscreveEstatico_LCD lcall Espera_LCD ; Espera até escrever no LCD ret ;============================================================================== Desliga_LCD: lcall Inicia_LCD mov A,#00Ch ; Desliga o display lcall EscrevaInstrucao_LCD lcall Tempo_LCD ; Escreve no LCD ret ;============================================================================== ;=== Sub-rotinas: 1 - EscreveEstatico_LCD === ;=== 2 - LoopEscreveEstatico_LCD === ;=== 3 - ContLoopEscreveEstatico_LCD === ;=== Information: 1 - Escreve tela padrao no LCD === ;=== 2 - """" === ;=== 3 - """" === ;=== Destroys: A, R7, Porta_LCD, DPTR === ;=== Calls: Escreve_40 === ;=== In: DPTR === ;=== Out: Porta_LCD === ;============================================================================== Mensagem_Conectando: db 'Conectando ao PC',0FFh ;============================================================================== MensagemLinha1_Conectado: db 'PC conectado! ',0FFh ;============================================================================== MensagemLinha2_Conectado: db '8051 <------> PC',0FFh ;============================================================================== Mensagem_IniTx2: db '8051 -------> PC',0FFh ;============================================================================== Mensagem_IniRx2: 104 db '8051 <------- PC',0FFh ;============================================================================== MensagemEEE: db 'EEE, ',0FFh ;============================================================================== Mensagem_IniTx: db 'Transmitindo... ',0FFh ;============================================================================== Mensagem_IniRx: db 'Recebendo... ',0FFh ;============================================================================== LimpaLinha: db ' ',0FFh ;============================================================================== Mensagem_FimTx: db 'Fim Transmissao!',0FFh ;============================================================================== Mensagem_FimRx: db 'Fim de Recepcao!',0FFh ;============================================================================== Espaco: db ' ',0FFh ;============================================================================== Ano20: db '20',0FFh ;============================================================================== SimboloHora: db ':',0FFh ;============================================================================== SimboloMinuto: db 39d,0FFh ;============================================================================== SimboloSegundo: db '"',0FFh ;============================================================================== MensagemMatricula_LCD: db 'Matricula ',0FFh ;============================================================================== end