发 帖  
原厂入驻New
[问答] MCC I2C和24FC1026顺序读取和页面写入
630 MPLAB EEPROM
分享
大家好,使用MC24FC1026 EEPROM来存储数据,需要能够使用序列读取和Page写的这个IC提供。我看不出如何使用I2C的MCC实现并使这些功能正常工作。我可能错了,但是MCC代码只会做随机读取和字节W。仪式。我也不确定它是否能读取当前地址。这是正确的吗?如果有人能告诉我更多关于使用这个EEPROM的信息吗?项目信息:MPLAB X V4.10 MCC 3.55.1 PIC18F26K22谢谢!!


0
2018-10-10 10:14:28   评论 分享淘帖 邀请回答

相关问题

2个回答
您好,I2C驱动程序的头文件中的示例代码是正确的,只演示了使用I2CJMistMraveX(…)和I2CyMistRead,并没有真正考虑EEPROM设备的实际属性。做一个当前地址读,是最简单的处理,只需调用:用POIN唯一的障碍是当从芯片1到芯片2通过不同的I2C从地址时,当写入一个数据块时,只写单个字节是不必要的,使用时间很长,并且在存储器阵列中造成不必要的磨损,但是编写单个字节避免处理页面边界交叉所需的逻辑。这里是一个修改的示例代码,处理一些问题,它是24LC65,它有64字节页:对于24x1026页大小是128字节,因此逻辑应该相应地调整。TE缓冲器,以便在存储数据之前定位内存地址。直接从用户缓冲区传输写入数据将需要一些额外的欺骗。即使驱动程序本身没有阻塞,上面的代码也会等到传输完成。版本的I2C驱动程序在状态代码中有一些不同。代码是已经在另一个线程中发布的一些测试和示例代码的一部分:

*    Example test code for EEPROM MCHP24LC65 with I2C interface
*            ________
*       |o-oo|A0   Vcc|o-----o +
*       |o-oo|A1      |o  |--o SDA
*       |o-oo|A2   SCL|o--+--o SCL
*       |o  o|Vss  SDA|o--|  o
*       |---|----------------o GND
*               A0 = 1
*               A1 = 1
*               A2 = 0
*               A  = 0x53
*/
#include "mcc.h"
#include "I2C_Master.h"
#include "MCHP24LC65.h"

// Example code from I2C2.h
#define MCHP24AA512_RETRY_MAX       10    // define the retry count maximum
#define MCHP24LC65_ADDRESS          0x53    /* Actual I2C address. */
#define SLAVE_I2C_GENERIC_RETRY_MAX   10
#ifdef __PIC32MX
  #define I2C_DEVICE_TIMEOUT    8000    /* define slave timeout, 4360 ticks/byte during debugging */
#else                                    /* On PIC32MX running 80 MHz, 8000 ticks is 0.2 millisecond, */
  #define I2C_DEVICE_TIMEOUT      50    /* a little longer than transfer time for each byte, */
#endif                                    /* when I2C is running 100 kHz, and there are no other traffic causing delays for the driver. */
                                        /* Counting Timeout as test iterations need to scale with processor speed and transfer length. */

#ifdef __PIC32MX
static inline
uint32_t __attribute__(( always_inline, nomips16)) ReadTimer(void)
{
    uint32_t count;
    asm volatile("mfc0 %0, $9" : "=r"(count));
    return(count);
}
#else
    /* On chips without Core timer, just increment a counter, or use some other timing resource. */
static inline
uint32_t __attribute__((always_inline, nomips16)) ReadTimer(void)
{
    static uint32_t count;
    count++;
    return(count);
}
#endif


