This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] LAUNCHXL-F280025C:支持 F280025C 的 EEPROM AT24Cxx 分线板接口

Guru**** 2347250 points
Other Parts Discussed in Thread: C2000WARE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1307362/launchxl-f280025c-eeprom-at24cxx-breakout-board-interface-with-f280025c

器件型号:LAUNCHXL-F280025C
主题中讨论的其他器件:C2000WARE

尊敬的社区:  

我目前使用由 C2000Ware SDK 的"i2c_ex2_eeproM"和"i2c_ex4_eeprom_Polling"启发的 I2C 轮询方法来编写1字节写入和读取 EEPROM 示例

我尝试运行两个代码的示例,我无法写入或读取 AT24XX 分离板。

因此、我 在 i2c_ex4_eeprom_polling   示例中尝试了对现有库 i2cLib_FIFO_POLLING 在没有 bus_scan ()的情况下使用以下代码。  

您能为我介绍如何配置从 EEPROM 读取和写入

根据我从 SDK 获取的信息、按顺序调用了以下函数、如有必要、请检查更新  

到 i2c 主器件函数调用流程:

I2C_setDataCount ();

I2C_setConfig ();

I2C_setAddressMode ();

I2C_setTargetAddress ();

I2C_putData ();

I2C_sendStartCondition ();

//等待 Rx 数据

I2C_sendStopCondition ();

我在此附上了尽可能简单的代码、此后我还无法从 EEPROM 写入或读取数据  

#include "driverlib.h"
#include "device.h"
#include "i2cLib_FIFO_polling.h"

//
// Defines
//
#define EEPROM_ADDR 0x50

//
// Globals
//
struct I2CHandle EEPROM;

uint16_t TX_MsgBuffer[MAX_BUFFER_SIZE];
uint16_t RX_MsgBuffer[MAX_BUFFER_SIZE];
uint32_t ControlAddr;
uint16_t status;

void I2C_GPIO_init(void)
{
    // I2CA pins (SDAA / SCLA)
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SDAA, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SDAA, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SDAA, GPIO_QUAL_ASYNC);

    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCLA, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SCLA, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCLA, GPIO_QUAL_ASYNC);

    GPIO_setPinConfig(DEVICE_GPIO_CFG_SDAA);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_SCLA);
}

void I2Cinit(void)
{
    //myI2CA initialization
    I2C_disableModule(I2CA_BASE);
    I2C_initController(I2CA_BASE, DEVICE_SYSCLK_FREQ, 100000, I2C_DUTYCYCLE_50);
    I2C_setConfig(I2CA_BASE, I2C_CONTROLLER_SEND_MODE);
    I2C_setTargetAddress(I2CA_BASE, 0x50);
//    I2C_setOwnAddress(I2CA_BASE, 96); //I2CA address
    I2C_disableLoopback(I2CA_BASE);
    I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
    I2C_setDataCount(I2CA_BASE, 2);
    I2C_setAddressMode(I2CA_BASE, I2C_ADDR_MODE_7BITS);
    I2C_enableFIFO(I2CA_BASE);
    I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
    I2C_setFIFOInterruptLevel(I2CA_BASE, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);
    I2C_enableInterrupt(I2CA_BASE, I2C_INT_ADDR_TARGET | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
    I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);
    I2C_enableModule(I2CA_BASE);
}

//
// pass - Function to be called if data written matches data read
//
void
pass(void)
{
    asm("   ESTOP0");
    for(;;);
}

