cannot write page and read strings in eeprom 24c04

Thread Starter

devjeetmandal

Joined May 7, 2017
48
hello everyone,
i was trying to write page in eeprom 24c04 using ATMega32
the problem is when i m trying to write 255 character its working fine with the code. i can write using the page write function i have build and i can read the string from eeprom too.
but when i try to read mode than 255 characters, display shows garbage


here is my twi.c file

C:
#include "twi.h"


void Twi_Init()
{
   TWSR = 0x00;
   TWBR = 0x02;
}

unsigned char Twi_Start(void)
{
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT)));
   return (TWSR & 0xf8);
   while((TWSR & 0xf8) != 0x08);
}

unsigned char Twi_Repeated_Start(void)
{
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT)));
   return (TWSR & 0xf8);
   while((TWSR & 0xf8) != 0x10);
}

unsigned char Twi_Send_Address(unsigned char addr)
{
   TWDR = addr;
   TWCR = (1<<TWINT)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT)));
   return (TWSR & 0xf8);
   while(((TWSR & 0xf8) != 0x18) || ((TWSR & 0xf8) != 0x40));
}

unsigned char Twi_Send_Data(unsigned char data)
{
   TWDR = data;
   TWCR = (1<<TWINT) |(1<<TWEN);
   while (!(TWCR & (1<<TWINT)));
   return (TWSR & 0xf8);
   while((TWSR & 0xf8) != 0x28);
}

unsigned char Twi_Send_String(unsigned char *string)
{
   while (*string)
   {
     TWDR = *string++;
     TWCR = (1<<TWINT) |(1<<TWEN);
     while (!(TWCR & (1<<TWINT)));
     while((TWSR & 0xf8) != 0x28);
   }
   return (TWSR & 0xf8);
}

unsigned char Twi_Receive_Data(void)
{
   TWCR =(1<<TWEA)|(1<<TWINT)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT)));
   return(TWDR);
   while((TWSR & 0xf8) != 0x50);
}

unsigned char Twi_Receive_Last_Data(void)
{
   TWCR =(1<<TWINT)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT)));
   return(TWDR);
   while((TWSR & 0xf8) != 0x58);
}

unsigned char *Twi_Receive_String(unsigned int number_of_bytes,unsigned char *string)
{
   for(unsigned int i=0;i<number_of_bytes;i++)
   {
     TWCR =(1<<TWEA)|(1<<TWINT)|(1<<TWEN);
     while (!(TWCR & (1<<TWINT)));
     *(string+i)=TWDR;
     while((TWSR & 0xf8) != 0x50);
   }
   *(string+number_of_bytes)=Twi_Receive_Last_Data();
   *(string+number_of_bytes)='\0';
}

void Twi_Stop(void)
{
   TWCR =  (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
   while ((TWCR & (1<<TWSTO)));
}

this is how i'm doing page write

C:
void EEP_PageWrite(unsigned int starting_memory_address, unsigned char *string)
{
   unsigned char page_value;
   page_value = 16;
   Twi_Start();
   Twi_Send_Address(EEP_W_Address);
   Twi_Send_Data(starting_memory_address);
   for(unsigned char i=0;i<page_value;i++)
   {
      Twi_Send_Data(*(string+i));
   }
   Twi_Stop();
}
and this is how i'm reading the string

C:
unsigned char *EEP_ReadString(unsigned int starting_memory_address, unsigned int number_of_bytes,unsigned char *string)
{
   unsigned char twi_status;
   Twi_Start();
   Twi_Send_Address(EEP_W_Address);
   Twi_Send_Data(starting_memory_address);
   Twi_Repeated_Start();
   Twi_Send_Address(EEP_R_Address);
   Twi_Receive_String(number_of_bytes,string);
   Twi_Stop();
   return string;
}
So when i first approached this problem i thought 24c04 takes 16bit address value and i'm just provideing with 8 bit address value while writing in page and reading the string.

so i did this
C:
void EEP_PageWrite(unsigned int starting_memory_address, unsigned char *string)
{
   unsigned char page_value;
   page_value = 16;
   Twi_Start();
   Twi_Send_Address(EEP_W_Address);
   Twi_Send_Data(starting_memory_address>>8);  //added this line   
   Twi_Send_Data(starting_memory_address);
   for(unsigned char i=0;i<page_value;i++)
   {
      Twi_Send_Data(*(string+i));
   }
   Twi_Stop();
}


unsigned char *EEP_ReadString(unsigned int starting_memory_address, unsigned int number_of_bytes,unsigned char *string)
{
   unsigned char twi_status;
   Twi_Start();
   Twi_Send_Address(EEP_W_Address);
   Twi_Send_Data(starting_memory_address>>8);    //added this line
   Twi_Send_Data(starting_memory_address);
   Twi_Repeated_Start();
   Twi_Send_Address(EEP_R_Address);
   Twi_Receive_String(number_of_bytes,string);
   Twi_Stop();
   return string;
}

but unfortunately the problem does not solve.
any help will be extremely helpful.
thanks in advance
 

JohnInTX

Joined Jun 26, 2012
4,237
unsigned char *EEP_ReadString(unsigned int starting_memory_address, unsigned int number_of_bytes,unsigned char *string)
{
unsigned char twi_status;
Twi_Start();
Twi_Send_Address(EEP_W_Address);
Twi_Send_Data(starting_memory_address>>8); //added this line
Twi_Send_Data(starting_memory_address);

Twi_Repeated_Start();
Twi_Send_Address(EEP_R_Address);
Twi_Receive_String(number_of_bytes,string);
Twi_Stop();
return string;
}
This EEPROM is organized as two 256 byte blocks. The block select is in the control byte, not in an additional address byte as it would be in a larger EEPROM. This means that the EEP_W_Address (EEPROM control) byte will be different when you address the upper block:
1010xx00 selects the lower block for writing
1010xx10 selects the upper block for writing

1010xx01 selects the lower block for reading
1010xx11 selects the upper block for reading

The Address Low Byte addresses the byte in the selected block.
Page 7 21708K.jpg
 
Top