16 Bit data in AT24C64 (iic)

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Freaks;

I need to write 16 bit data (Word) in iic EEPROM.
do any one have library for it.,I tried googling but for external iic devices doesn't have this function since its 8 bit EEProm, but we can split up msb and lsb and save them and also to retrieve them back.

i saw library for internal eeprom to write Word.,

Please Freaks help

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please guys .., help me.

There would be lots of good programmer in this forums , who had experienced this issues, please help

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Before you start your school project:

1. read the data sheet for the 24C64
2. google "Fleury I2C AVR"

Write down in English (or Hindi) which commands you should send.
Design your program.
Write the C code.

Go to the top of your class.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

but we can split up msb and lsb and save them and also to retrieve them back.

Didn't you answer your own question. To write a 16bit word to an 8bit memory you split it into its two component bytes. As long as you reconstitute them in the same order when you read back you'll get the 16bit value back. Something like:

uint16_t word = 12345;
iic_eeprom_write_byte(location0, word & 0xFF);
iic_eeprom_write_byte(location1, word >> 8);

later

uint16_t readback;
readback = iic_eeprom_read_byte(location0);
readback |= (iic_eeprom_read_byte(location1) << 8);

'readback' should now contain 12345.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for reply...

david.prentice @ i am using Fleury I2C lib, i tried but the failed.

clawson @ thanks for logic will try it,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Obviously you wouldn't do all the shifting and masking every time you want to read or write. Given iic_eeprom_write/read_byte() routines you'd make a couple of wrapper routines:

void iic_eeprom_write_word(uint16_t n, uint16_t location) {
 iic_eeprom_write_byte(location, n & 0xFF); 
 iic_eeprom_write_byte(location+1, n >> 8); 
}

and

uint16_t iic_eeprom_read_word(uint16_t location) {
 uint16_t readback; 
 readback = iic_eeprom_read_byte(location); 
 readback |= (iic_eeprom_read_byte(location+1) << 8); 
 return readback;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dhimullai wrote:
Thanks for reply...

david.prentice @ i am using Fleury I2C lib, i tried but the failed.

clawson @ thanks for logic will try it,

I have not downloaded the current Fleury example code.
The older releases had examples for a AT24C04 eeprom.

The AT24C64 and the AT24C04 require different bytes to set the location register.

Read the data sheet for the ATC24C01/2/4/8/16.
Compare with your 24C64 data sheet.

If you have a question, ask the question.
It is a very important skill for you google data sheets, google libraries, ask questions etc.

And if you do not understand something, say so. We are happy to explain.

Say what you are trying to do.
It is pretty obvious which students just say 'gimme solution' and which students are thinking about their problem.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

David, he does not use a 16-bit eeprom, he just needs to store 16-bit data to 8-bit eeprom as bytes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I knew difference btw 24c64 and 24c02, mainly we need to change device address. i will try to write my code and if any problem i will post questions

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi clawson and other thanks for your help .. Finally it works.

will post my 24c64 library

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include 
#include 

#include "24c64.h"

void EEOpen()
{
	//Set up TWI Module
	TWBR = 5;
	TWSR &= (~((1<<TWPS1)|(1<<TWPS0)));

}

uint8_t EEWriteByte(uint16_t address,uint8_t data)
{
	do
	{
		//Put Start Condition on TWI Bus
		TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

		//Poll Till Done
		while(!(TWCR & (1<<TWINT)));

		//Check status
		if((TWSR & 0xF8) != 0x08)
			return FALSE;

		//Now write SLA+W
		//EEPROM @ 00h
		TWDR=0b10100000;	

		//Initiate Transfer
		TWCR=(1<<TWINT)|(1<<TWEN);

		//Poll Till Done
		while(!(TWCR & (1<<TWINT)));
	
	}while((TWSR & 0xF8) != 0x18);
		

	//Now write ADDRH
	TWDR=(address>>8);

	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);

	//Poll Till Done
	while(!(TWCR & (1<<TWINT)));

	//Check status
	if((TWSR & 0xF8) != 0x28)
		return FALSE;

	//Now write ADDRL
	TWDR=(address);

	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);

	//Poll Till Done
	while(!(TWCR & (1<<TWINT)));

	//Check status
	if((TWSR & 0xF8) != 0x28)
		return FALSE;

	//Now write DATA
	TWDR=(data);

	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);

	//Poll Till Done
	while(!(TWCR & (1<<TWINT)));

	//Check status
	if((TWSR & 0xF8) != 0x28)
		return FALSE;

	//Put Stop Condition on bus
	TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
	
	//Wait for STOP to finish
	while(TWCR & (1<<TWSTO));

	//Wait untill Writing is complete
	_delay_ms(12);

	//Return TRUE
	return TRUE;

}

