哪位用过AT24C1024
我现在编写的AT24C1024程序,不知道什么原因,只能读写一半空间,我在编程时也加了页的控制,就是不能读写页设置1时空间,请大家给以指点,早出原因。非常感谢! 会不会是时序问题?回复【楼主位】lyq123456-----------------------------------------------------------------------
回复【楼主位】lyq123456
-----------------------------------------------------------------------
会不会是时序问题? 上图、上代码。 I can help you:
This chip has 2 different I2C addresses:
Like this ...
#define AT91C_EEPROM_I2C_ADDRESS_1 ( ( 0xA0 << 15 ) | AT91C_TWI_IADRSZ_2_BYTE ) //the first 64Kbyte
#define AT91C_EEPROM_I2C_ADDRESS_2 ( ( 0xA2 << 15 ) | AT91C_TWI_IADRSZ_2_BYTE ) //the second 64Kbyte
So the read application is like this:
S16 at24_write ( U32 a_adr, U8 a_val )
{
int mode_adr;
i2c_ok = 0;
#ifdef AT24_ERROR
return;
#endif
if ( a_adr & 0xFFFF0000 )
{
mode_adr = AT91C_EEPROM_I2C_ADDRESS_2;
a_adr &= 0x0000FFFF;
}
else
{
mode_adr = AT91C_EEPROM_I2C_ADDRESS_1;
}
if ( AT91F_TWI_WriteByte ( mypTWI, mode_adr, a_adr, (S8*)&a_val, 1 ) < 1000 )
i2c_ok = 1;
return i2c_ok;
} 回复【3楼】sgweilong
-----------------------------------------------------------------------
能加一下QQ吗,帮我解决一下,849438298,非常感谢 void EEPROM_ByteWrite(unsigned long addr, unsigned char dat)
{
unsigned char SMB_SINGLEBYTE_OUT; // Global holder for single byte writes.
while (SMB_BUSY); // Wait for SMBus to be free.
SMB_BUSY = 1; // Claim SMBus (set to busy)
// Set SMBus ISR parameters
TARGET = EEPROM_ADDR; // Set target slave address
SMB_RW = WRITE; // Mark next transfer as a write
SMB_SENDWORDADDR = 1; // Send Word Address after Slave Address
SMB_RANDOMREAD = 0; // Do not send a START signal after the word address
SMB_ACKPOLL = 1; // Enable Acknowledge Polling (The ISR
// will automatically restart the
// transfer if the slave does not
// acknoledge its address.
// Specify the Outgoing Data
WORD_ADDR_order=0;
//ADDR_D0=0;
//ADDR_D0=addr&0x01;
//ADDR_D0 |=(addr>>16)&0x01;
// if(addr>0xffff)
if(addr & 0xffff0000)
{
SMB_RW |= 0x02;
}
else {SMB_RW |= 0x00;} // ADDR_D0=0x02;
// else ADDR_D0=0x00;
WORD_ADDR_H = (addr>>8)&0xff; // Set the target address in the
// EEPROM's internal memory space
WORD_ADDR_L = addr&0xff;
SMB_SINGLEBYTE_OUT = dat; // Store <dat> (local variable) in a
// global variable so the ISR can read
// it after this function exits
pSMB_DATA_OUT = &SMB_SINGLEBYTE_OUT;// The outgoing data pointer points to the <dat> variable
SMB_DATA_LEN = 1; // Specify to ISR that the next transfer
// will contain one data byte
STA = 1; // Initiate SMBus Transfer
}
//-----------------------------------------------------------------------------
// EEPROM_WriteArray ()
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) unsigned char dest_addr - beginning address to write to in the EEPROM
// range is full range of character: 0 to 255
//
// 2) unsigned char* src_addr - pointer to the array of data to be written
// range is full range of character: 0 to 255
//
// 3) unsigned char len - length of the array to be written to the EEPROM
// range is full range of character: 0 to 255
//
// Writes <len> data bytes to the EEPROM slave specified by the <EEPROM_ADDR>
// constant.
//
void EEPROM_WriteArray(unsigned long dest_addr, unsigned char* src_addr,
unsigned char len)
{
unsigned char i;
//// unsigned char* pData = (unsigned char*) src_addr;
unsigned char* pData;
pData = src_addr;
WP = 0; // allows normal write operations
PCA0CPH4 = 0x00; // 喂狗
for( i = 0; i < len; i++ )
{
EEPROM_ByteWrite(dest_addr++, *pData++);
}
// WP = 1; // write operations to the memory are inhibited
}
//-----------------------------------------------------------------------------
// EEPROM_ReadArray ()
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters :
// 1) unsigned char* dest_addr - pointer to the array that will be filled
// with the data from the EEPROM
// range is full range of character: 0 to 255
//
// 2) unsigned char src_addr - beginning address to read data from the EEPROM
// range is full range of character: 0 to 255
//
// 3) unsigned char len - length of the array to be read from the EEPROM
// range is full range of character: 0 to 255
//
// Reads up to 256 data bytes from the EEPROM slave specified by the
// <EEPROM_ADDR> constant.
//
void EEPROM_ReadArray (unsigned char* dest_addr, unsigned long src_addr,
unsigned char len)
{
while (SMB_BUSY); // Wait for SMBus to be free.
SMB_BUSY = 1; // Claim SMBus (set to busy)
// Set SMBus ISR parameters
TARGET = EEPROM_ADDR; // Set target slave address
SMB_RW = WRITE; // A random read starts as a write
// then changes to a read after
// the repeated start is sent. The
// ISR handles this switchover if
// the <SMB_RANDOMREAD> bit is set.
SMB_SENDWORDADDR = 1; // Send Word Address after Slave Address
SMB_RANDOMREAD = 1; // Send a START after the word address
SMB_ACKPOLL = 1; // Enable Acknowledge Polling
// Specify the Incoming Data
WORD_ADDR_order=0;
if(src_addr & 0xffff0000)
{
SMB_RW |= 0x02;
}
else {SMB_RW |= 0x00;}
//ADDR_D0=0;
//ADDR_D0=src_addr&0x01;
// ADDR_D0 |=(src_addr>>16)&0x01;
//if(src_addr>0xffff)
// ADDR_D0=0x02;
//else ADDR_D0=0x00;
WORD_ADDR_H = (src_addr>>8)&0xff; // Set the target address in the
// EEPROM's internal memory space
WORD_ADDR_L = src_addr&0xff;
// Set the the incoming data pointer
pSMB_DATA_IN = (unsigned char*) dest_addr;
SMB_DATA_LEN = len; // Specify to ISR that the next transfer will contain <len> data bytes
STA = 1; // Initiate SMBus Transfer
while(SMB_BUSY); // Wait until data is read
} void SMBus_ISR (void) interrupt 7
{
bit FAIL = 0; // Used by the ISR to flag failed
// transfers
static char i; // Used by the ISR to count the
// number of data bytes sent or
// received
static bit SEND_START = 0; // Send a start
switch (SMB0CN & 0xF0) // Status vector
{
// Master Transmitter/Receiver: START condition transmitted.
case SMB_MTSTA:
PCA0CPH4 = 0x00; // watchdog
SMB0DAT = TARGET; // Load address of the target slave
SMB0DAT &= 0xFC; // Clear the LSB of the address for the R/W bit
//SMB0DAT |=0x00;
SMB0DAT |= SMB_RW;//(SMB_RW|ADDR_D0); // Load R/W bit
STA = 0; // Manually clear START bit
i = 0; // Reset data byte counter
break;
// Master Transmitter: Data byte (or Slave Address) transmitted
case SMB_MTDB:
if (ACK) // Slave Address or Data Byte
{ // Acknowledged?
if (SEND_START)
{
STA = 1;
SEND_START = 0;
break;
}
if(SMB_SENDWORDADDR) // Are we sending the word address?
{
if(WORD_ADDR_order==0)
{
SMB0DAT = WORD_ADDR_H; // Send first word address
WORD_ADDR_order=1;
break;
}
if(WORD_ADDR_order==1)
{
SMB_SENDWORDADDR = 0; // Clear flag
SMB0DAT = WORD_ADDR_L; // Send word address
if (SMB_RANDOMREAD)
{
SEND_START = 1; // Send a START after the next ACK cycle
SMB_RW = READ;
}
break;
}
}
//=================================================================================
if (SMB_RW==WRITE) // Is this transfer a WRITE?
{
if (i < SMB_DATA_LEN) // Is there data to send?
{
SMB0DAT = *pSMB_DATA_OUT; // send data byte
pSMB_DATA_OUT++; // increment data out pointer
i++; // increment number of bytes sent
}
else
{
STO = 1; // Set STO to terminte transfer
SMB_BUSY = 0; // Clear software busy flag
}
}
else {} // If this transfer is a READ,
// then take no action. Slave
// address was transmitted. A
// separate 'case' is defined
// for data byte recieved.
}
else // If slave NACK,
{
if(SMB_ACKPOLL)
{
STA = 1; // Restart transfer
}
else
{
FAIL = 1; // Indicate failed transfer
} // and handle at end of ISR
}
break;
// Master Receiver: byte received
case SMB_MRDB:
if ( i < SMB_DATA_LEN ) // Is there any data remaining?
{
*pSMB_DATA_IN = SMB0DAT; // Store received byte
pSMB_DATA_IN++; // Increment data in pointer
i++; // Increment number of bytes received
ACK = 1; // Set ACK bit (may be cleared later in the code)
}
if (i == SMB_DATA_LEN) // This is the last byte
{
SMB_BUSY = 0; // Free SMBus interface
ACK = 0; // Send NACK to indicate last byte of this transfer
STO = 1; // Send STOP to terminate transfer
}
break;
default:
FAIL = 1; // Indicate failed transfer and handle at end of ISR
break;
}
if (FAIL) // If the transfer failed,
{
SMB0CF &= ~0x80; // Reset communication
SMB0CF |= 0x80;
STA = 0;
STO = 0;
ACK = 0;
SMB_BUSY = 0; // Free SMBus
FAIL = 0;
}
SI = 0; 回复【3楼】sgweilong
-----------------------------------------------------------------------
你怎么左移位15位,不是16位吗? 回复【7楼】lyq123456
-----------------------------------------------------------------------
I use ARM7, the structure is some different from normal 51 MCU. The RD and WR bit is added by MCU itself. 我现在只能读一页数据,另一页读不出,不知道什么原因 Should can.
For read, no "page" at all. For write, it will have a 256-byte page write limitation.
If you can read half 64Kbyte, the other half is the same, only the chip address is different.
1pc at1024 = 2pcs at512. 我认为在A0、A2的有问题;
但是我是按要求写的。怎么只能读A1的数据,不能读A3时的数据,不知什么原因。 检查下你那片子,是否是真的?
或者说就像我们现在的U盘,是被1024了? 芯片上标识是
ATMLH016
2GB 2
9H3615B
不知道这个是不是1024的
现在只能读64K的地址 调试了几天,都是能读存64KB数据,另一半还是读存不出来。改为AT24C1024W芯片事事 一片1024相当于挂了两片512;访问的时候第一片地址为“0xa0”第二片为“0xa2”,要切换地址才行
页:
[1]