Saturday 1 February 2014

c - Number of address in AT24C16 EEPROM or is it duplicate?


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
#include // 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);

}

Answer



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.


No comments:

Post a Comment

arduino - Can I use TI&#39;s cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...