0

图片:PIC32MX564F128L

EEPROM:24AA16

我已经用 C 语言为 PIC 编写了一些代码,以通过 I2C 读取和写入外部 EEPROM。当我使用这些方法写入单个字节,然后再次读取它以进行验证时,它可以工作。如果我更改写入位置,它会起作用,所以我认为寻址是有效的,并且我读回的字节与写入匹配,所以这似乎也有效。到目前为止一切都很好!

然后我将代码扩展为使用相同的例程 100 次,在相邻位置写入不同的字节。IE 在位置 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);
}
// ----------------------------------------------------------------------------
4

0 回答 0