BANCO DE MEMÓRIA EXTERNO PARA MICROCONTROLADORES
memo_UC


O artigo a seguir foi publicado na revista Eletrônica Total nr126 de Setembro/Outubro de 2007. Na época eu projetei esse banco para ser utilizado com microcontroladores que possuíam pouca ou nenhuma memória EEPROM como a linha PIC16F6XX da Microchip® e outros. Hoje em dia temos microcontroladores com bastante memória FLASH, mas alguns deles sem nenhuma memória EEPROM e para estes a solução é na maioria dos casos usar parte dessa memória para dados, "simulando" uma EEPROM. Porém isso nem sempre é o melhor dos mundos e no meu caso, em um projeto recente, isso mostrou-se impossível já que toda a área da FLASH estava sendo ocupada pelo programa.

Pensando nisso, percebi que esse antigo projeto, hoje pode se mostrar uma "mão na roda" para o desenvolvedor. O artigo será aqui descrito tal qual publiquei na época, mas com pequenas adaptações você poderá usar essa placa com um microcontrolador de 32 bits como o STM32F103C6T8 (Blue Pill) e no banco memórias com mais de 32kBytes.


A PROPOSTA

Quantas vezes o hobista ou estudante de eletrônica que gosta de desenvolver suas próprias soluções não se deparou com a necessidade de coletar alguns dados vindos de sensores e outros através de um circuito microcontrolado? E quantas não foram as vezes onde se fazia necessário guardar estas informações para posteriormente processá-las?

Pensando nisso, desenvolvi o circuito que será apresentado neste artigo. Ele permite preparar um pequeno banco de memória EEPROM com mais 2 kBytes! Este tamanho pode ser estendido com a alteração de alguns componentes e do programa de controle.

Para muitos usuários 2 kBytes de memória EEPROM pode parecer pouco, mas se levarmos em conta que muitos microcontroladores de 8 bits possuem memória EEPROM interna da ordem de 128 Bytes como, por exemplo, o PIC16F628A Microchip®, os 2 kBytes propostos são bem mais interessantes.

As sugestões de uso para um banco externo como o proposto neste artigo são ilimitadas. Tudo dependera da criatividade de cada um. Como exemplo, podemos citar algumas aplicações que podem fazer uso do banco de memória memo_uC. São elas:

    • Aplicação em um data logger;
    • Mini-servidor web (para guardar a página e outros dados);
    • Relógio de ponto eletrônico;
    • Mini-terminal de dados stand alone (operação off-line);
    • etc.

Como dito anteriormente, o limite para a aplicação do circuito proposto depende apenas da criatividade e conhecimentos de cada um.


COMUNICAÇÃO I2C

O protocolo I2C (Inter-Integrated Circuit) é do tipo serial síncrono e foi desenvolvido originalmente pela Phillips® em meados da década de 1990. Atualmente ele está presente em uma série de dispositivos eletrônicos e componentes dos mais variados tipos como: microcontroladores, controladores de LCD, memórias, dispositivos de I/O, relógios de tempo real (RTC), entre outros.

As vantagens deste tipo de comunicação são muitas e dentre elas podemos citar:

    • Barramento de simples controle: mestre / escravo (Master/Slave) com endereçamento resolvido via software ou hardware;
    • Interface de comunicação interna ao dispositivo o que facilita o uso dos dispositivos;
    • Permite a ligação de dispositivos com tensões de alimentação diferentes graças as vias de comunicação tipo open drain;
    • Excelente taxa de comunicação (velocidade): 100 kbps no modo Standart, 400 kbps no modo Fast e até 3.4 Mbps no modo High Speed;
    • Modo de comunicação síncrono o que permite que dispositivos de velocidades diferentes sejam conectados ao mesmo barramento usando a taxa de comunicação do dispositivo de menor velocidade;
    • Boa imunidade a ruídos elétricos;
    • Flexibilidade no barramento para inclusão ou exclusão de um dispositivo escravo sem afetar os demais de mesma natureza;
    • etc.

Porém nem tudo “são flores” e o padrão I2C também possui algumas desvantagens:

    • Número de dispositivos ligados a um mesmo barramento limitados a 128 dispositivos no modo normal (7 bits para endereçamento) ou 1024 dispositivos no modo estendido (10 bits no endereçamento);
    • O barramento, devido às suas características elétricas, não pode percorrer grandes distâncias ficando estas limitadas ao circuito principal. O barramento deve ser utilizado para comunicação entre dispositivos inseridos internamente em um equipamento e nunca externamente (em alguns casos está regra pode ser quebrada, desde que o cabo/conexão e a distância sejam pequenas: > 2 metros);
    • Devido ao modo de comunicação mestre / escravo a rede não pode ser compartilhada com vários dispositivos se comunicando ao mesmo tempo. Toda e qualquer comunicação é sempre feita entre o mestre e o escavo, sendo está iniciada sempre pelo dispositivo mestre

