i2c eeprom

Software e Hardware para linha x51

Moderadores: 51, guest2003, Renie, gpenga

i2c eeprom

Mensagempor edusoppa » 26 Out 2006 17:34

Ola pessoal,
Será que alguem tem um exemplo da utilizacao de uma eeprom por i2c em c keil...

Obrigado.

Eduardo.
edusoppa
Nibble
 
Mensagens: 55
Registrado em: 23 Out 2006 15:55

Mensagempor ftegon » 27 Out 2006 06:17

Ola!

Como vovê não especificou qual eeprom serial, segue abaixo um exemplo.

Ate+

cpp code
/*********************************************************************/
/* PROGRAMA I2C.C Fabio Tegon 13/12/1999 */
/* */
/* Funcao: Ler/Escrever eeprom serial 24C04/08 */
/*********************************************************************/
/* Keil C51 , PLACA SBC80C535, 24C04 ATMEL */
/*********************************************************************/
/* Baseado em rotinas de Dmitry Obukhov, dso@usa.net */
/*********************************************************************/
#define SBC80535 1
#if SBC80535
#include <reg515.h>
#else
#include <at892051.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <intrins.h>

#if SBC80535
sbit SCL = P5^0; /* serial clock */
sbit SDA = P5^1; /* serial endereco/dado */
#else
sbit SCL = P1^1;
sbit SDA = P1^0;
#endif

/* 0x02 eeprom 24C04 , 0x0E eeprom 24C08 */
#define PG 0x02


void delay5(void)
{
_nop_(); /* modificado para Keil C51 */
_nop_();
_nop_();
_nop_();
_nop_();
}
/*
This function is hardware depended (CPU speed)
For fast processors you can define a loop
This concrete function written for I8051 on 12MHz (NOP=1uS)
*/


void i2c_start_tx(void)
{
SCL=1;
SDA=1;
delay5();
SDA=0;
delay5();
SCL=0;
}

void i2c_send_ack(void)
{
SDA=1;
SCL=1;
delay5();
SCL=0;
}

unsigned char i2c_read_char(void)
{
unsigned char res=0;
unsigned char cnt;
for ( cnt=0;cnt<8;cnt++ )
{
SDA=1;
SCL=1;
delay5();
res<<=1;
if (SDA) { res |= 0x01; }
SCL=0;
delay5();
}
return res;
}


bit i2c_check_ack(void)
{
SDA=1;
SCL=1;
delay5();
if (SDA)
{
SCL=0;
return 1;
}
SCL=0;
return 0;
}


void i2c_write_char(unsigned char d)
{
unsigned char i;
for (i=0;i<8;i++)
{
SDA=(bit)(d & 0x80);
SCL=1;
delay5();
SCL=0;
d = d << 1;
}
i2c_send_ack();
}

void i2c_stop_tx(void)
{
SDA=0;
delay5();
SCL=1;
delay5();
SDA=1;
}

/* The following two functions are an entry points
* for the external calls */

void WR24C04(unsigned int index,unsigned char content)
{
unsigned char res;
res=(((unsigned char)(index>>7))& PG) | 0xA0;
i2c_start_tx();
//Send control word + page NUM
i2c_write_char(res);
i2c_write_char((unsigned char)(index&0x00FF));
i2c_write_char(content);
i2c_stop_tx();
}

unsigned char RD24C04(unsigned int index)
{
unsigned char res;
//Send control word + page NUM
res=(((unsigned char)(index>>7))& PG) | 0xA0;
i2c_start_tx();
i2c_write_char(res);
i2c_write_char((unsigned char)(index&0x00FF));
i2c_start_tx();
i2c_write_char(res+1);
res=i2c_read_char();
i2c_stop_tx();
return res;
}

void inic_serial()
{
#if SBC80535
EAL = 0;
#else
EA = 0;
#endif

PCON = PCON | 0x40; /* reseta bit SMOD no registro PCON */
/* bit SMOD = 0 sem dobrar a velocidade na serial */
SCON = 0x52; /* canal serial no modo 1 8bits 1stop sem paridade*/
TMOD = 0x20; /* timer 1, no modo 2, 8bits com auto-reload */
TH1 = 0xFD; /* setado para velocidade de 9600 bps */
#if SBC80535
EAL = 1;
#else
EA = 1; /* habilita escolha de interrupcoes */
#endif
TR1 = 1; /* liga timer 1 para clock do canal serial */
}

