在PIC32MX上通过IC2写入EEPROM失败

时间:2012-10-05 09:28:05

标签: c pic i2c eeprom

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);
}
// ----------------------------------------------------------------------------

0 个答案:

没有答案