quinta-feira, 6 de janeiro de 2011

Interface com memoria AT24C04 ou AT24C16A;

veja que funciona para qualquer memoria AT24CXX

verifique o datasheet para saber exatamente como acessar a sua memoria (no meu caso depois deste programa de teste usei o AT24C16A e ele possui 8 banco de memoria(que cabe 256 bits ), que são acessados via código pelo endereço (0 a 7),outra curiosidade desta memoria é que ela é organizadas em vetores que cabe 16 bytes cada (veja que no 24C04A são 8 bytes).

O código:

****************************************************************************************************************************************************
// interface com memoria 24C04A
// Data: 06-01-2011
// ultimo acesso : 06-01-2011
// Autor: Aguivone
// Descrição: usa o protocolo I2C para comunicar
// Solução esperada: ler memoria AT24C04A
// versão : 1.0
// ****************************************************************************************************************************************************
#include <16F877A.h>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20M)
#locate rx_reg= 0x1A
#use I2C(master, scl=PIN_C3, sda=PIN_C4)//para a memoria
////////////////////////////////variaveis do I2C //////////////////////////////////
#define MEMO_Ende_escrita 0xA0 //o endereço da memoria é 0 (pois é só uma)
#define MEMO_Ende_leitura 0xA1 //o endereço da memoria é 0 (pois é só uma)
#define protege_escrita output_high(PIN_C5);//WP só permite leitura
#define permite_escrita output_low(PIN_C5);//WP permite leitura e escrita
////////////////////////////////////////////////////////////////////////////////////
char teste[11],sequencia[11],teste3[10];

////////////////////////// Funções I2C ////////////////////////////////////////

// escreve 1 byte ----------------------------------------------
void MEMO_escreve_byte(int8 endereco, int8 dados)
{
permite_escrita
// disable_interrupts(GLOBAL);
i2c_start(); //inicializa a comunicaçao i2c
i2c_write(MEMO_Ende_escrita);
i2c_write(endereco);
i2c_write(dados);
i2c_stop(); //finaliza comunicação
delay_us(1000);//tempo necessario antes de uma nova escrita
// enable_interrupts(GLOBAL);
protege_escrita
}

// lê um byte ----------------------------------------------
int MEMO_ler_byte(int endereco)
{
int lido;
//disable_interrupts(GLOBAL);
i2c_start();
i2c_write(MEMO_Ende_escrita);
i2c_write(endereco);
i2c_start();
i2c_write(MEMO_Ende_leitura);
lido = i2c_read(0);//ler sem ack =0 , ler com ack = 1
i2c_stop();
// enable_interrupts(GLOBAL);
return(lido); //retorna o valor lido
}
void MEMO_escreve_seq(int8 endereco, char *dados[11],int max_dados)
{
int temp;
permite_escrita
// disable_interrupts(GLOBAL);
i2c_start(); //inicializa a comunicaçao i2c
i2c_write(MEMO_Ende_escrita);
i2c_write(endereco);
delay_us(20);//tempo necessario antes de uma nova escrita
if(max_dados > 7)
{
max_dados = 7;
}
for(temp = 0; temp <= max_dados; temp++)
{
i2c_write(dados[temp]);
}
i2c_stop(); //finaliza comunicação
// enable_interrupts(GLOBAL);
protege_escrita
}
void MEMO_ler_seq(int endereco,int max_dados)
{
int temp;
for(temp = 0; temp <= max_dados; temp++)
{
sequencia[temp] = MEMO_ler_byte(temp+endereco);
}


}

/////////////////////////////////////////////////////////////////////////////////
void main()
{
SET_TRIS_C(0X10);
protege_escrita
MEMO_escreve_byte(0X01,'A');
MEMO_escreve_byte(0X02,'B');
MEMO_escreve_byte(0X03,'C');
teste3[0]=MEMO_ler_byte(0X01);
teste3[1]=MEMO_ler_byte(0X02);
teste3[2]=MEMO_ler_byte(0X03);
teste[0]='1';
teste[1]='2';
teste[2]='3';
teste[3]='4';
teste[4]='5';
teste[5]='6';
teste[6]='7';
teste[7]='8';
MEMO_escreve_seq(0X00,teste,7);//escreve 10 bytes ,numa sequencia que inicia no endereço 0X20
MEMO_ler_seq(0X00,7);//escreve 10 bytes ,numa sequencia que inicia no endereço 0X20
//veja que o vetor maximo no 24C08 é de 8 bytes e no 24C16 é de 16bytes
// veja agora que teste3 é igual a A B C
// sequencia é igual a 1 2 3 4 5 6 7 8 .
for(;;)
{

}//fim do for
}//main

Esquema no simulador :