uint8_t EEReadByte(uint16_t address)
{
	uint8_t data;

	//Initiate a Dummy Write Sequence to start Random Read
	do
	{
		//Put Start Condition on TWI Bus
		TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

		//Poll Till Done
		while(!(TWCR & (1<<TWINT)));

		//Check status
		if((TWSR & 0xF8) != 0x08)
			return FALSE;

		//Now write SLA+W
		//EEPROM @ 00h
		TWDR=0b10100000;	

		//Initiate Transfer
		TWCR=(1<<TWINT)|(1<<TWEN);

		//Poll Till Done
		while(!(TWCR & (1<<TWINT)));
	
	}while((TWSR & 0xF8) != 0x18);
		

	//Now write ADDRH
	TWDR=(address>>8);

	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);

	//Poll Till Done
	while(!(TWCR & (1<<TWINT)));

	//Check status
	if((TWSR & 0xF8) != 0x28)
		return FALSE;

	//Now write ADDRL
	TWDR=(address);

	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);

	//Poll Till Done
	while(!(TWCR & (1<<TWINT)));

	//Check status
	if((TWSR & 0xF8) != 0x28)
		return FALSE;

	//*************************DUMMY WRITE SEQUENCE END **********************


	
	//Put Start Condition on TWI Bus
	TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

	//Poll Till Done
	while(!(TWCR & (1<<TWINT)));

	//Check status
	if((TWSR & 0xF8) != 0x10)
		return FALSE;

	//Now write SLA+R
	//EEPROM @ 00h
	TWDR=0b10100001;	

	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);

	//Poll Till Done
	while(!(TWCR & (1<<TWINT)));

	//Check status
	if((TWSR & 0xF8) != 0x40)
		return FALSE;

	//Now enable Reception of data by clearing TWINT
	TWCR=(1<<TWINT)|(1<<TWEN);

	//Wait till done
	while(!(TWCR & (1<<TWINT)));

	//Check status
	if((TWSR & 0xF8) != 0x58)
		return FALSE;

	//Read the data
	data=TWDR;

	//Put Stop Condition on bus
	TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
	
	//Wait for STOP to finish
	while(TWCR & (1<<TWSTO));

	//Return TRUE
	return data;
}


void EEWriteWord(uint16_t address, uint16_t data) 
{

EEWriteByte(address, data & 0xFF);
EEWriteByte(address+1, data >> 8);

}

uint16_t EEReadWord(uint16_t address) 
{

uint16_t readback;
readback = EEReadByte(address);
readback |= (EEReadByte(address+1) << 8);
return readback;

} 


  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Previously i tried but did some errors in bitwise operators. Thanks to all

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dear dhimullai,

You have not grasped the point of using a library.

You should build your 'uint8_t EEWriteByte(uint16_t address,uint8_t data)' function with the primitive library routines.

This involves a handful of lines of code. And most importantly you know that the underlying functions are 100% reliable.

It is the same principle as building a bridge with ready-made nuts and bolts. Of course you can always mine your own iron-ore, design your own threads etc.
But at the end of the day the world is better off with ready-made standard bolts. (except for regressive Americans).

David.

p.s. your EEWriteWord() and EEReadWord() functions are nice and elegant.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

p.s. your EEWriteWord() and EEReadWord() functions are nice and elegant.

:-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

p.s. your EEWriteWord() and EEReadWord() functions are nice and elegant.


Quote:

readback |= (EEReadByte(address+1) << 8);

Hmmmm--here is where the promotion rules come into play again. If you indeed shift an 8-bit value 8 times you get 0.

If it is promoted to (signed) int, I guess you are safe in this instance. Prior promotion threads have noted how sign extension may come into play but I think this one is OK.

As with precedence, I usually don't want to guess so I'd cast the 8 bits to 16 bits unsigned before doing the shift.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The precedence and Promotion of these two functions look fine to me for conforming C Compilers. Yes, you require attention for Codevision.

No I have not even dreamed of looking through the '100-line' functions. I am sure they may well be fully debugged. Just like a hand-crafted nut and bolt. I just prefer to buy nuts and bolts fully certified from the shop.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use always block read and write routines, since the EEPROM support block-read and page-write (shorter write time and less wearout).

Then I give a pointer to the data and the length of the data in bytes to these routines.
If the data contain more variables, I use a struct.

Peter

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi.. sorry i join and ask cause i really need a help. i follow the code above by dhimullai but i my program got halt when i press the button function.

 

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "CMod_LCD.h"
#include "Mod_LCD.h"
#include "IOinit.h"
#include "PZ_ADC.h"
#include "PZ_ADCConfig.h"
//#include "i2cmaster.h"
#include "24c64.h"
 
#define ADDEEPROM    0xA2
#define ADDRREAD_EEPROM   0xA1

uint16_t CONSOLE_DO, CONSOLE_LR, TMPCNT, Readthis; 
char buffConDO [20];
char buffConLR [20];
char buffer [20];
//Savethis = buffConDO[20];
//uint16_t ADDR1;

int main(void)
{
 SET_AS_INPUT (DDRF, BUP);
 SET_AS_INPUT (DDRF, BRIGHT);
 SET_HIGH  (PORTF, BUP);
 SET_HIGH  (PORTF, BRIGHT);
  
 lcd_init(LCD_DISP_ON);
 //lcd_init(LCD_HOME);
 lcd_clear();
 _delay_ms(100);
 ADC_Init();
 ADC_SetPrescaler(ADC_PRESCALE_DIV128);
 ADC_SetReference(ADC_REFERENCE_AVCC);
 _delay_ms(50);
 
    while(1)
    {
  _delay_ms(100);
  CONSOLE_DO = ADC_Read10bit(ADC_CH_ADC4);
  CONSOLE_LR = ADC_Read10bit(ADC_CH_ADC5);
  sprintf(buffConDO,"ADC UD= %u ", CONSOLE_DO);
  sprintf(buffConLR,"ADC LR= %u ", CONSOLE_LR);
  lcd_gotoxy(0,0); lcd_puts(buffConDO);
  lcd_gotoxy(0,1); lcd_puts(buffConLR);
  
//_____ STATE CAPTURE VALUE _______
  if (ENBUTT_PRS())
  {
   _delay_ms(100);
   EEWriteWord(0x01, CONSOLE_DO);   
  }
  
  if (CANBUTT_PRS())
  {
   uint16_t readback;
   _delay_ms(100);
   readback=EEReadWord(0x01);
   sprintf(buffer,"EEPROM= %u", readback);
   lcd_gotoxy(0,3); lcd_puts(buffer);
  }
  
//_____ TODO:: Please write your application code
 }
}

 

how can i do to fix this?

i don't know if i had maked wrong address into library.

I like logic and such a programming :)