Apesar disso, o protocolo I2C é excelente para uso na comunicação entre dispositivos como um microcontrolador (elemento mestre) e alguns dispositivos como: memórias, RTCs, controladores de I/O, etc (dispositivos escravos). Fica óbvio que a realização do projeto será simplificada pois o padrão de comunicação entre os vários dispositivos será o mesmo e o barramento usado também. A figura abaixo demonstra um exemplo típico de aplicação I2C.


A comunicação I2C usa duas vias de comunicação tipo open drain: Dados (SDA) e Clock (SCL). A via SDA é bidirecional e serve para a troca de dados seriais entre o dispositivo mestre e o dispositivo escravo. A via SCL é usada para sincronismo (clock de comunicação) entre os dispositivos mestre e escravo e é sempre controlada pelo dispositivo mestre. A figura abaixo mostra o diagrama de tempos padrão para a comunicação I2C.


Observando a figura acima você pode perceber que existe um procedimento de comunicação bastante simples no protocolo I2C:

    • O dispositivo mestre inicia a comunicação (SDA em nível lógico “1” e SCL em nível lógico “0”);
    • O dispositivo mestre envia os bits de endereçamento. Todos os dispositivos escravos recebem, mas apenas o dispositivo escravo que possui o endereço enviado responderá;
    • O dispositivo mestre envia o bit de comando – escrita ou leitura;
    • O dispositivo escrava retorna através da via SDA o sinal de ACK (Acknowledge);
    • O dispositivo mestre ou escravo (dependendo da operação – escrita ou leitura) envia pacotes de 8 bits de dados, que serão sempre seguidos de um sinal ACK enviado pelo dispositivo que aguarda os dados (escravo ou master);
    • O dispositivo mestre encerra a comunicação (SDA e SCL em nível lógico “1”).


Você deve ter em mente que os dispositivos I2C possuem funções diferentes e sendo assim, o modo de operá-los também é diferente. O protocolo é valido apenas para a padronização da comunicação no barramento. O uso de cada dispositivo pode depender do acesso a registros internos com envio de comandos específicos. A forma de comunicação já foi demonstrada, mas cabe ao desenvolvedor estudar cada um dos dispositivos que irá usar. Para isso basta ler atentamente os datasheets e notas de aplicações de cada componente. Estas informações estão sempre presentes no site do fabricante! Use-as sempre!


CIRCUITO E FUNCIONAMENTO


A figura acima traz o circuito elétrico do banco de memória externo memo_uC. Ele apresenta oito memórias EEPROM AT24C01A ATMEL (CI1 a CI8). Cada uma destas memórias pode armazenar 1 kbit ou 128 bytes (1024/8). Como temos oito memórias, podemos afirmar que o banco tem capacidade de armazenamento igual a 1 kByte (128 x 8). Se utilizarmos neste banco, memórias AT24C02A, também da ATMEL, teremos um banco de memória com capacidade máxima de 2 kBytes.

Nota em 2023: Se você utilizar 8 memórias AT24C32 terá um banco com 32kBytes e se usar 8 memórias AT24C64 o mesmo banco passará a ter 64KBytes!!!

C1 a C8 são capacitores de desacoplamento e ajudam a filtrar possíveis ruídos vindos da fonte de alimentação. O capacitor C9 aumenta o nível do filtro da fonte.

O conector JP1 serve para conectar o banco de memória ao circuito principal e possui as duas vias de comunicação I2C (SDA e SCL), um ponto de alimentação +5VDC e um GND (terra).

O LED1 ajuda a demonstrar que o circuito está ligado.R1 é o resistor limitador de corrente para LED1. Esta aparente alegoria tem um simples motivo: como a alimentação pode ser controlada de forma externa (através do circuito principal) e as memórias são do tipo “não voláteis”, é possível utilizar mais de um banco memo_uC num mesmo circuito. Se usarmos, por exemplo, 8 bancos de 2 kBytes teremos um total de 16 kBytes de memória disponíveis.