uint8_t MCHP24LC65_Write(    uint16_t dataAddress,    /* EEPROM Memory address. */
                            uint8_t *pData,            /* Pointer to user data buffer. */
                            uint16_t nCount)        /* Number of bytes to write. */
{
    // write to a EEPROM Device
    uint16_t    slaveDeviceAddress = MCHP24LC65_ADDRESS;
    uint16_t    counter = 0, icount;
    uint8_t        i,  retryCount;
    unsigned int    slaveTimeOut;
    static    uint8_t         writeBuffer[18];
    volatile static    I2C_MESSAGE_STATUS writeStatus = I2C_MESSAGE_PENDING;

    while (nCount > 0)
    {
        icount = nCount;                // number of bytes to write

        /* For a real EEPROM, it is a bad practice to write single bytes,
         * when a block of data is to be Written. */
        /* For a real MCHP24LC65, starting address + write_count should be less
         * than the next 64 byte boundary 0x003F */
        if ((dataAddress + nCount) > (dataAddress | 0x003F))
            icount = (dataAddress | 0x003F)     - (dataAddress    - 1);

        /* In this example code, the scratch array is limited at 16 Byte. */
        if (icount > 16)
            icount = 16;

        // Build the write buffer first
        // starting address of the EEPROM memory
        writeBuffer[0] = (dataAddress >> 8);                // high address
        writeBuffer[1] = (uint8_t)(dataAddress);            // low low address

            // data to be written
        i = 0;
        while (i < icount)
        {    writeBuffer[2+i] = *(pData +i);
            i++;
        }
            // Now it is possible that the slave device will be slow.
            // As a work around on these slaves, the application can
            // retry sending the transaction
        retryCount = 0;
        while(writeStatus != I2C_ERROR_FAIL)
        {    writeStatus = I2C_MESSAGE_START;
            slaveTimeOut = ReadTimer();        /* Start time */
                // write icount bytes to EEPROM (2 is the number of address bytes.)
            I2C1_MasterWrite(  writeBuffer,
                                2 + icount,
                                slaveDeviceAddress,
                                &writeStatus);

                // wait for the message to be sent or status has changed.
            while(writeStatus < I2C_MESSAGE_COMPLETE)    // == I2C_MESSAGE_PENDING)
            {

                /* Timeout is wrong, and PIC is fast, each Byte will use about 100 microsecond * 80 instructions/ microsecond */
                /* But EEPROM device that is active, will not acknowledge its address, until internal operation is completed.
                 * Then Trying to Redo a transfer that is still active, using the same buffer and Status word will only cause more problem. */
                /* This is just I2C transfer time, EEPROM internal write time is after message complete. */
                if ( ReadTimer() - slaveTimeOut > I2C_DEVICE_TIMEOUT * (1 + 2 + icount))
                    return (0);            /* Timeout expired. */ /* But Timeout here will not cancel task that is already queued. */
            }

            if    (writeStatus == I2C_MESSAGE_COMPLETE)
            {    dataAddress += icount;
                counter += icount;
                pData  += icount;
                nCount -= icount;
                break;
            }
                slaveTimeOut = ReadTimer();        /* New start time */
            if (writeStatus ==    I2C_MESSAGE_QUEUE_FULL)
            {                            /* Delay until timeout expire, for other transfer to complete. */
                while (ReadTimer() - slaveTimeOut < I2C_DEVICE_TIMEOUT * (1 + 2 + icount));
            }
            if (writeStatus ==  I2C_MESSAGE_ADDRESS_NO_ACK ||
                writeStatus ==  I2C_MESSAGE_DATA_NO_ACK)
            {
                // The device may be busy with internal operation, following
                // a previous write. Wait a millisecond before trying again.
                while (ReadTimer() - slaveTimeOut < I2C_DEVICE_TIMEOUT * 5);
            }
            // check for max retry and skip this byte
            if (retryCount >= SLAVE_I2C_GENERIC_RETRY_MAX)
                return (0);

            retryCount++;
        }
        if (writeStatus == I2C_MESSAGE_FAIL)
        {
            return (0);
        }
    }
    return counter;
}   


2018-10-10 10:33:56 评论

举报

谢谢你的回答,我看到我的选择是写我自己的C代码来做正确的或使用ASM(我以前做过,但不知道如何将ASM与我的C代码的其余部分)。我真的想读和写128个字节一次。我可以确保我不跨越页面边界,芯片将内存分为一半。你必须在控制字节中设置一个高位访问。我想Microchip会为自己的EEPROM发布一个I2C的驱动程序


2018-10-10 10:45:49 评论

举报

只有小组成员才能发言,加入小组>>

65个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表