|
|
View previous topic :: View next topic |
Author |
Message |
Leef_me
Joined: 14 Mar 2006 Posts: 45
|
the timing of writing to the internal eeprom |
Posted: Fri Apr 30, 2010 9:53 pm |
|
|
I am confused about the timing of writing to the internal eeprom, specifically at 16mhz.
I have this code that I am using to get estimates on reading and storing information.
For some reason the timing isn't what I expect it to be.
I have 3 places where I sample Timer1, giving me an idea of how many instructions are executed,
and with a little math how long a section of code may take to execute.
Code: |
@ 16mhz
2 25741
---------------> 22408 5.602 ms ; difference in instruction count & time
1 3333
---------------> 1993 0.498 ms
0 1340
@ 1mhz
2 6421
---------------> 1498 5.9ms
1 4923
---------------> 4596 18.38ms
0 327
|
Can anyone shed light on why the number of instructions executed between time[2] and time[1] is
roughly 10 times greater than between time[1] and time[0] ?
Thank in advance.
Leef_me
edit: added address increment to code
Code: | #include <18F26K20.h>
#device ICD=TRUE
#device adc=16 // this will force the ADC output to be 16 bits wide, left justified
#fuses INTRC_IO
#use delay(clock=1000000)
#use delay(clock=16000000)
void main(void)
{
int8 b0,b1,b2,b3,b4,b5, b6,b7;
int8 x,y;
int16 time[20];
int16 analog_dat, address;
address=0x0000;
y=0;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN0|sAN1|sAN2|sAN4|VSS_VDD);
setup_timer_1 ( T1_INTERNAL);
set_timer1(0L);
for (x=0; x<15;x++)
{
time[0]=get_timer1();
set_adc_channel(0); //the next read_adc call will read channel 0
analog_dat=read_adc(); //starts the conversion and reads the result
b0=make8(analog_dat,1);
b1=make8(analog_dat,0);
set_adc_channel(0); //the next read_adc call will read channel 0
analog_dat=read_adc(); //starts the conversion and reads the result
b2=make8(analog_dat,1);
b3=make8(analog_dat,0);
set_adc_channel(0); //the next read_adc call will read channel 0
analog_dat=read_adc(); //starts the conversion and reads the result
b4=make8(analog_dat,1);
b5=make8(analog_dat,0);
address=0; // eeprom starting address
write_eeprom(address,b0);
write_eeprom(address+1,b1);
write_eeprom(address+2,b2);
write_eeprom(address+3,b3);
write_eeprom(address+4,b4);
write_eeprom(address+5,b5);
time[1]=get_timer1();
set_adc_channel(1); //the next read_adc call will read channel 1
analog_dat=read_adc(); //starts the conversion and reads the result
b6=make8(analog_dat,1);
b7=make8(analog_dat,0);
write_eeprom(address+6,b6);
write_eeprom(address+7,b7);
time[2]=get_timer1();
y++; // just a place to add a breakpoint
y++;
y++;
y++;
y++;
y++;
y++;
y++;
y++;
}
} |
Last edited by Leef_me on Sat May 01, 2010 4:39 pm; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Sat May 01, 2010 4:22 am |
|
|
The processor speed, doesn't really affect the EEPROM write speed. For this you need to look in the data sheet: 'Data EEPROM memory', 'Erase/Write time'. 4mSec. Now, in fact even this is only approximate, since it will vary a little with temperature, and voltage on the chip. The write code, waits for the chip to signal that the write has completed.
Second comment though, if what you are showing, is what you intend to do (write A/D values to the EEPROM), then "don't".... You need to consider a different approach:
1) Store the values in RAM, and only write them when a power fail is detected.
2) Use an external memory, like FRAM.
The problem is that EEPROM, is _not_ designed to store values that are changed at all frequently. It is designed to store things like calibration constants, that are rarely changed. The EEPROM, has a relatively limited 'write life'. Only 100000 erase/write cycles are 'guaranteed' for your chip (worst case). A single 'pass' through the code shown, uses 90 cycles. Repeat this 1200 times, and you have potentially destroyed the EEPROM....
Best Wishes |
|
|
Leef_me
Joined: 14 Mar 2006 Posts: 45
|
|
Posted: Sat May 01, 2010 4:53 pm |
|
|
Thanks Ttelmah,
Yes, I know that that writing values to eeprom is sub-optimum.
My code should have incremented the address variable, with each byte placed in a different location.
This was a cut-down from my original code and I missed the increment.
I only ran my code 2x or so times through the loop to get timing.
I am trying the store many samples of data; I can store 450, 8 byte samples in RAM at the moment.
I was trying to increase the amount by using EEPROM.
>>The processor speed, doesn't really affect the EEPROM write speed
What I originally wrote about was that the processor speed actually did seem to be a factor.
But the results are illogical.
The adc read & eeprom write for 6 bytes is comparable at 5.602ms and 5.9ms. Roughly the same.
But the results for writing 2 byte varies by a factor of approximately 37 to 1!! |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Sun May 02, 2010 10:04 am |
|
|
@16 MHz it's possible that your timer 1 overflowed which might explain the weird times you recorded. There is no way that an EEPROM will take less than 1ms. |
|
|
Leef_me
Joined: 14 Mar 2006 Posts: 45
|
|
Posted: Mon May 03, 2010 1:05 am |
|
|
newguy wrote: | @16 MHz it's possible that your timer 1 overflowed which might explain the weird times you recorded. There is no way that an EEPROM will take less than 1ms. |
Thanks newguy,
I knew the 2nd statement to be true. But I think I was myoptic enough not to realize the first.
Doing a really quick piece of math, 4500 counts * 16 = 72000 => overflow. Now I'm pretty sure the instruction count for the ADC didn't take 16 x as long as @ 1mhz but it is reasonable that the eeprom did.
Background: I ran these test as a last minute thing before rushing out the door for a weekend family visit (away from my test bed )
I cobbled together the script I posted, and missed the address increment.
It's the last few minutes of Sunday in California, but I'll be at my code again Monday morning to redo the script & the test.
At least you gave me an area to persue to find out what went wrong.
I'll post back what I find out.
Best wishes to the newguy in Canada. |
|
|
Leef_me
Joined: 14 Mar 2006 Posts: 45
|
|
Posted: Mon May 03, 2010 7:45 pm |
|
|
That was the problem. Timer1 was overflowing so it appeared that the 6 writes to eeprom were taking less time than the 2 writes to eeprom.
I added another variable that is incremented in the #INT_TIMER1 routine.
Now I can see the real time taken.
Thanks all. |
|
|
|
|
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
|