//
// fail - Function to be called if data written does NOT match data read
//
void fail(void)
{
    asm("   ESTOP0");
    for(;;);
}
void verifyEEPROMRead(void)
{
    uint16_t i;
    while(I2C_getStatus(I2CA_BASE) & I2C_STS_BUS_BUSY);

    for(i=0;i<EEPROM.NumOfDataBytes;i++)
    {
        if(RX_MsgBuffer[i] != TX_MsgBuffer[i])
        {
            //Transmitted data doesn't match received data
            //Fail condition. PC shouldn't reach here
            ESTOP0;
            fail();
        }
    }
}
//
// Main
//
void main()
{
    volatile int status = 0;

    uint16_t i;

    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // Initialize I2C pins
    //
    I2C_GPIO_init();

    //
    // Initialize PIE and clear PIE registers. Disable CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    I2Cinit();
    EEPROM.TargetAddr      = 0x50;
    EEPROM.base           = I2CA_BASE;
    EEPROM.pControlAddr   = &ControlAddr;
    EEPROM.NumOfAddrBytes = 2;
    EEPROM.pTX_MsgBuffer  = TX_MsgBuffer;
    EEPROM.pRX_MsgBuffer  = RX_MsgBuffer;
    EEPROM.NumOfAttempts  = 5;
    EEPROM.Delay_us       = 10;
    EEPROM.WriteCycleTime_in_us = 6000;    //10ms for EEPROM this code was tested

    //Example 1: EEPROM Byte Write
    //Write 11 to EEPROM address 0x0
    ControlAddr = 0x01;
    EEPROM.NumOfDataBytes = 1;
    TX_MsgBuffer[0]       = 11;

    status = I2C_ControllerTransmitter(&EEPROM);

    //Wait for EEPROM write cycle time
    //This delay is not mandatory. User can run their application code instead.
    //It is however important to wait for EEPROM write cycle time before you initiate
    //another read / write transaction
    DEVICE_DELAY_US(EEPROM.WriteCycleTime_in_us);

    //Example 2: EEPROM Byte Read
    //Make sure 11 is written to EEPROM address 0x0
    ControlAddr = 0x01;
    EEPROM.pControlAddr   = &ControlAddr;
    EEPROM.NumOfDataBytes = 1;
    status = I2C_ControllerReceiver(&EEPROM);

    while(I2C_getStatus(EEPROM.base) & I2C_STS_BUS_BUSY);

    verifyEEPROMRead();
}

请纠正我错的地方期待解决方案或提示.

在 TRM 中

'当此模块被配置为 I2C 总线上的一个主器件时、开始和停止条件可由 I2C 模块生成。'  

问:执行哪条指令后、我们可以观察 DSO 上的时钟和数据?

在本例中、无法在"void I2Cinit (void)"和"I2C_sendStartCondition (base);"之后立即查看任何示例程序的 SCL 和 SDA。

问:从任何 TI 电路板的软件和硬件两个方面给出了 I2C 调试的一般步骤。  

谢谢。此致、

Ajaykumar V

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    请预计节假日会造成延迟。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Opus Fontillas:

    快乐的假期,我会等待响应。

    问:哪个流程高于或低于一个流程是正确的?

    I2C_setDataCount ();

    I2C_setConfig ();

    I2C_setAddressMode ();

    I2C_setTargetAddress ();

    I2C_sendStartCondition ();

    I2C_putData ();(或) I2C_getData ();

    //等待 Rx 数据

    I2C_sendStopCondition ();

    问:在调用 I2C_sendStartCondition (base)之后、I2C_setTargetAddress ()函数中的目标地址是否会自动配置、并与读/写位一起?

    谢谢。此致、

    阿贾伊库马尔五世

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Ajaykumar:

    问题是您无法看到 SCL/SDAA、因此我建议看一下您的 I2C 和 GPIO 设置。 具体来说,我看到 I2C_setOwnAddress()函数已被禁用,但需要设置模块自身的地址。 然后将此函数中设置的地址与 I2C 控制器发送的目标地址进行比较。

    此时、您应该能够 相应地探测总线。 您的函数逻辑似乎正确。 我只想指出的是,   除了在 verifyEEPROMRead ()中使用 I2C_getStatus ()外,在 EEPROM 事务处理之后的 while 循环中使用了 I2C_getStatus (),这可能使程序卡在那一行上。 此外、 当您将 TX_MsgBuffer/RX_MsgBuffer 传递到第129-130行的指针时、TX_MsgBuffer/RX_MsgBuffer 当前是空的、因此我要看 i2c_ex4_eeprom_polling 示例、以了解如何 使用缓冲区

    艾什瓦里亚