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.

[参考译文] TMS320F28388D:F28388d / I2C 接口/从从器件读取多个字节的数据

Guru**** 2614265 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1064573/tms320f28388d-f28388d-i2c-interface-reading-multiple-bytes-of-data-from-slave

器件型号:TMS320F28388D
主题中讨论的其他器件:C2000WARE

您好、TI 技术团队!!

有一个与 I2C 读取相关的问题。

**目前的情况

1) 1)受控

主器件- F28388d

从站- IIS328DQ

2)进度。

读取/写入一个字节的数据

请参阅随附的代码。

3) 3)问答

情况1. 在代码中取消注释行100和注释行101。
状态= I2CRead (I2CB_BASE、24、32、缓冲器、1、 5);//将 CTRL_REG1读取到 CTRL_REG5寄存器
//status = I2CRad_T (I2CB_BASE、24、32、buffer、5); //将 CTRL_REG1读取到 CTRL_REG5寄存器

-->重复读取1字节数据五次。
-->从起始点寄存器地址连续读取以下五个寄存器值。 请参阅图1。
-->(ST / SAD + W / SAK / SUB / SAK / SR / SAD + R / SAK / DATA_n / NMAK / SP) X 5.


情况2. 在代码中注释行100和取消注释行101。
//status = I2CRead (I2CB_BASE、24、32、buffer、1、 5);//将 CTRL_REG1读取到 CTRL_REG5寄存器
状态= I2CRad_T (I2CB_BASE、24、32、buffer、5); //将 CTRL_REG1读取到 CTRL_REG5寄存器

-->起始点寄存器地址的值被读取5次(相同值)。 请参阅图2。
-->(ST / SAD + W / SAK / SUB / SAK / SR / SAD + R / SAK / Data1 / Data1 / Data1 / Data1 / Data1 / SP)

问:我想读取多字节数据并获得与情况1相同的结果。
-->(ST / SAD + W / SAK / SUB / SAK / SR / SAD + R / SAK / Data1 / MAK / DATA2 / MAK / DATA3 /.... / Data5/NMAK/SP)

如何修改附加代码中的'i2cRead_T'函数?

我需要帮助

请注意