O LED2 foi inserido no circuito para demonstrar a presença de comunicação entre o banco de memória e o circuito principal. Seu controle é feito através de Q1. Sempre que houver a presença do sinal SCL no barramento e a placa estiver devidamente alimentada (+5VDC), o LED irá piscar  a uma frequência igual a usada no barramento. Na menor velocidade (modo standart) o período será igual a 0,000001 s. A esta velocidade o piscar é quase que imperceptível, e o usuário terá apenas a impressão do LED estar simplesmente ligado. R2 é o resistor de polarização de base para Q1 (que controla LED1). O resistor R3 mantém o transistor Q1 em corte, e consequentemente LED2 apagado, quando o sinal SCL não estiver presente.

Os resistores de pull-up necessários as vias de comunicação SDA e SCL, pois estas são do tipo open drain, não estão presentes na placa, mas são necessários e devem ser previstos no projeto do circuito principal que fará uso do memo_uC.


MONTAGEM



A figura acima mostra minha sugestão do lay-out para a confecção de um circuito impresso. Este foi o desenho usado em meu protótipo. Você se preferir poderá montar o banco em uma placa do tipo padrão ou ainda em uma matriz de contatos. A escolha é livre.

Comece por soldar os resistores R1, R2 e R3. Os mesmos não são polarizados e não requerem preocupação maior ao montá-los na placa. Apenas tome cuidado para não trocá-los entre si, já que suas resistências são diferentes. Caso tenha dúvida use a lista de materiais para identificá-los.

Os capacitores C1 a C8 são cerâmicos e também não são polarizados. Todos possuem o mesmo valor e você não terá dificuldades em sua montagem na placa. O capacitor C9 é do tipo eletrolítico e polarizado. Tenha cuidado para não montá-lo invertido na placa.

O transistor Q1 também requer um maior cuidado para não montá-lo invertido. LED1 e LED2 também precisam do mesmo cuidado. Como sugestão é interessante que LED1 seja vermelho e LED2 verde, por exemplo. Com cores diferentes fica mais fácil identificar como a placa está sendo operada.

Os CIs também são polarizados e merecem todo cuidado na sua inserção na placa. O uso de suportes para os mesmos é altamente recomendável, pois facilita a conexão dos CIs de maneira segura e rápida.

O conector JP1 usado em nosso protótipo é do tipo “barra de pinos”. Caso você não o tenha em mãos poderá usar fios para conectar a placa ao seu circuito principal.


UM CIRCUITO AUXILIAR PARA TESTES

Para poder testar o memo_uC eu desenvolvi um pequeno circuito  para uso com a placa, presente na figura abaixo. A ideia é interagir com o banco de memória memo_uC através do canal serial de um PC, usando um microcontrolador PIC16F628A como interface entre o PC e o memo_uC.


O circuito de teste basicamente é composto de um microcontrolador PIC16F628A. Escolhi este microcontrolador para os testes por acreditar (na época - 2007) ser este um dos mais difundidos , porém nada impede que cada um faça os seus testes utilizando seu microcontrolador preferido.

O LED presente no circuito é apenas uma alegoria que ajuda a informar que o circuito está em operação, pois o mesmo pisca a uma frequência de 1 Hz. O MAX232 faz a conversão dos níveis de tensão presentes na porta RS-232 de um PC para o padrão TTL presente nos pinos de I/O do microcontrolador ligados a sua USART interna e vice-versa. Aconselho a montagem do circuito em uma matriz de contados, já que o mesmo é apenas para testes.



PROGRAMA PARA O CIRCUITO AUXILIAR

