|
|
View previous topic :: View next topic |
Author |
Message |
azand1
Joined: 04 Feb 2014 Posts: 9
|
Calculation of variables in external EEPROM bytes |
Posted: Fri Feb 07, 2014 10:57 pm |
|
|
Calculation of variables in external EEPROM bytes
CCS Community. Help!
How to calculate the external EEPROM (24C64), where the page is 32 bytes.
Total pages is 256 by 32 bytes.
With constant string of 22 bytes.
Thank you. |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Sat Feb 08, 2014 12:29 am |
|
|
42 (Hitchhikers guide to the Galaxy). You are going to have to do a better job of explaining what you are trying to do and at least make an effort to create some code to accomplish whatever it is you are doing.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
azand1
Joined: 04 Feb 2014 Posts: 9
|
CALCULATING EXTERNAL EEPROM 24C64 BYTES |
Posted: Sat Feb 08, 2014 8:39 am |
|
|
CALCULATING EXTERNAL EEPROM 24C64 BYTES
Here the basic program
How to make a routine for computing string of 22 bytes in pages of 32 bytes.
Made an improvement in the program.
I could change the size of the string to 16 bytes (page 2 x 16 = 32), solved my problem. But, still insisting that it has solution.
This problem almost ready.
I ask for help.
Missing another part of the string.
RESULT IS
I would like to improve this routine.
I did two string .....
More than that, given problems.
// 10 de Fevereiro de 2014 02:27h
#include <16F876A.H>
#device *=16
#use delay(clock=4000000)
#fuses HS,NOPROTECT,NOWDT,NOBROWNOUT,PUT
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 8192 // EEPROM 24C64 –24C64: 8Kx8 (256 pages of 32 bytes)
int8 EEPROM_PAGE_LENGTH= 32; //chip dependent. Set based on datasheet
#define EEPROM_PAGE_LEN 32 // Page length in bytes FOR EEprom
#define EEPROM_PAGE_COUNT 256 // Nunber of pages in eeprom
#define EEPROM_SIZE_STRINGS 22 // sizer fix of string
#define EEPROM_COUNT_STRINGS 300 // number of strings
//
#define EEPROM_I2C_WRITE_ADDR 0xA0
#define EEPROM_I2C_READ_ADDR 0xA1
//
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3//
#use I2C(MASTER, SDA=EEPROM_SDA, SCL=EEPROM_SCL,FAST=400000)
long int Count_Eeprom =0;
//char *Ptr2=Buffer2;
// SILVIAGHIJLMNOPQRSTUVW Wilson dos
// 10 22
char Buffer3[22] = {'W','i','l','s','o','n',' ','d','o','s',' ','A','n','j','o','s','.','R','u','a',' ','D'};
char Buffer1[22] = {'S','I','L','V','I','A','G','H','I','J','L','M','N','O','P','Q','R','S','T','U','V','W'};
char Buffer2[32];
long int page=0;
int8 Count_letters=0;
void init_ext_eeprom() {
output_low(eeprom_scl);
output_high(eeprom_sda);
delay_ms(200);
}
void read_eeprom_block(long addr, char block_len, char* out_buffer) // corrigida ....................
{
char i;
char count;
if(block_len == 0) // 0 Não pode ter pagina com 2 bytes
return;
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
i2c_start();
i2c_write(EEPROM_I2C_READ_ADDR);
count = block_len -1;
for(i = 0; i < count; i++)
{
*out_buffer++ = i2c_read();
}
*out_buffer = i2c_read(0); // Last byte read must have no ACK
i2c_stop();
delay_ms(6);
}
//****************************** ALEATÓRIO *****************************
///////////////////////////////////////////////////////
// Erase one page (32 bytes) of the eeprom. The page can be from 0 to 256.
// The page is filled with zeros.
void erase_eeprom_page(long int page)
{
char i;
long int addr;
long int apagar;
addr = (page << 5); // Convert page address to a byte address (multiply by 64)
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
for(i = 0; i < EEPROM_PAGE_LEN; i++)
{
i2c_write(0); // Fill page with all zeros
Count_Eeprom++;
}
i2c_stop();
delay_ms(11);
//if((page % 8) == 0)
putc('.');
}
/////////////////////////////////////////////////////
void i2c_write_bloco(long address,char length, char *data,){
unsigned int16 dataIndex = 0;
unsigned int16 pageIndex;
unsigned int8 atualiza_end =0;
finish:
if( atualiza_end == 15){ address= Count_Eeprom; atualiza_end=10; }
pageIndex = address % EEPROM_PAGE_LENGTH; // 0 % 32
// while(dataIndex < length){
//Start I2C command
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write(address >> 8);
i2c_write(address);
//Loop through just the data on the current page
while(pageIndex < EEPROM_PAGE_LENGTH && dataIndex < length)
{
i2c_write(data[dataIndex++]);
pageIndex++;
Count_Eeprom++;
Count_letters++;
}
printf("\r\npageIndex: %lu < EEPROM_PAGE_LENGTH: %u dataIndex:%lu < length:%u "pageIndex,EEPROM_PAGE_LENGTH,dataIndex,length);
printf("\r\ndata : %u Count_Eeprom:%lu Count_letters:%u"data,Count_Eeprom,Count_letters);
i2c_stop();
if( atualiza_end == 10){
atualiza_end=0;
goto sai_ja;
}
if(Count_letters == 22) //OK
{
Count_letters=0;
}
else{ /// ?????????????????????????????????
EEPROM_PAGE_LENGTH=pageIndex;
if(Count_letters != 22){
EEPROM_PAGE_LENGTH=22;
length =22;
atualiza_end =15;
dataIndex=10;
pageIndex=0;
goto finish;
}
}
sai_ja :delay_cycles(6);
delay_ms(6); // opcional
}
///////////////////////////////////////////////////
void main(void) {
int8 n;
long int apagar;
int8 cmd =10;
delay_ms(1000);
puts("Inicio");
init_ext_eeprom();
delay_ms(15);
delay_ms(15);
apagar=0;
for (apagar=0;apagar< 4;apagar++)
erase_eeprom_page(apagar);
delay_ms(15);
Count_Eeprom=0;
//write_eeprom_block(0, 32, Buffer1); // &Buffer1);
puts("\r\n");
puts("Comecou");
delay_ms(1000);
Count_Eeprom=0;
i2c_write_bloco(Count_Eeprom,22,Buffer1);
delay_ms(15);
i2c_write_bloco(Count_Eeprom,22,Buffer3);
delay_ms(15);
puts("\r\n");
Count_Eeprom=0;
read_eeprom_block(Count_Eeprom, 32, Buffer2);
for (n=0;n<32;n++)
{ putchar((char)Buffer2[n]); }
//
delay_ms(15);
puts("\r\n");
Count_Eeprom=32;
read_eeprom_block(Count_Eeprom, 32, Buffer2);
for (n=0;n<32;n++)
{ putchar((char)Buffer2[n]); }
while(TRUE);;
}
/*
Inicio
....
Comecou
pageIndex: 22 < EEPROM_PAGE_LENGTH: 32 dataIndex:22 < length:22
data : 59 Count_Eeprom:22 Count_letters:22
pageIndex: 32 < EEPROM_PAGE_LENGTH: 32 dataIndex:10 < length:22
data : 37 Count_Eeprom:32 Count_letters:10
pageIndex: 22 < EEPROM_PAGE_LENGTH: 22 dataIndex:22 < length:22
data : 37 Count_Eeprom:44 Count_letters:22
SILVIAGHIJLMNOPQRSTUVWWilson dos
Anjos.Rua D
*/
Last edited by azand1 on Mon Feb 10, 2014 12:55 pm; edited 6 times in total |
|
|
azand1
Joined: 04 Feb 2014 Posts: 9
|
Routine eemprom page? |
Posted: Sun Feb 09, 2014 11:08 am |
|
|
Nobody knows make a page in eeprom routine?
I'm Newbie in C language. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Feb 09, 2014 11:17 am |
|
|
I still don't understand what the problem is.
Mike |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 09, 2014 11:47 am |
|
|
I think he wants to know how to calculate the page boundaries.
The 24LC64 eeprom has 32 pages with 32 bytes in each page.
So, to get the starting address of each page, multiply the desired page
number by 32:
Page 0 is (0 * 32) = address 0
Page 1 is (1 * 32) = address 32
Page 2 is (2 * 32) = address 64
Page 3 is (3 * 32) = address 96
etc. |
|
|
azand1
Joined: 04 Feb 2014 Posts: 9
|
I want to put 300 strings in order (continuous). Each string |
Posted: Sun Feb 09, 2014 12:13 pm |
|
|
I've tried to explain my doubts above.
I want to put 300 strings in order (continuous). Each string is 22 bytes.
The strings that will get the RS232 to an array after shipping
to eeprom.
I want to make those written in block (page), it is much faster. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 09, 2014 1:10 pm |
|
|
300 * 22 = 6600 bytes. That exceeds the capacity of the 24C64 eeprom,
which has only 1024 bytes in it. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Sun Feb 09, 2014 1:26 pm |
|
|
Er. Calculation gone wrong somewhere.
24C64, has 8KB, not 1KB....
However start with a comment, poster should be using the 24LC64, not the 24C64. The former is the current replacement for the latter, which is obsolete.
Also remember that with a 'string', there is an extra termination byte.
Personally, I'd suggest using 24byte records. 32byte page. Then 3 EEPROM pages, will hold 4 records. 300*24byte records, will then use 225 pages. Write in 96byte blocks.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 09, 2014 1:34 pm |
|
|
You are right, Ttelmah. I popped up the data sheet and left it un-zoomed,
and I didn't see the first part of:
Quote: | eight blocks of 1K x 8-bit |
And it's before my coffee as well. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Sun Feb 09, 2014 1:38 pm |
|
|
First mistake I remember from you, in many a month!....
Many more from me.
Best Wishes |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1355
|
|
Posted: Sun Feb 09, 2014 2:48 pm |
|
|
If I understand your question correctly, you want to be able to write more than just a single byte at a time but also avoid the issue of page boundaries messing with the writing. I use a function for work that does this, but I don't have it in front of me. Below is my attempt at trying to recreate it from memory.
Some notes:
1. I don't use I2C anymore (I use SPI eeproms), so I don't know if the I2C parts are correct. That's partially off of old memory and the datasheet. It's up to you to make sure the I2C parts are functionally correct (or perhaps you will get lucky and some other users can correct any mistakes).
2. This is just off the top of my head from some old memories, so there could be holes. The important part here is the idea of the algorithm used. Which is, calculate where in the current page you are, making sure to stop the command at the end of the page and start a new command at the beginning of the next page, and finally, making sure all the data gets written.
3. I typically work with PIC24 parts. I don't have as much experience with non PCD chips, so something I take for granted as quick/easy might not be on your chips.
With that said, here is a stab at an algorithm for writing long data without having to worry about page boundaries.
Code: |
#define EEPROM_PAGE_LENGTH 32 //chip dependent. Set based on datasheet
#define EEPROM_I2C_ADDR 0xA0 //hardware dependent. Set based on circuit. 8 bit address format
void i2c_write_eeprom(unsigned int16 address, unsigned int8 *data, unsigned int16 length){
unsigned int16 dataIndex = 0;
unsigned int16 pageIndex;
BOOLEAN writing;
//figure out index relative to page boundary
pageIndex = address % EEPROM_PAGE_LENGTH;
//loop through each page
while(dataIndex < length){
//Start I2C command
i2c_start();
i2c_write(EEPROM_I2C_ADDR);
i2c_write(address >> 8);
i2c_write(address);
//Loop through just the data on the current page
while(pageIndex < EEPROM_PAGE_LENGTH && dataIndex < length){
i2c_write(data[dataIndex++]);
pageIndex++;
}
i2c_stop(); //page write done
pageIndex = 0; //reset for next time
//This part just polls the chip to make sure the write finished.
//It could be replaced with just a delay_ms() call. If so,
//reference the datasheet to see what the appropriate time is.
do{
i2c_start();
writing = i2c_write(EEPROM_I2C_ADDR);
}while(writing);
i2c_stop();
}
}
|
Last edited by jeremiah on Sun Feb 09, 2014 9:18 pm; edited 1 time in total |
|
|
azand1
Joined: 04 Feb 2014 Posts: 9
|
Someone's starting to endender what I mean. |
Posted: Sun Feb 09, 2014 4:44 pm |
|
|
Sorry about the bad English because I'm from Brazil. AZAND1
My friend jeremiah.
Understand that I meant.
The idea is:
10 = 32-22 (string) / / I record 22 bytes on the same page
-12 = 10-22 (String) / / Part of the string on the same page
12 remaining on another page.
/ *
Have an error in your routina.
below:
/ / This part just polls the chip to make sure the write finished.
/ / It could be Replaced with just a delay_ms () call. If so,
/ / reference the datasheet to see what the time is Appropriate.
i2c_start ();
do {
i2c_start ();
writing i2c_write = (EEPROM_I2C_ADDR);
} while (writing);
i2c_stop ();
* / |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Mon Feb 10, 2014 1:20 am |
|
|
And, as I say, think again, and don't use 22byte.
Use 24.
Even if the extra bytes are not needed (however one may be, a '22 character' string, needs 23 bytes), it makes the maths, and storage so much easier.
3 EEPROM pages, will hold 4 records.
Write a 96byte block (3 pages).
On the error '=' misplaced.
writing=i2c_write(EEPROM_I2C_ADDR);
Best Wishes |
|
|
|
|
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
|