JM LEE

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

    e2e.ti.com/.../TEST_5F00_CODE_5F00_20211222.txt

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

    Lee、

    请考虑修改 最新 C2000Ware 中提供的 i2c_ex6_EEPROM_interrupt.c 示例代码。 此示例使用 I2C 通过中断方法读取/写入"N"个字节。

    此致、

    曼诺伊

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

    您好、TI 技术团队!!

    有一个与 I2C 读取相关的问题。

    通过稍微修改 ex6 EEPROM 中断示例来执行调试。

    仍然、一个字节的读取/写入操作正常。

    但是、当读取读'N'字节时、会出现与之前代码相同的问题。

    这次、第五个寄存器(或第一个寄存器)地址的数据被读取5次并存储在 Rx 缓冲器中。

    请参阅修改后的示例代码。

    请详细查看!

    请注意

    JM LEE

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "i2cLib_FIFO_master_interrupt.h"
    
    #define BUFFER_SIZE 5
    //
    // Defines
    //
    #define EEPROM_SLAVE_ADDRESS        0x18
    
    //
    // Globals
    //
    
    struct I2CHandle EEPROM;
    struct I2CHandle *currentResponderPtr;                   // Used in interrupt
    uint16_t AvailableI2C_slaves[20];
    uint16_t TX_MsgBuffer[BUFFER_SIZE];
    uint16_t RX_MsgBuffer[BUFFER_SIZE];
    uint32_t ControlAddr;
    uint16_t status=0;
    
    //
    // Function Prototypes
    //
    
    interrupt void i2cFIFO_isr(void);
    interrupt void i2c_isr(void);
    void I2C_GPIO_init(void);
    void I2Cinit(void);
    
    //
    // Main
    //
    void main(void)
    {
        //
        // 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();
        //
        // Interrupts that are used in this example are re-mapped to ISR functions
        // found within this file.
        //
        Interrupt_register(INT_I2CB_FIFO, &i2cFIFO_isr);
    
        Interrupt_enable(INT_I2CB_FIFO);
    
        Interrupt_register(INT_I2CB, &i2c_isr);
    
        Interrupt_enable(INT_I2CB);
    
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //I2Cs connected to I2CA will be found in AvailableI2C_slaves buffer
        //after you run I2CBusScan function.
        uint16_t *pAvailableI2C_slaves = AvailableI2C_slaves;
        status = I2CBusScan(I2CB_BASE, pAvailableI2C_slaves);
    
        //uint16_t i;
    
        currentResponderPtr = &EEPROM;
    
        EEPROM.currentHandlePtr     = &EEPROM;
        EEPROM.SlaveAddr            = EEPROM_SLAVE_ADDRESS;
        EEPROM.WriteCycleTime_in_us = 10000;    //6ms for EEPROM this code was tested
        EEPROM.base = I2CB_BASE;
        EEPROM.pControlAddr = &ControlAddr;
        EEPROM.NumOfAddrBytes = 1;
    
    
        TX_MsgBuffer[0] = 0x07;
        TX_MsgBuffer[1] = 0x23;
        TX_MsgBuffer[2] = 0;
        TX_MsgBuffer[3] = 0;
        TX_MsgBuffer[4] = 0x03;
    
        ControlAddr = 0x20;   
        EEPROM.NumOfDataBytes = BUFFER_SIZE;
        EEPROM.pTX_MsgBuffer = TX_MsgBuffer;
        status = I2C_MasterTransmitter(&EEPROM);
        DEVICE_DELAY_US(EEPROM.WriteCycleTime_in_us);
    
    
        while (1)
        {        
            ControlAddr = 0x20;
            EEPROM.pControlAddr = &ControlAddr;
            EEPROM.pRX_MsgBuffer = RX_MsgBuffer;
            EEPROM.NumOfDataBytes = BUFFER_SIZE;
    
            status = I2C_MasterReceiver(&EEPROM);
            DEVICE_DELAY_US(EEPROM.WriteCycleTime_in_us);
    
        }
    
    
    }
    
    interrupt void i2c_isr(void)
    {
        uint16_t MasterSlave = HWREGH(currentResponderPtr->base + I2C_O_MDR);
    
        handleI2C_ErrorCondition(currentResponderPtr);
    
        if(MasterSlave & I2C_MDR_MST)
        {
            I2C_enableInterrupt(currentResponderPtr->base, I2C_INT_RXFF);
            I2C_clearInterruptStatus(currentResponderPtr->base,(I2C_INT_RXFF));
        }
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    }
    
    interrupt void i2cFIFO_isr(void)
    {
        Write_Read_TX_RX_FIFO(currentResponderPtr);
    
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    }
    
    
    void I2C_GPIO_init(void)
    {
        // I2CB pins (SDAA / SCLA)
        GPIO_setDirectionMode(35, GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(35, GPIO_PIN_TYPE_PULLUP);    
        GPIO_setMasterCore(35, GPIO_CORE_CPU1);
        GPIO_setQualificationMode(35, GPIO_QUAL_ASYNC);
    
        GPIO_setDirectionMode(40, GPIO_DIR_MODE_IN);
        GPIO_setPadConfig(40, GPIO_PIN_TYPE_PULLUP);    
        GPIO_setMasterCore(40, GPIO_CORE_CPU1);
        GPIO_setQualificationMode(40, GPIO_QUAL_ASYNC);
    
        GPIO_setPinConfig(GPIO_35_I2CB_SCL);
        GPIO_setPinConfig(GPIO_40_I2CB_SDA);
    
    }
    
    void I2Cinit(void)
    {
        I2C_disableModule(I2CB_BASE);
    
        I2C_initMaster(I2CB_BASE, DEVICE_SYSCLK_FREQ, 100000, I2C_DUTYCYCLE_50); // I2C configuration. Use a 100kHz I2CCLK with a 50% duty cycle.
        I2C_setConfig(I2CB_BASE, I2C_MASTER_SEND_MODE);
        I2C_setSlaveAddress(I2CB_BASE, 80);
        //I2C_setOwnSlaveAddress(I2CB_BASE, 96);
        I2C_disableLoopback(I2CB_BASE);
        I2C_setBitCount(I2CB_BASE, I2C_BITCOUNT_8);
        I2C_setDataCount(I2CB_BASE, 2);
        I2C_setAddressMode(I2CB_BASE, I2C_ADDR_MODE_7BITS);
        I2C_enableFIFO(I2CB_BASE);
        I2C_clearInterruptStatus(I2CB_BASE, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
        I2C_setFIFOInterruptLevel(I2CB_BASE, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);
        I2C_enableInterrupt(I2CB_BASE, I2C_INT_ADDR_SLAVE | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
        I2C_setEmulationMode(I2CB_BASE, I2C_EMULATION_FREE_RUN);
    
        I2C_enableModule(I2CB_BASE);
    }
    //
    // End of File
    //
    
    

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

    Jim、

    在 IIS328DQ 数据表中、它明确指出您需要通过设置 MSB 位来启用自动增量。 您的 ControlAddr 应为0xA0而不是0x20。 希望这可以解决这个问题。

    来自 IIS328DQ 数据表的示例代码段。

    对此,

    曼诺伊

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

    你好!!  曼诺伊

    非常感谢!

    ControlAddr = 0xA0;

    修改地址后、"N"字节 W/R 正常运行。

    下一次、我将详细了解数据表。

    总之、谢谢!

    请注意

    JM LEE