Mais abaixo em "downlods" disponibilizei o programa original memo_crtl_24c01.c desenvolvido na linguagem C. Utilizei para montagem e compilação deste exemplo o compilador PICC CCS (http://www.ccsinfo.com). A empresa CCS fornece uma versão demo que poderá ser utilizada por você em seus testes. Esta versão possui algumas limitações como os tipos de microcontroladores habilitados e também no tamanho máximo do programa a ser compilado, porém é uma boa alternativa para aqueles que desejam “entrar” no mundo da programação na Linguagem C, mais especificamente dedicada aos microcontroladores PIC Microchip.

É importante compreender que você não precisa compilar o código fornecido para realizar os seus testes, conforme proposto. Junto ao código fonte você encontrará o arquivo memo_crtl_24c01.hex que poderá ser utilizado para gravar o microcontrolador de forma direta, sem a necessidade de uma re-compilação. O uso do compilador só será necessário se você desejar alterar o programa fornecido.

Nota: Eu teno o hábito de inserir linhas de comentários em meus programas no intuito de ajudar na compreensão do mesmo. Estas linhas devem ser lidas atentamente por quem deseja utilizar tais códigos fontes. Elas contem informações sobre a versão do compilador e pinos de I/O utilizados, além de detalhes a respeito do funcionamento das funções presentes no código, entre outras. Ao estudar um código fonte meu, use as linhas de comentários!


O programa foi ricamente comentado, para ajudar na sua compreensão. Porém a seguir falareis um pouco sobre o seu funcionamento, descrevendo as operações mais importantes do programa.

Um detalhe a ser comentado sobre este programa é o uso da biblioteca 24C01.c, fornecida pela CCS no pacote do compilador (..\PICC\Drivers\24C01.c). Junto ao código fonte fornecido mais abaixo você encontrará a mesma, devidamente adaptada (foram inseridos cabeçalhos explicando o funcionamento de cada função para auxiliar o estudo das mesmas por parte de você).

Na figura abaixo temos o fluxograma que descreve a operação do programa desenvolvido para o exemplo proposto neste artigo.



O programa começa configurando o microcontrolador, definindo o modo de uso dos pinos (entrada ou saída), o tempo para o WDT (Watch Dog Timer - relógio cão de guarda que evita que o programa se perda e assim que o microcontrolador trave por algum motivo), a configuração do Timer1 (interrupção responsável pelo “piscar” do LED) e a habilitação da USART do microcontrolador (com interrupção para recepção dos dados através da RS-232).

Após a configuração do microcontrolador, o programa configura as portas de comunicação com as memórias EEPROM. As funções de controle para as memórias foram aproveitados de uma biblioteca do próprio CCS-C (compilador selecionado para os testes). O módulo 24C01.c sofreu apenas algumas modificações para se adequar ao funcionamento com o memo_uC e recebeu também comentários em nossa língua para facilitar a compreensão dvocê. O estudo deste arquivo é recomendável avocê que quer saber como a comunicação entre o microcontrolador em questão e as memórias é feita.

As operações mais importantes do programa são tratadas através de interrupções. Uma destas operações é realizada pelo Timer1 do microcontrolador. Este temporizador gera uma interrupção no microcontrolador a cada 0,526 segundos (com clock operando a 4MHz). Quando isso acontece a função trata_int_t1() é chamada. Esta função verifica quantas interrupções aconteceram: se duas (2 x 0,526 = 1,052 segundos) a função troca o estado atual do LED, fazendo-o piscar na freqüência de 1 Hz.

Temos no programa também a interrupção para tratamento de um dado qualquer recebido do PC. você notará que sempre que um dado for recebido, o microcontrolador efetuará a leitura do mesmo e realizará uma ação. Esta tanto pode ser imediata e ligada ao banco memo_uC como também o envio de uma outra mensagem complementar solicitando mais um dado. Estas mensagens basicamente servem como ajuda para o usuário com os comandos que podem ser utilizados.

Temos seis opções válidas:

1 – Seleciona banco (1 a 8): permite selecionar em qual memória (CI1 a CI8) será gravado ou lido um dado;
2 – Apaga banco (1 a 8): permite apagar a memória (CI1 a CI8) selecionada;
3 – Grava dado (endereço): permite gravar um dado no endereço solicitado, dentro do banco previamente selecionado;
4 – Apaga dado (endereço): permite apagar um dado no endereço solicitado, dentro do banco previamente selecionado.
5 – Dump da memória em ASCII: mostra o conteúdo da memória (CI1 a CI8) previamente selecionado, no formato ASCII.
6 - Dump da memória em HEX: mostra o conteúdo da memória (CI1 a CI8) previamente selecionado, no formato hexadecimal.

São duas as interrupções habilitadas no programa. Na linha #priority RDA0, timer inserida no começo do arquivo memo_crtl_24c01.h, definimos qual interrupção tem maior prioridade. No caso definiu-se a interrupção da USART.



TESTE E USO

Para que você possa realizar, com êxito, o teste proposto neste artigo são necessários os seguintes itens:

    • Circuito de testes montado;
    • Microcontrolador devidamente gravado com o programa de teste;
    • Computador Pessoal (PC) com uma porta serial RS-232 disponível;
    • Um cabo de comunicação RS-232 (facilmente encontrado em lojas de informática);
    • Programa Terminal instalado no PC como, por exemplo, o Hyper Terminal do Windows, devidamente configurado para operar com a porta COM livre em seu PC, velocidade de 9600 bps, sem paridade, número de bits de comunicação igual a 8, número de stop bits igual a 1 e nenhum controle de fluxo (9600, n, 8, 1).

Após a montagem de ambos os circuitos (memo_uC e circuito de testes, este último em uma matriz de contatos ou placa padrão), é sempre aconselhável uma minuciosa verificação. Jamais diga a si mesmo “tenho certeza absoluta de que tudo está certo” sem ao menos ter feito uma boa verificação. Cometer enganos é comum e estes podem ser corrigidos antes de qualquer teste, evitando a perda de componentes, tempo e dinheiro. Use o bom senso e sempre verifique suas montagens!

A figura abaixo, mostra a montagem do circuito de testes realizada em uma matriz de contatos, juntamente com a placa memo_uC. Nesta montagem usei também a placa “Conversor RS-232/TTL duplo”, publicada na edição número 116 da revista Eletrônica Total para realizar a comunicação entre o microcontrolador e o PC.



Conecte o cabo descrito anteriormente entre o circuito e seu PC. Rode um programa “terminal” como o Hyper Terminal do Windows®, por exemplo.

Após a configuração do programa terminal, alimente o circuito. O LED deverá piscar na frequência descrita (1 Hz). Neste momento você poderá ver o menu para uso da aplicação conforme descrito anteriormente.
 
Um pequeno teste pode ser feita da seguinte maneira:
  1.   Selecione o banco 2;
  2.   Grave um dado qualquer em um endereço (anote onde o gravou)
  3.   Selecione o banco 1;
  4.   Grave um outro dado em um endereço (anote isto também);
  5.   Selecione novamente o banco 2;
  6.   Faça o dump da memória deste banco;
  7.   Apague o dado no endereço usado;
  8.   Faça um dump novamente;
  9.   Agora selecione o banco 1 e repita as operações 6 a 8.

Se tudo correu bem, você terá conseguido inserir um dado qualquer em um ponto da memória e em seguida verificá-lo através do comando dump. Em seguida o dado foi removido da memória e isto também pôde ser verificado através do comando dump. você também terá comprovado o uso de mais de um banco de memória (CI).

Para aplicar o memo_uC em seus projetos, você terá de desenvolver um programa de controle. Para isto poderá utilizar o código fonte fornecido realizando algumas alterações para que  a adaptação seja feita com sucesso. Deixaremos isso por conta de cada um, já que cada um tem suas próprias necessidades. 

Apenas para exemplificar, vamos supor que uma determinada aplicação precisar guardar dados coletados ao longo do tempo. Estes dados terão de ser armazenados de forma sequencial e assim, a aplicação principal irá encarar o memo_uC como um banco de memória único com tamanho de x Kbytes. Para que isso seja feito este programa terá de guardar em uma memória auxiliar qual CI foi trabalho por último e onde está o último ponto de memória ocupada deste CI. Isto pode ser feito de duas maneiras:

  1.   O programa lê todos os CIs de maneira sequencial até encontrar um byte igual a “FFH” (byte inserido em um endereço vazio na memória);
  2.   O programa usa uma ou mais posições do próprio banco memo_uC (os dois últimos bytes do CI8, por exemplo) para guardar o número do banco e posição de memória usados pela última vez.

Outras formas também podem ser experimentadas. Como dito anteriormente o uso do memo_uC não tem limites. Tudo depende da criatividade e conhecimentos de cada um.


CONCLUSÃO

Com algumas memórias de custo bem acessível é possível montar um banco de memória externo com tamanho adequado para o uso em vários projetos. O uso de memórias seriais com um protocolo de comunicação simples e poderoso como o I2C favorece ainda mais o projeto final. Esperamos ter colaborado com você desenvolvedor, seja este um hobista/estudante ou profissional da área, pois as dicas apresentadas neste artigo são para todos! Bons estudos e testes! Até a próxima!


DOWNLOADS

- Circuito eletrônico
- Lay-out para circuito impresso (método da transferência térmica)
- Lay-out para circuito impresso (método manual)
- Programa de testes (pacote original 2006-2007)
- Lista de materiais



Este projeto foi publicado, com minha autorização, na Revista "Eletrônica Total nr 126" de Setembro/Outubro de 2007.

Especificações:

- Cérebro  - qualquer microcontrolador 
- Memória - até 64KBytes
- Tipo - EEPROM
- Programa - A sua escolha! :P

 




Copyright deste conteúdo reservado para Márcio José Soares e protegido pela Lei de Direitos Autorais LEI N° 9.610, de 19 de Fevereiro de 1998. É estritamente proibida a reprodução total ou parcial do conteúdo desta página em outros pontos da internet, livros ou outros tipos de publicações comerciais ou não, sem a prévia autorização por escrito do autor.