i2c eeprom

Ola pessoal,
Será que alguem tem um exemplo da utilizacao de uma eeprom por i2c em c keil...
Obrigado.
Eduardo.
Será que alguem tem um exemplo da utilizacao de uma eeprom por i2c em c keil...
Obrigado.
Eduardo.
Fórum sobre desenvolvimento de sistemas embarcados: Hardware e Software, Tecnologias: Eletrônica digital e analógica, Microcontroladoras, Microprocessadores, Sistemas *NIX (Linux, BSD), Software embarcado Baremetal. Sem fins lucrativos.
http://www.asm51.com.br/phpbb/
/*********************************************************************/
/* 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);
};
}
/***********************************
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;
}
}
}