4
\$\begingroup\$

I am working on EEPROM AT24C16 for a particular project. According to the datasheet it must have 2048 addresses and I should be able to write 1024 unsigned int into it [ 1 unsigned int per 2 addresses] but I am only able to write 128 unsigned ints onto 256 addresses.

Is my EEPROM duplicate or I am confused and it has only 256 addresses. please help me to figure out the number of addresses in AT24C16.

Code:

#include<p18f4520.h>
#include<i2c.h>  // Required For In-built I2C Routine


#pragma config OSC = HS   /* Sets the oscillator mode HS */
#pragma config WDT = OFF   /* Turns the watchdog timer off */
#pragma config LVP = OFF   /* Turns low voltage programming off */


#define LCD_PORT  LATB
#define LCD_EN  LATDbits.LATD7
#define LCD_RS  LATDbits.LATD6
#define ADDRESS   0xA0

#define LCD_PORT_DIR  TRISB
#define LCD_EN_DIR  TRISDbits.TRISD7
#define LCD_RS_DIR  TRISDbits.TRISD6

#define I2C_SCL    TRISCbits.TRISC3
#define I2C_SDA    TRISCbits.TRISC4

#define AddressU 0
#define AddressL 1

int TempUpper, TempLower;
long int TempValue;
int TempUpper1, TempLower1;
long int TempValue1;

void DelayMS(unsigned int);
void init_lcd();
void command();
void lcd_data(unsigned char);
void Init_MSSP_I2C();



void DelayMS(unsigned int itime) {
    unsigned int i;
    unsigned char j;

    for (i = 0; i < itime; i++)
        for (j = 0; j < 165; j++);
}

void command() {
    LCD_RS = 0  ;
    LCD_EN = 1  ;
    DelayMS(1);
    LCD_EN = 0  ;
    DelayMS(1);
}
void lcd_data(unsigned char dat) {
    LCD_PORT  = dat ;
    LCD_RS    = 1  ;
    LCD_EN    = 1  ;
    LCD_EN    = 0  ;
    DelayMS(1);
}
void init_lcd() {
    LCD_PORT = 0x38 ;   //LCD 2 Lines
    command();
    LCD_PORT = 0x0E;  //Display On,Cursor On
    command();
    LCD_PORT = 0x01;  // Clear LCD
    command();
    LCD_PORT = 0x06;  //Shift Cursor right
    command();
    LCD_PORT = 0x80;  //line 1, position 1
    command();
}

void lcd_string(char rom *str) {
    while (*str)
    { lcd_data(*str++); }

    DelayMS(1);
}
void Init_MSSP_I2C() {
    I2C_SCL = 1                 ;   //      Initilize MSSP For I2C Send Write '1' RC3/SCL
    I2C_SDA = 1                 ;   //      Initilize MSSP For I2C Send Write '1' RC4/SDA
    OpenI2C(MASTER, SLEW_OFF)      ;  //   Start I2C Stop I2C
    SSPADD = 0x18 ;
}

unsigned int e, th, h, t, o, c = 0, g = 0, temp, tempvalue, fu, add = 0, mv = 0;