main() {

int i,endereco;
unsigned char dado;
inic_serial();



while(1) {
dado = 0xbb;
endereco = 100;

WR24C04(endereco,dado);
for(i=0;i < 10000; i++) {
P4 = 0x00;
delay5();
delay5();
delay5();
P4 = 0xFF;
delay5();
delay5();
delay5();
}

dado = 0;
dado = RD24C04(endereco);
printf("valor gravado %d\n",(int)dado);


};
}
ftegon
Bit
 
Mensagens: 36
Registrado em: 13 Out 2006 09:05

Mensagempor edusoppa » 27 Out 2006 14:08

Ola amigo,
Olha eu ate consegui simular no proteus o codigo que eu fiz, mas quando eu gravo no 89s52 e tento ele soh mostra FF no port que eu estou mostrando a informacao.
Estou passando o meu codigo para voce ver se podeme ajudar. obrigado. ah eu estou usando uma 24c64..., mas no projeto final usarei uma 24c01.
cpp code
/***********************************
I2c.h
***********************************/

// I2C.H

// esta biblioteca é para o i2c generico, para todos os dispositivos
// que usem este tipo de protocolo!
// qualquer duvida verificar o progama at24c04.c

#include <intrins.h>

#define SCL P1_5 // se estes pinos não estiverem definidos no
// progama principal serão definidos este pinos
// como padrão

#define SDA P1_6


/* ******************************************************** */
/* ******************************************************** */
void i2c_delay(void)
{
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();

}

void i2c_start(void)
{
/* Force defined state of SCL and SDA*/
SCL = 1; /* Release SCL */
SDA = 1; /* Release SDA */
i2c_delay(); /* Force 5µs-delay */

/* Generate START condition */
SDA = 0;
i2c_delay(); /* Force 5µs-delay */
SCL = 0;


}

void i2c_stop(void)
{

SDA = 0;
i2c_delay();
SCL = 1;
i2c_delay();
SDA = 1;
}
/*
void i2c_ack(void) // reconhecimento do mestre
{
// Generate ACK
SDA = 0;
SCL = 1; // Release SCL
while(SCL == 0); // Synchronize clock
i2c_delay(); // Force 5µs-delay
SCL = 0; // Force a clock cycle
}

void i2c_nack(void) // naõ reconhecimento do mestre
{
// Generate NACK
SDA = 1; // Release SDA
SCL = 1; // Release SCL
while(SCL == 0); // Synchronize clock
i2c_delay(); // Force 5µs-delay
SCL = 0; // Force a clock cycle
} */

unsigned char i2c_check(void) // ler o reconhecimento do escravo
{
unsigned char vbit=0;
SDA = 1; /* Release SDA */
i2c_delay();
SCL = 1; /* Release SCL */
i2c_delay(); /* Force 5µs-delay */
if (SDA) /* SDA is high */
{
vbit=1;
i2c_delay();
SCL = 0; /* Force a clock cycle */
i2c_delay();
return(vbit); /* No acknowledge from Slave */
}
else
{
vbit=0;
i2c_delay();
SCL = 0;
i2c_delay();
return(vbit); /* Acknowledge from Slave */
}
}

unsigned i2c_write(unsigned char value)
{
unsigned char counter = 0,reconhece; /* Bitcounter */

for ( counter = 0; counter < 8; counter++ )
{
SDA = ((value&128) >> 7); /* Set SDA to value of MSB */
i2c_delay();
SCL = 1; /* Release SCL */
i2c_delay(); /* Force 5µs-delay */
SCL = 0; /* Force a clock cycle */
value <<= 1; /* Prepare next bit for transmission */
}
reconhece=i2c_check();
return(reconhece);
}

unsigned char i2c_read(void)
{
unsigned char result = 0; /* Returnvalue with read I2C byte */
unsigned char counter = 0; /* Bitcounter */


for ( counter = 0; counter < 8; counter++ )
{
SDA = 1; /* Release SDA */
SCL = 1; /* Release SCL */
while(SCL == 0); /* Synchronize clock */
i2c_delay(); /* Force 5µs-delay */

result <<= 1; /* Shift left the result */

if (SDA) result |= 0x01; /* Set actual SDA state to LSB */
SCL = 0; /* Force a clock cycle */
i2c_delay(); /* Force 5µs-delay */
}

/* ACK or NACK from MASTER must be generated outside this routine */
return(result);
}


/********************************
Modulo.c
*******************************/

#include<regx52.h>
#include<i2c.h>

void escreve_memoria(int endereco,int dado)
{
bit erro =0;
i2c_start();
erro=i2c_write(0xA0);//comando para setar endereco
erro=i2c_write(endereco);//endereco
erro=i2c_write(dado);//dado
if(erro)
{
i2c_stop();
P3_7=1;
}
i2c_stop();
}

