|
|
View previous topic :: View next topic |
Author |
Message |
young
Joined: 24 Jun 2004 Posts: 285
|
external eeprom w/r speed. |
Posted: Tue Nov 16, 2004 2:22 pm |
|
|
I am using a 24fc515 eeprom, according my program, I find out the it meed about 5 minutes to write to the whole eerpom space. do you it is about 218-273byte/s. I think it might be slow, but I do not know exactly how fast it could be. could anybody tell me how the speed usually be? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Nov 16, 2004 2:29 pm |
|
|
Read the datasheet. Maximum write time is 5ms. You can write byte by byte so 64K * 5ms which is over 5 minutes or you can do page writes which will take you about 5 seconds. |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Tue Nov 16, 2004 2:40 pm |
|
|
thank you, as you said I am writing byte by byte, which is about 5 minutes. How could I write it page by page? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Nov 16, 2004 2:43 pm |
|
|
Instead of just sending it 1 byte, send it 64 bytes. The address must be page aligned or the index pointer will wrap and overwrite the wrong location. Read the datasheet and it will make more sense. |
|
|
young
Joined: 24 Jun 2004 Posts: 285
|
|
Posted: Tue Nov 16, 2004 2:56 pm |
|
|
Thank you, I am studying the datasheet right now, by the way, would you please check and correct what I am doing wrong with my page wrting coding
Code: |
void write_ext_eeprom(int32 pages, BYTE data)
{
short int status,eeprnum;
long int quotient, remainder;
i2c_start();
if(pages*64<0x8000)
i2c_write(0xa0);
else
i2c_write(0xa8);
for(i=0;i<64;i++)
{
i2c_write((pages*64+i>>8) & 0xFF);
i2c_write(pages*64+i & 0xFF);
i2c_write(data);
i2c_stop();
i2c_start();
if(pages*64+i<0x8000)
status=i2c_write(0xa0);
else
status=i2c_write(0xa8);
while(status==1)
{
i2c_start();
if(pages*64+i<0x8000)
status=i2c_write(0xa0);
else
status=i2c_write(0xa8);
}
}
} |
|
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Tue Nov 16, 2004 7:19 pm |
|
|
Code: | void write_ext_eeprom(int32 pages, BYTE *data)
{
int i;
i2c_start();
if(pages*64<0x8000)
i2c_write(0xa0);
else
i2c_write(0xa8);
i2c_write((pages*64+i>>8) & 0xFF);
i2c_write(pages*64+i & 0xFF);
for(i=0;i<64;i++)
i2c_write(data++);
i2c_stop();
} |
_________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Wed Nov 17, 2004 12:23 pm |
|
|
If you need speed, on a byte by byte basis,.. check out the fram.
It is very fast. and may fit right into your 8 pin socket of the serial eprom.
I use a FM24C04 from ramtron hooked to the i2C bus like the serial eprom would be. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Nov 17, 2004 12:39 pm |
|
|
He also does not check to see if the device is ready before blasting it with more data. He should fix this or probably get by with the FRAM since it is so fast. |
|
|
Guest
|
|
Posted: Fri Nov 19, 2004 10:57 am |
|
|
I changed the program posted by asmalli a little, because I thought some place is not proper. however, I could not run the program, please check it and provide some advice please.
Code: |
void write_ext_eeprom(int32 pages, BYTE data)
{
int i;
i2c_start();
if(pages*64<0x8000)
i2c_write(0xa0);
else
i2c_write(0xa8);
i2c_write((pages*64>>8) & 0xFF);
i2c_write(pages*64 & 0xFF);
for(i=0;i<64;i++)
i2c_write(data);
i2c_stop();
} |
init_eeprom();
for(i=0;i<1024;i++)
write_ext_eeprom(i,0); |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Nov 19, 2004 11:26 am |
|
|
Bug:
- Data must be a pointer! Or how are you otherwise going to access the data in the buffer?
- You never adjust the contents of Data, so writing the same value everytime.
Also some optimizations possible:
- Using an int32 for Page is a waste of memory.
- You are 3 times calculating 'pages*64'. Better to do it once.
- make8(var, offset) is just a single byte move instruction and much faster than (((var >> (offset*8)) & 0xff)
Code: | void write_ext_eeprom(int32 pages, BYTE *data)
{
int i;
int16 StartAddr;
StartAddr = pages * 64;
i2c_start();
if (StartAddr < 0x8000)
i2c_write(0xa0);
else
i2c_write(0xa8);
i2c_write( make8(StartAddr,1) );
i2c_write( make8(StartAddr,0) );
for(i=0;i<64;i++)
i2c_write(data++);
i2c_stop();
} |
I haven't tested the above. |
|
|
Guest
|
|
Posted: Fri Nov 19, 2004 11:59 am |
|
|
I tested your program, same thing, the program could not work |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Nov 19, 2004 12:25 pm |
|
|
Quote: | I tested your program, same thing, the program could not work |
You have to call the function correctly as well. You really should post a small test program. |
|
|
Guest
|
|
Posted: Fri Nov 19, 2004 1:14 pm |
|
|
Following is the code, I made two sub routine fro external eeprom, one is for singal data write write_ext_eeprom(), one is for pages write write_ext_eeprom1(). I want to initialize the external eeprom as zero in the int_rda, with write_ext_eeprom(), it works fine but take abi\out 5 minutes with write_ext_eeprom1(), it is not working.
Thank you.
Code: |
#if defined(__PCM__)
#include <16F76.h>
#include <stdio.h>
#fuses XT,WDT,NOPROTECT
//#device ADC=10
#use delay(clock=4000000)
#use rs232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7)
#ifndef EEPROM_SDA
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#endif
#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 65536
int8 frequency,i, length,data[64];
int32 j=0, danum=0;
char b, status, status1[10];
void init_ext_eeprom()
{
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
void write_ext_eeprom(int32 address, BYTE data)
{
short int status,eeprnum;
long int quotient, remainder;
i2c_start();
if(address<0x8000)
i2c_write(0xa0);
else
i2c_write(0xa8);
i2c_write((address>>8) & 0xFF);
i2c_write(address & 0xFF);
i2c_write(data);
i2c_stop();
i2c_start();
if(address<0x8000)
status=i2c_write(0xa0);
else
status=i2c_write(0xa8);
while(status==1)
{
i2c_start();
if(address<0x8000)
status=i2c_write(0xa0);
else
status=i2c_write(0xa8);
}
}
//write in pages to external eeprom
void write_ext_eeprom1(int16 pages, BYTE *data)
{
int16 StartAddr;
short int status;
StartAddr = pages * 64;
i2c_start();
if (StartAddr < 0x8000)
i2c_write(0xa0);
else
i2c_write(0xa8);
i2c_write( make8(StartAddr,1) );
i2c_write( make8(StartAddr,0) );
for(i=0;i<64;i++)
i2c_write(data++);
i2c_stop();
}
BYTE read_ext_eeprom(int32 address)
{
BYTE data;
long int quotient, remainder;
i2c_start();
if(address<0x8000)
i2c_write(0xa0);
else
i2c_write(0xa8);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
if(address<0x8000)
i2c_write(0xa1);
else
i2c_write(0xa9);
data=i2c_read(0);
i2c_stop();
return(data);
}
#int_rda
void RDA_isr()
{
gets(status1);
status=status1[0];
if(status=='R')
{
for(j=0;j<64;j++)
data[j]=0;
for(j=0;j<1023;j++)
{ write_ext_eeprom1(j,data);
}
}
void main()
{
int8 temperature,humidity,tilt, write_read;
int16 total;
int i,SleepCount=0;
setup_port_a(AN0_AN1_AN3);
setup_adc( ADC_CLOCK_INTERNAL );
set_tris_a(0xFF); //set ccp1 pin as low as output ccp1 pin is b2
enable_interrupts(INT_RDA);
enable_interrupts(global);
init_ext_eeprom();
while(1)
{
}
}
|
|
|
|
Guest
|
|
Posted: Fri Nov 19, 2004 1:25 pm |
|
|
in the int_rda subroutine;
if I changed to
Code: |
#int_rda
void RDA_isr()
{
gets(status1);
status=status1[0];
if(status=='R')
{
for(j=0;j<64;j++)
data[j]=0;
write_ext_eeprom1(1023,data);
}
it still could work, the problem seems like the for loop, but I did not see any problem of the for loop, please help |
|
|
|
Guest
|
|
Posted: Fri Nov 19, 2004 1:35 pm |
|
|
if I put the for loop as
for(j=0;j<1023;j++)
{ output_high(PIN_A2);
delay_ms(200);
output_low(PIN_A2);
delay_ms(200);
write_ext_eeprom1(j,data);
}
the led just blink a few times, then stop looping. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|