void main(void) {
    Init_MSSP_I2C();
    LCD_RS_DIR =  0 ;
    LCD_EN_DIR =  0 ;
    LCD_PORT_DIR = 0 ;
    DelayMS(250);   // Wait on Intilization LCD
    init_lcd();
    lcd_string((rom  char *)"Testing 24C02.. ");    // DPTR in 8051 AS
    TempValue = mv;
    add = 0;

    while (add < 512) {
        TempUpper1 = (TempValue >> 8) & 0x00FF;
        TempLower1 = (TempValue & 0x00FF);
        EEByteWrite(ADDRESS, add, TempUpper1);
        DelayMS(10);
        EEByteWrite(ADDRESS, add + 1, TempLower1);
        DelayMS(10);
        TempValue = TempValue + 1;
        add = add + 2;
    }

    init_lcd();
    lcd_string((rom  char *)"END ");

    while (1);

    while (add < 512) {
        TempUpper = EERandomRead(ADDRESS, add);
        TempLower = EERandomRead(ADDRESS, add + 1);
        DelayMS(10);
        add = add + 2;
        TempValue = 0x0000;
        TempValue = TempUpper;
        TempValue = TempValue << 8;
        TempValue = TempValue | TempLower;
        DelayMS(50);
        g = TempValue;
        fu = g / 10000; // gets 1000's value of number to Segments[1]
        temp = g % 10000;
        th = temp / 1000; // gets 1000's value of number to Segments[2]
        temp = temp % 1000;
        h = temp / 100; // gets 100's of number value to Segments[3]
        temp = temp % 100;
        t = temp / 10; // gets 10's value of number to Segments[4]
        o = temp % 10; // gets 1's value of number to Segments[5]
        LCD_PORT = 0xc2;    //line 1, position 1
        command();
        lcd_data(fu | 0x30) ;
        LCD_PORT = 0xc3;    //line 1, position 1
        command();
        lcd_data(th | 0x30) ;
        LCD_PORT = 0xc4;    //line 1, position 1
        command();
        lcd_data(h | 0x30) ;
        LCD_PORT = 0xc5;    //line 1, position 2
        command();
        lcd_data(t | 0x30) ;
        LCD_PORT = 0xc6;    //line 1, position 3
        command();
        lcd_data(o | 0x30) ;
        DelayMS(1000);
    }

    while (1);
}
\$\endgroup\$
  • \$\begingroup\$ AT24C16 has 256 bytes per page. It has 8 pages. Are you just writing to page zero? \$\endgroup\$ – Roger Rowland Jun 23 '15 at 8:49
  • \$\begingroup\$ I don't know how to flip between pages and write differently on them i am just sequentially incrementing the addresses like 'epwrite(value,address) epwrite(value,address+1)', plz guide me @RogerRowland. \$\endgroup\$ – prog_SAHIL Jun 23 '15 at 8:58
  • 1
    \$\begingroup\$ The datasheet (which I haven't seen) surely shows you the protocol used to address the memory? For example see this similar project which describes the I2C protocol. \$\endgroup\$ – Roger Rowland Jun 23 '15 at 9:00
  • 1
    \$\begingroup\$ It's a shame to see this question not receiving a few upvotes. He's run into a problem in the library routines he is using rather than having a coding error per se. This is a typical trap for the uninitiated and the question is a reasonable one. \$\endgroup\$ – Russell McMahon Jun 23 '15 at 14:14
  • 1
    \$\begingroup\$ Got it @RogerRowland . I checked the datasheet and found three pins as p0 , p1 , p2 meaning page control pins. I changed ADDRESS into array containing values A0,A2,A4,A6,A8,AA,AC,AE and now i can access all the pages. THANKS TO ALL GREAT HELP. \$\endgroup\$ – prog_SAHIL Jul 8 '15 at 11:23
5
\$\begingroup\$

The problem here is actually with the I2C peripheral library, not your code.

The EEByteWrite function is defined as:

signed char EEByteWrite1(  unsigned char control,
                           unsigned char address,
                           unsigned char data );
#define EEByteWrite EEByteWrite1

As you can see the address parameter is an unsigned char which means it can only accept values up to 255. That's the limit you are hitting.

The EERandomRead function is defined similarly.

The built-in EEByte* functions in plib are not suitable for anything more than small EEPROMs with up to 256 addresses.

To access more than 256 addresses you will need to write your own routines that control the target chip appropriately.

\$\endgroup\$
  • \$\begingroup\$ See my comment on his answer. He's trying to adapt, the question is reasonable and he needs encouraging. Nudge, nudge, ... . \$\endgroup\$ – Russell McMahon Jun 23 '15 at 14:15
  • \$\begingroup\$ I have tried it but its not working.When I googled it I learnt that EEPROM has 128 pages of 16 bytes each and we can write 16 bytes at a time by sending start bit>>data>>>stop bit and then swap between pages and repeat the same...But i still can't figure that out...what pages ...how to swap...what start/stop bit??? :( \$\endgroup\$ – prog_SAHIL Jun 23 '15 at 14:23
  • \$\begingroup\$ If you are just writing a single byte at a time you don't need to worry about pages. That's only really for higher speed block transfers. The start and stop bits are all part of the I2C protocol - you'll need to learn how that works first before you apply it to the EEPROM. \$\endgroup\$ – Majenko Jun 23 '15 at 14:42
  • \$\begingroup\$ Got it @Majenko . I checked the datasheet and found three pins as p0 , p1 , p2 meaning page control pins. I changed ADDRESS into array containing values A0,A2,A4,A6,A8,AA,AC,AE and now i can access all the pages. THANKS TO ALL GREAT HELP. \$\endgroup\$ – prog_SAHIL Jul 8 '15 at 11:22
  • \$\begingroup\$ Got it @RussellMcMahon . I checked the datasheet and found three pins as p0 , p1 , p2 meaning page control pins. I changed ADDRESS into array containing values A0,A2,A4,A6,A8,AA,AC,AE and now i can access all the pages. THANKS TO ALL GREAT HELP. \$\endgroup\$ – prog_SAHIL Jul 8 '15 at 11:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.