int le_memoria(int endereco)
{
int dado;
bit erro = 0;
i2c_start();
erro=i2c_write(0xA0);//comando para setar endereco
erro=i2c_write(endereco);//endereco
i2c_start();
erro=i2c_write(0xA1);//comando para ler dado da memoria.
if(erro)
{
i2c_stop();
P3_7=1;
}
dado=(int)i2c_read();
i2c_stop();
return(dado);
}

void pausa()
{
int i,j;
for(i=0;i<10000;i++)
for(j=0;j<50;j++);
}
void main()
{
int endereco,i;

bit erro;
P1=0;
P3=0;
P2=1;
endereco=1;
P1_7=0;
P2=0;
erro=0;
while(1)
{
if(P1_7 == 1)
{
while(P1_7==1);
//escrever informacao;
for(i=0;i<0x10;i++)
{
escreve_memoria(i,i);
pausa();
P1_1=~P1_1;
}
//ler informacao;
P2=0;
pausa();
pausa();
P2 = le_memoria(0x04);
pausa();
P1_1=~P1_1;
}
}
}
edusoppa
Nibble
 
Mensagens: 55
Registrado em: 23 Out 2006 15:55

Mensagempor ftegon » 27 Out 2006 19:04

Ola!

Como você não especificou qual era a eeprom serial , postei um
código para 24C04 ou 24C08, já utilizo o mesmo há mais de 6 anos.

Quanto a usar o PROTEUS eu tenho pessimas experiencias com o mesmo
principalmente com displays gLCD (T6963C).

Para mim é um software em desenvolvimento (de grande futuro) mas
e ainda muito instavel e pouco confiavel.

Ao inves do PROTEUS , prefiro testar o hardware direto,
ou num protoboard ou numa placa de prototipos.

Se você tiver um analizador lógico , você podera monitorar as
formas de onda nos pinos da eeprom , isso ajuda muito.

O analisador pode ser um desses que utilizam a tela do PC para
display, do tipo bitscope (http://wwww.bitscope.com )pois o clock é relativamente baixo.

Não tenho nada para 24C01, utilizo somente 24C04 para cima
pois o custo de uma 24C01 é praticamente o mesmo
de uma 24C04, (que tem capacidade maior).

Para 24C32_64_128_256_512 as rotinas estão no link

http://www.taylorriver.com/content/view/130/2/#intro

O software é em C para o compilador da RAISONACE, mas
é compativel com o Keil.

OBS: Se você olhar detalhadamente os datasheets há diferenças
um tanto quanto significativas entre uma 24C01 e uma 24C64.

Se você for usar uma 24C01, desenvolva e teste o teu software com
uma 24C01 e não com uma 24C64.


Ate+

Fabio Tegon
ftegon
Bit
 
Mensagens: 36
Registrado em: 13 Out 2006 09:05

to doido, to doido, to doido!

Mensagempor eyegold » 25 Nov 2006 13:01

Olá, Gostaria de saber se vc tem rotina em asm para a 24lc512, pois ja to doido, ja quebrei a cabeça e não consegui botar essa danada pra rodar.
eyegold
Bit
 
Mensagens: 6
Registrado em: 25 Nov 2006 12:50

Mensagempor ftegon » 25 Nov 2006 14:05

Ola!

Em asm para 24LC512 infelizmente não tenho.

Mas no site da atmel tem uma app. note chamada Interfacing AT24CXX serial eeproms with AT89CX051 microcontrolers, juntamente com o código fonte.

O fonte é generico (esta em asm) mas segundo a app. note tambem serve para a AT24C512 e AT24C512B.



a++

Fabio Tegon
ftegon
Bit
 
Mensagens: 36
Registrado em: 13 Out 2006 09:05

Mensagempor Renie » 25 Nov 2006 21:45

Olá pessoALL!

Ha um tempo atrás (acho que já vai fazer aniversário, se não for o segundo!) disponibilizei no meu site um pequeno tutorial sobre I2C,
não tem rotinas nem exemplos, mas....

tem a noção, como funciona, se isso não ajuda, então não precisam de
ajuda, querem pronto! Acho que no ASM51, só conseguirá sem esforço de
um participante novato que ainda não leu mais que 10 post's!
[]'s
Renie
-------------------------------------------------------------------------------------------------------------
Meu velho site com eletrônica praticamente parado http://www.reniemarquet.com
Nosso Blog http://artemadeiraevida.blogspot.com.br
Renie
Word
 
Mensagens: 732
Registrado em: 11 Out 2006 22:35
Localização: RJ - Niterói - Brasil


Voltar para 8051

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x