/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __AT24_H
#define __AT24_H
#include <
string.h>
#include "hw_twi.h"
#include "hw_def.h"
/*
AT24C02, 2K Bits SERIAL EEPROM:
Internally organized with 32 pages of 8 bytes each,
the 2K Bits requires an 8-bit data word address for random word addressing.
// Serial EEPROM type //
#define IIC_EEPROM_AT24C01 1 // AT24C01 - 1K ( 128 x 8) ( 8 byte page write)
#define IIC_EEPROM_AT24C02 2 // AT24C02 - 2K ( 256 x 8) ( 8 byte page write)
#define IIC_EEPROM_AT24C04 4 // AT24C04 - 4K ( 512 x 8) (16 byte page write)
#define IIC_EEPROM_AT24C08 8 // AT24C08 - 8K (1024 x 8) (16 byte page write)
#define IIC_EEPROM_AT24C16 16 // AT24C16 -16K (2048 x 8) (16 byte page write)
+---+---+---+---+---+---+---+---+
1k/2K | 1 | 0 | 1 | 0 | A2| A1| A0|R/W| AT24C01A/AT24C02
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
4k | 1 | 0 | 1 | 0 | A2| A1| P0|R/W| AT24C04
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
8k | 1 | 0 | 1 | 0 | A2| P1| P0|R/W| AT24C08
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
16k | 1 | 0 | 1 | 0 | P2| P1| P0|R/W| AT24C16
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
512k | 1 | 0 | 1 | 0 | A2| A1| A0|R/W| AT24C512
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
1M | 1 | 0 | 1 | 0 | A2| A1| P0|R/W| AT24C1024
+---+---+---+---+---+---+---+---+
P0,P1,P2 - Page Address
*/
#define AT24_CMD_READ ( 0xA1 )
#define AT24_CMD_WRITE ( 0xA0 )
#define AT24_CHIP_SIZE ( 0x100 )
#define AT24_PAGE_SIZE ( 0x08 )
#define AT24_WRITE_TIMEOUT ( 50 )
#define AT24_PAGE_MASK ( AT24_PAGE_SIZE-1 )
#define AT24_PAGE_COUNT ( AT24_CHIP_SIZE/AT24_PAGE_SIZE )
unsigned int AT24_Init(
void);
void AT24_ReadMemory(unsigned
int dwAddr,
unsigned int dwSize, unsigned
char *
Memory);
void AT24_WriteMemory(unsigned
int dwAddr,
unsigned int dwSize, unsigned
char *
Memory);
#endif /*__AT24_H*/
#include
"AT24.h"
#include "hw_eeprom_addr.h"
unsigned int AT24_Init(
void)
{
#if ( 1 )
unsigned int TestValue;
unsigned int i =
0;
do {
TestValue =
0xAA;
AT24_ReadMemory(EEPROM_ADDR_TEST_UNIT, 1, (unsigned
char *)&
TestValue);
if ( ( i >
0 ) || ( TestValue ==
0x55 ) )
break;
AT24_WriteMemory(EEPROM_ADDR_TEST_UNIT, 1, (unsigned
char *)&
TestValue);
i++
;
} while (
1);
return ( TestValue ==
0x55 );
#else
unsigned int TestValue;
TestValue =
0xAA;
AT24_ReadMemory(EEPROM_ADDR_TEST_UNIT, 1, &
TestValue);
if ( TestValue !=
0x55 )
{
TestValue =
0x55;
AT24_WriteMemory(EEPROM_ADDR_TEST_UNIT, 1, &
TestValue);
TestValue =
0xAA;
AT24_ReadMemory(EEPROM_ADDR_TEST_UNIT, 1, &
TestValue);
}
return ( TestValue ==
0x55 );
#endif
}
// only for UserZone 0..2
void AT24_ReadMemory(unsigned
int dwAddr,
unsigned int dwSize, unsigned
char *
Memory)
{
//memset( Memory, 0xFF, dwSize );
if ( dwAddr + dwSize > AT24_CHIP_SIZE )
return;
#if ( AT24_CHIP_SIZE > 0x0800 )
// AT24C32 > 2048 Bytes
#else // AT24C16 : 2048 Bytes : P2:P1:P0:ADDR
// Write Address
HW_TWI_Start( HW_TWI_AT24 );
HW_TWI_SendByte(HW_TWI_AT24, AT24_CMD_WRITE | ( (dwAddr>>
8) <<
1 ) );
if ( HW_TWI_ReadACK( HW_TWI_AT24 ) ==
HW_TWI_NACK )
{
HW_TWI_Stop( HW_TWI_AT24 );
return;
}
HW_TWI_SendByte(HW_TWI_AT24, dwAddr );
HW_TWI_ReadACK( HW_TWI_AT24 );
// READ Data
HW_TWI_Start( HW_TWI_AT24 );
HW_TWI_SendByte(HW_TWI_AT24, AT24_CMD_READ | ( (dwAddr>>
8) <<
1 ) );
HW_TWI_ReadACK( HW_TWI_AT24 );
while ( dwSize )
{
*Memory =
HW_TWI_ReceiveByte ( HW_TWI_AT24 );
if ( dwSize ==
1 )
HW_TWI_SendACK( HW_TWI_AT24, HW_TWI_NACK );
else
HW_TWI_SendACK( HW_TWI_AT24, HW_TWI_ACK );
Memory++
;
dwSize--
;
}
HW_TWI_Stop( HW_TWI_AT24 );
#endif
}
void AT24_WritePage(unsigned
int dwAddr,
unsigned int dwSize, unsigned
char *
Memory)
{
#if ( AT24_CHIP_SIZE > 0x0800 )
// AT24C32 > 2048 Bytes
#else // AT24C16 : 2048 Bytes : P2:P1:P0:ADDR
HW_TWI_Start( HW_TWI_AT24 );
HW_TWI_SendByte(HW_TWI_AT24, AT24_CMD_WRITE | ( (dwAddr>>
8) <<
1 ) );
if ( HW_TWI_ReadACK( HW_TWI_AT24 ) ==
HW_TWI_NACK )
{
HW_TWI_Stop( HW_TWI_AT24 );
return;
}
HW_TWI_SendByte(HW_TWI_AT24, dwAddr );
HW_TWI_ReadACK( HW_TWI_AT24 );
while ( dwSize )
{
HW_TWI_SendByte(HW_TWI_AT24, *
Memory );
HW_TWI_ReadACK( HW_TWI_AT24 );
Memory++
;
dwSize--
;
}
HW_TWI_Stop( HW_TWI_AT24 );
// Poll Ack from eeprom
HW_TWI_WaitComplete(HW_TWI_AT24,
AT24_CMD_WRITE | ( (dwAddr>>
8) <<
1 ), AT24_WRITE_TIMEOUT);
#endif
}
/*
When the word address, internally generated, reaches the page boundary,
the following byte is placed at the beginning of the same page.
If more than eight (1K/2K) or sixteen (4K, 8K, 16K) data words
are transmitted to the EEPROM, the data word address
will roll over and previous data will be overwritten.
*/
void AT24_WriteMemory(unsigned
int dwAddr,
unsigned int dwSize, unsigned
char *
Memory)
{
unsigned int dwSizeInPage;
if ( dwAddr + dwSize > AT24_CHIP_SIZE )
return;
while ( dwSize >
0 )
{
dwSizeInPage = AT24_PAGE_SIZE - ( dwAddr & (AT24_PAGE_SIZE-
1) );
if ( dwSizeInPage > dwSize ) dwSizeInPage =
dwSize;
AT24_WritePage(dwAddr, dwSizeInPage, Memory);
dwSize -=
dwSizeInPage;
Memory +=
dwSizeInPage;
dwAddr +=
dwSizeInPage;
// now it must be page alignment
}
}
转载于:https://www.cnblogs.com/shangdawei/archive/2013/04/28/3049775.html
相关资源:AT24C64 系列内存程序