PIC:PIC32MX564F128L
EEPROM:24AA16
我已经把C的一些代码放在一起,用来读取&通过I2C写入外部EEPROM。 当我使用这些方法写一个字节,然后再读回来进行验证时,它可以工作。 如果我改变了写入位置,它就可以工作,所以我认为寻址是有效的,而且我读回的字节与写入相匹配,因此看起来也可以工作。 到目前为止一切都很好!
然后我扩展了代码以使用相同的例程100次,在相邻位置写入不同的字节。 I.E.在位置x到x + 99中写入值0到99。 然后我继续回读100个位置以验证写入,这就是它出错的地方。
从各种测试中可以看出,write方法在同一位置执行所有写操作,因为read方法从第一个位置获取最后一个值(99),而没有任何内容(0xFF)来自其他地方!
示波器显示时钟良好,数据线切换,我期望单次写入工作。
PIC上的调试显示方法使用的地址是顺序的,所以我有点难以理解为什么所有的写操作都在同一个位置执行!我可以更改此位置,但它始终只使用所有值的第一个字节。
任何人都知道可能出现什么问题?
我的代码在这里,入口点是testEeprom():
// ----------------------------------------------------------------------------
#include "eeprom.h"
//#define _PLIB_DISABLE_LEGACY
#include <plib.h>
//// ----------------------------------------------------------------------------
#define SYS_CLOCK (80000000L)
#define GetSystemClock() (SYS_CLOCK)
#define GetPeripheralClock() (SYS_CLOCK / 2)
#define GetInstructionClock() (SYS_CLOCK)
#define I2C_CLOCK_FREQ 100000
#define EEPROM_I2C_BUS I2C1
#define EEPROM_ADDRESS 0x50 // 0b1010000 Serial EEPROM address
#define EEPROM_STORAGE_LOCATION 0x0100
#define DATA_ARRAY_SIZE 100
// ----------------------------------------------------------------------------
UINT8 EEPROM_Data_Array[DATA_ARRAY_SIZE];
UINT8 EEPROM_Data_Array_RX[DATA_ARRAY_SIZE];
BOOL EEPROM_Success;
I2C_7_BIT_ADDRESS SlaveAddress;
// ----------------------------------------------------------------------------
void i2c_wait(unsigned int cnt)
{
while (--cnt)
{
Nop();
Nop();
} // while
}
// ----------------------------------------------------------------------------
BOOL StartTransfer(BOOL restart)
{
I2C_STATUS status;
// Send the Start (or Restart) signal
if (restart)
{
I2CRepeatStart(EEPROM_I2C_BUS);
}
else
{
// Wait for the bus to be idle, then start the transfer
while (!I2CBusIsIdle(EEPROM_I2C_BUS));
if (I2CStart(EEPROM_I2C_BUS) != I2C_SUCCESS)
{
debugTrace("I2C Error: Bus collision during transfer Start\r\n");
return FALSE;
}
}
// Wait for the signal to complete
do
{
status = I2CGetStatus(EEPROM_I2C_BUS);
}
while (!(status & I2C_START));
return TRUE;
}
// ----------------------------------------------------------------------------
BOOL TransmitOneByte(UINT8 data)
{
// Wait for the transmitter to be ready
while (!I2CTransmitterIsReady(EEPROM_I2C_BUS));
// Transmit the byte
if (I2CSendByte(EEPROM_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION)
{
debugTrace("I2C Error: I2C Master Bus Collision\r\n");
return FALSE;
}
// Wait for the transmission to finish
while (!I2CTransmissionHasCompleted(EEPROM_I2C_BUS));
return TRUE;
}
// ----------------------------------------------------------------------------
void StopTransfer(void)
{
I2C_STATUS status;
// Send the Stop signal
I2CStop(EEPROM_I2C_BUS);
// Wait for the signal to complete
do
{
status = I2CGetStatus(EEPROM_I2C_BUS);
}
while (!(status & I2C_STOP));
}
// ----------------------------------------------------------------------------
void initIcd()
{
UINT32 actualClock;
EEPROM_Success = TRUE;
// Set the I2C baudrate
actualClock = I2CSetFrequency(EEPROM_I2C_BUS, GetPeripheralClock(), I2C_CLOCK_FREQ);
if (abs(actualClock - I2C_CLOCK_FREQ) > I2C_CLOCK_FREQ / 10)
{
debugTrace("Error: I2C1 clock frequency (%u) error exceeds 10%%.\r\n", (unsigned) actualClock);
}
// Enable the I2C bus
I2CEnable(EEPROM_I2C_BUS, TRUE);
}
// ----------------------------------------------------------------------------
// Send the data to EEPROM to program one location
// ----------------------------------------------------------------------------
void txIcd(unsigned int address, unsigned char value)
{
BOOL Acknowledged;
int Index;
UINT8 i2cData[4];
int DataSz;
EEPROM_Success = TRUE;
// Initialize the data buffer
I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_WRITE);
i2cData[0] = SlaveAddress.byte;
i2cData[1] = address >> 8; // EEPROM location to program (high address byte)
i2cData[2] = address & 0xFF; // EEPROM location to program (low address byte)
i2cData[3] = value; // EEPROM location to program (low address byte)
DataSz = 4;
// Start the transfer to write data to the EEPROM
if (!StartTransfer(FALSE))
{
debugTrace("I2C Error: Can't Start Transfer TX (1)\r\n");
return;
}
// Transmit all header
Index = 0;
while (EEPROM_Success && (Index < DataSz))
{
// Transmit a byte
if (TransmitOneByte(i2cData[Index]))
{
// Advance to the next byte
Index++;
// Verify that the byte was acknowledged
if (!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
{
debugTrace("I2C Error: Sent byte was not acknowledged (1)\r\n");
EEPROM_Success = FALSE;
}
}
else
{
EEPROM_Success = FALSE;
}
}
// End the transfer (hang here if an error occured)
StopTransfer();
if (!EEPROM_Success)
{
debugTrace("I2C Error: No Success on TX (1)\r\n");
return;
}
// Wait for EEPROM to complete write process, by polling the ack status.
Acknowledged = FALSE;
do
{
// Start the transfer to address the EEPROM
if (!StartTransfer(FALSE))
{
debugTrace("I2C Error: Can't Start Transfer TX (2)\r\n");
return;
}
// Transmit just the EEPROM's address
if (TransmitOneByte(SlaveAddress.byte))
{
// Check to see if the byte was acknowledged
Acknowledged = I2CByteWasAcknowledged(EEPROM_I2C_BUS);
}
else
{
EEPROM_Success = FALSE;
}
// End the transfer (stop here if an error occured)
StopTransfer();
if (!EEPROM_Success)
{
debugTrace("I2C Error: No Success on TX (2)\r\n");
return;
}
}
while (Acknowledged != TRUE);
}
// ----------------------------------------------------------------------------
// Read the data back from the EEPROM.
// ----------------------------------------------------------------------------
unsigned char rxIcd(unsigned int address)
{
UINT8 i2cbyte;
UINT8 i2cData[3];
int DataSz;
int Index;
EEPROM_Success = TRUE;
// Initialize the data buffer
I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_WRITE);
i2cData[0] = SlaveAddress.byte;
i2cData[1] = address >> 8; // EEPROM location to program (high address byte)
i2cData[2] = address & 0xFF; // EEPROM location to program (low address byte)
DataSz = 3;
// Start the transfer to write data to the EEPROM
if (!StartTransfer(FALSE))
{
debugTrace("I2C Error: Can't Start Transfer TX (1)\r\n");
return;
}
// Transmit all header
Index = 0;
while (EEPROM_Success && (Index < DataSz))
{
// Transmit a byte
if (TransmitOneByte(i2cData[Index]))
{
// Advance to the next byte
Index++;
}
else
{
EEPROM_Success = FALSE;
}
// Verify that the byte was acknowledged
if (!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
{
debugTrace("I2C Error: Sent byte was not acknowledged (1)\r\n");
EEPROM_Success = FALSE;
}
}
// Restart and send the EEPROM's internal address to switch to a read transfer
if (EEPROM_Success)
{
// Send a Repeated Started condition
if (!StartTransfer(TRUE))
{
debugTrace("I2C Error: Can't Start Transfer TX (4)\r\n");
return;
}
// Transmit the address with the READ bit set
I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_READ);
if (TransmitOneByte(SlaveAddress.byte))
{
// Verify that the byte was acknowledged
if (!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
{
debugTrace("I2C Error: Sent byte was not acknowledged (3)\r\n");
EEPROM_Success = FALSE;
}
}
else
{
EEPROM_Success = FALSE;
}
}
// Read the data from the desired address
if (EEPROM_Success)
{
if (I2CReceiverEnable(EEPROM_I2C_BUS, TRUE) == I2C_RECEIVE_OVERFLOW)
{
debugTrace("I2C Error: I2C Receive Overflow\r\n");
EEPROM_Success = FALSE;
}
else
{
while (!I2CReceivedDataIsAvailable(EEPROM_I2C_BUS));
i2cbyte = I2CGetByte(EEPROM_I2C_BUS);
}
}
// End the transfer (stop here if an error occured)
StopTransfer();
if (!EEPROM_Success)
{
debugTrace("I2C Error: No Success on TX (3)\r\n");
return;
}
return i2cbyte;
}
// ----------------------------------------------------------------------------
void testEeprom(void)
{
unsigned int i;
BOOL failed = FALSE;
unsigned char value;
// Create & Write 100 byte array
for (i = 0; i < DATA_ARRAY_SIZE; i++)
{
EEPROM_Data_Array[i] = i;
initIcd();
txIcd(EEPROM_STORAGE_LOCATION + i, EEPROM_Data_Array[i]);
StopTransfer();
I2CEnable(EEPROM_I2C_BUS, FALSE);
} // for i
// Read back & varify data against array
for (i = 0; i < DATA_ARRAY_SIZE; i++)
{
initIcd();
value = rxIcd(EEPROM_STORAGE_LOCATION + i);
if (EEPROM_Data_Array[i] != value)
{
failed = TRUE;
break;
}
StopTransfer();
I2CEnable(EEPROM_I2C_BUS, FALSE);
} // for i
if (failed == FALSE)
{
debugTrace("I2C SUCCESS\r\n");
}
else
{
debugTrace("I2C FAILED %d: %d != %d\r\n", i, value, EEPROM_Data_Array[i]);
}
while(1);
}
// ----------------------------------------------------------------------------