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.

[参考译文] TMS320F280049C:当给出 START 条件命令时、Tms320f280049m I2C SDA 和 SCL 引脚会下拉

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

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1129949/tms320f280049c-tms320f280049m-i2c-sda-and-scl-pins-go-pull-down-when-start-condition-command-is-given

器件型号:TMS320F280049C
主题中讨论的其他器件:TMS320F280049MC2000WARE

你(们)好。

使用 TMS320F280049m 微控制器实现 I2C 时遇到问题。

控制器正在尝试与温度传感器通信。

完成 I2C 初始化之后。 我已给予足够的延迟使巴士繁忙标志趋稳(以读取正确的 BB 标志)。

初始化后、我通过在发送非重复模式中生成从地址0x48的起始条件来开始通信。 发出此命令后 、SCL 和 SDA 引脚立即变为0v、总线忙标志卡在1。 它会一直保持在那里、在重置 I2C 并尝试开始通信后、同样的事情也会重复。 我想知道发生了什么。

在 Schematic Pull Restore 中,值为:10k 欧姆,Vcc 为3.3V。 请告诉我是怎么出错的。

 (笑声)

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

    您的温度传感器在传输目标(从器件)地址时是否确认? 这是第一步。

    此外、我建议您查看 I2C 示例的 driverlib 版本。

    C:\ti\c2000\C2000Ware_4_01_00_00\driverlib\f28004x\examples\i2c

    示例:I2C_ex4_EEPROM_POLLING

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

    您好、Manoj、

    感谢您的回复。

    我尝试了以下示例代码。 我遇到了相同的问题。

    在这里、我的系统时钟是92.16MHz。 我希望 GPIO0&1作为 I2C 控制信号。 我将 SCL 时钟设置为256kHz。

    //#############################################################################
    //
    // FILE:   i2c_ex2_eeprom.c
    //
    // TITLE:  I2C EEPROM
    //
    //! \addtogroup driver_example_list
    //! <h1>I2C EEPROM</h1>
    //!
    //! This program will write 1-14 words to EEPROM and read them back. The data
    //! written and the EEPROM address written to are contained in the message
    //! structure, i2cMsgOut. The data read back will be contained in the message
    //! structure i2cMsgIn.
    //!
    //! \b External \b Connections on Control card\n
    //!  - Connect external I2C EEPROM at address 0x50
    //!  - Connect GPIO32/SDAA on controlCARD to external EEPROM SDA (serial data) pin
    //!  - Connect GPIO33/SCLA on controlCARD to external EEPROM SCL (serial clock) pin
    //!
    //! \b External \b Connections on Launchpad\n
    //!  - Connect external I2C EEPROM at address 0x50
    //!  - Connect GPIO35/SDAA on Launchpad to external EEPROM SDA (serial data) pin
    //!  - Connect GPIO37/SCLA on Launchpad to external EEPROM SCL (serial clock) pin
    
    //! \b Watch \b Variables \n
    //!  - \b i2cMsgOut - Message containing data to write to EEPROM
    //!  - \b i2cMsgIn - Message containing data read from EEPROM
    //!
    //
    //#############################################################################
    //
    //
    // $Copyright:
    // Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    //
    // Defines
    //
    #define SLAVE_ADDRESS               0x48
    #define TEMP_REG_ADDR            0x00
    #define EEPROM_LOW_ADDR             0x30
    #define NUM_BYTES                   2
    #define MAX_BUFFER_SIZE             2      // Max is currently 14 because of
                                                // 2 address bytes and the 16-byte 
                                                // FIFO
    
    //
    // I2C message states for I2CMsg struct
    //
    #define MSG_STATUS_INACTIVE         0x0000 // Message not in use, do not send
    #define MSG_STATUS_SEND_WITHSTOP    0x0010 // Send message with stop bit
    #define MSG_STATUS_WRITE_BUSY       0x0011 // Message sent, wait for stop
    #define MSG_STATUS_SEND_NOSTOP      0x0020 // Send message without stop bit
    #define MSG_STATUS_SEND_NOSTOP_BUSY 0x0021 // Message sent, wait for ARDY
    #define MSG_STATUS_RESTART          0x0022 // Ready to become master-receiver
    #define MSG_STATUS_READ_BUSY        0x0023 // Wait for stop before reading data
    
    //
    // Error messages for read and write functions
    //
    #define ERROR_BUS_BUSY              0x1000
    #define ERROR_STOP_NOT_READY        0x5555
    #define SUCCESS                     0x0000
    
    //
    // Typedefs
    //
    struct I2CMsg {
        uint16_t msgStatus;                  // Word stating what state msg is in.
                                             // See MSG_STATUS_* defines above.
        uint16_t slaveAddr;                  // Slave address tied to the message.
        uint16_t numBytes;                   // Number of valid bytes in message.
        uint16_t temperature_reg_addr;             // EEPROM address of data associated
                                             // with message (high byte).
        uint16_t msgBuffer[MAX_BUFFER_SIZE]; // Array holding message data.
    };
    
    //
    // Globals
    //
    struct I2CMsg i2cMsgOut = {MSG_STATUS_SEND_WITHSTOP,
                               SLAVE_ADDRESS,
                               NUM_BYTES,
                               TEMP_REG_ADDR,
                               EEPROM_LOW_ADDR,
                               0x01,                // Message bytes
                               0x23,
                               0x45,
                               0x67,
                               0x89,
                               0xAB,
                               0xCD,
                               0xEF};
    struct I2CMsg i2cMsgIn  = {MSG_STATUS_SEND_NOSTOP,
                               SLAVE_ADDRESS,
                               NUM_BYTES,
                               TEMP_REG_ADDR};
    
    struct I2CMsg *currentMsgPtr;                   // Used in interrupt
    
    uint16_t passCount = 0;
    uint16_t failCount = 0;
    
    //
    // Function Prototypes
    //
    void initI2C(void);
    uint16_t readData(struct I2CMsg *msg);
    uint16_t writeData(struct I2CMsg *msg);
    
    void fail(void);
    void pass(void);
    
    __interrupt void i2cAISR(void);
    
    //
    // Main
    //
    void main(void)
    {
        uint16_t error;
        uint16_t i;
    
    #if 0
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pullups.
        //
        Device_initGPIO();
    
        //
        // Initialize GPIOs 32 and 33 (35 and 37 on LaunchPad) 
        // for use as SDA A and SCL A respectively
        //
        GPIO_setPinConfig(DEVICE_GPIO_CFG_SDAA);
        GPIO_setPadConfig(DEVICE_GPIO_PIN_SDAA, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(DEVICE_GPIO_PIN_SDAA, GPIO_QUAL_ASYNC);
    
        GPIO_setPinConfig(DEVICE_GPIO_CFG_SCLA);
        GPIO_setPadConfig(DEVICE_GPIO_PIN_SCLA, GPIO_PIN_TYPE_PULLUP);
        GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCLA, GPIO_QUAL_ASYNC);
    #endif
    
    EALLOW;
    
    /* Configuring GPIO0 as SDA */
    GpioCtrlRegs.GPAGMUX1.bit.GPIO0 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 2;
    
    /* Enable Pull Up */
    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;
    
    /* Set Qualification as ASYNCH Only */
    GpioCtrlRegs.GPAQSEL1.bit.GPIO0 = 3;
    
    /* Configuring GPIO0 as SCL */
    GpioCtrlRegs.GPAGMUX1.bit.GPIO1 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 2;
    
    /* Enable Pull Up */
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;
    
    /* Set Qualification as ASYNCH Only */
    GpioCtrlRegs.GPAQSEL1.bit.GPIO1 = 3;
    
    EDIS;
    
        //
        // 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();
    
        //
        // Interrupts that are used in this example are re-mapped to ISR functions
        // found within this file.
        //
        Interrupt_register(INT_I2CA, &i2cAISR);
    
        //
        // Set I2C use, initializing it for FIFO mode
        //
        initI2C();
    
        //
        // Clear incoming message buffer
        //
        for (i = 0; i < MAX_BUFFER_SIZE; i++)
        {
            i2cMsgIn.msgBuffer[i] = 0x0000;
        }
    
        //
        // Set message pointer used in interrupt to point to outgoing message
        //
        currentMsgPtr = &i2cMsgIn;
    
        //
        // Enable interrupts required for this example
        //
        Interrupt_enable(INT_I2CA);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        //
        // Loop indefinitely
        //
        while(1)
        {
            //
            // **** Write data to EEPROM section ****
            //
            // Check the outgoing message to see if it should be sent. In this
            // example it is initialized to send with a stop bit.
            //
            if(0)
            {
                //
                // Send the data to the EEPROM
                //
                error = writeData(&i2cMsgOut);
    
                //
                // If communication is correctly initiated, set msg status to busy
                // and update currentMsgPtr for the interrupt service routine.
                // Otherwise, do nothing and try again next loop. Once message is
                // initiated, the I2C interrupts will handle the rest. See the
                // function i2cAISR().
                //
                if(error == SUCCESS)
                {
                    currentMsgPtr = &i2cMsgOut;
                    i2cMsgOut.msgStatus = MSG_STATUS_WRITE_BUSY;
                }
            }
    
            //
            // **** Read data from EEPROM section ****
            //
            // Check outgoing message status. Bypass read section if status is
            // not inactive.
            //
            if (1)
            {
                //
                // Check incoming message status
                //
                if(i2cMsgIn.msgStatus == MSG_STATUS_SEND_NOSTOP)
                {
                    //
                    // Send EEPROM address setup
                    //
                    while(readData(&i2cMsgIn) != SUCCESS)
                    {
                        //
                        // Maybe setup an attempt counter to break an infinite
                        // while loop. The EEPROM will send back a NACK while it is
                        // performing a write operation. Even though the write
                        // is complete at this point, the EEPROM could still be
                        // busy programming the data. Therefore, multiple
                        // attempts are necessary.
                        //
                    }
    
                  //
                  // Update current message pointer and message status
                  //
                  currentMsgPtr = &i2cMsgIn;
                  i2cMsgIn.msgStatus = MSG_STATUS_SEND_NOSTOP_BUSY;
               }
    
                //
                // Once message has progressed past setting up the internal address
                // of the EEPROM, send a restart to read the data bytes from the
                // EEPROM. Complete the communique with a stop bit. msgStatus is
                // updated in the interrupt service routine.
                //
                else if(i2cMsgIn.msgStatus == MSG_STATUS_RESTART)
                {
                    //
                    // Read data portion
                    //
                    while(readData(&i2cMsgIn) != SUCCESS)
                    {
                        //
                        // Maybe setup an attempt counter to break an infinite
                        // while loop.
                        //
                    }
    
                    //
                    // Update current message pointer and message status
                    //
                    currentMsgPtr = &i2cMsgIn;
                    i2cMsgIn.msgStatus = MSG_STATUS_READ_BUSY;
                }
            }
        }
    }
    
    //
    // Function to configure I2C A in FIFO mode.
    //
    void initI2C()
    {
        //
        // Must put I2C into reset before configuring it
        //
        I2C_disableModule(I2CA_BASE);
    
        //
        // I2C configuration. Use a 256kHz I2CCLK with a 50% duty cycle.
        //
        I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 256000, I2C_DUTYCYCLE_50);  //DEVICE_SYSCLK_FREQ = 92.16MHz
        I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
        I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS);
        I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);
    
        //
        // Enable stop condition and register-access-ready interrupts
        //
        I2C_enableInterrupt(I2CA_BASE, I2C_INT_STOP_CONDITION |
                                       I2C_INT_REG_ACCESS_RDY);
    
        //
        // FIFO configuration
        //
        I2C_enableFIFO(I2CA_BASE);
        I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_RXFF | I2C_INT_TXFF);
    
        //
        // Configuration complete. Enable the module.
        //
        I2C_enableModule(I2CA_BASE);
    }
    
    //
    // Function to send the data that is to be written to the EEPROM
    //
    uint16_t writeData(struct I2CMsg *msg)
    {
        uint16_t i;
    
        //
        // Wait until the STP bit is cleared from any previous master
        // communication. Clearing of this bit by the module is delayed until after
        // the SCD bit is set. If this bit is not checked prior to initiating a new
        // message, the I2C could get confused.
        //
        if(I2C_getStopConditionStatus(I2CA_BASE))
        {
            return(ERROR_STOP_NOT_READY);
        }
    
        //
        // Setup slave address
        //
        I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS);
    
        //
        // Check if bus busy
        //
        if(I2C_isBusBusy(I2CA_BASE))
        {
            return(ERROR_BUS_BUSY);
        }
    
        //
        // Setup number of bytes to send msgBuffer and address
        //
        I2C_setDataCount(I2CA_BASE, (msg->numBytes + 2));
    
        //
        // Setup data to send
        //
        I2C_putData(I2CA_BASE, msg->temperature_reg_addr);
        I2C_putData(I2CA_BASE, msg->memoryLowAddr);
    
        for (i = 0; i < msg->numBytes; i++)
        {
            I2C_putData(I2CA_BASE, msg->msgBuffer[i]);
        }
    
        //
        // Send start as master transmitter
        //
        I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
        I2C_sendStartCondition(I2CA_BASE);
        I2C_sendStopCondition(I2CA_BASE);
    
        return(SUCCESS);
    }
    
    //
    // Function to prepare for the data that is to be read from the EEPROM
    //
    uint16_t readData(struct I2CMsg *msg)
    {
        //
        // Wait until the STP bit is cleared from any previous master
        // communication. Clearing of this bit by the module is delayed until after
        // the SCD bit is set. If this bit is not checked prior to initiating a new
        // message, the I2C could get confused.
        //
        if(I2C_getStopConditionStatus(I2CA_BASE))
        {
            return(ERROR_STOP_NOT_READY);
        }
    
        //
        // Setup slave address
        //
        I2C_setSlaveAddress(I2CA_BASE, SLAVE_ADDRESS);
    
        //
        // If we are in the the address setup phase, send the address without a
        // stop condition.
        //
        if(msg->msgStatus == MSG_STATUS_SEND_NOSTOP)
        {
            //
            // Check if bus busy
            //
            if(I2C_isBusBusy(I2CA_BASE))
            {
                return(ERROR_BUS_BUSY);
            }
    
            //
            // Send data to setup EEPROM address
            //
            I2C_setDataCount(I2CA_BASE, 2);
            I2C_putData(I2CA_BASE, msg->temperature_reg_addr);
            I2C_putData(I2CA_BASE, msg->memoryLowAddr);
            I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
            I2C_sendStartCondition(I2CA_BASE);
        }
        else if(msg->msgStatus == MSG_STATUS_RESTART)
        {
            //
            // Address setup phase has completed. Now setup how many bytes expected
            // and send restart as master-receiver.
            //
            I2C_setDataCount(I2CA_BASE, (msg->numBytes));
            I2C_setConfig(I2CA_BASE, I2C_MASTER_RECEIVE_MODE);
            I2C_sendStartCondition(I2CA_BASE);
            I2C_sendStopCondition(I2CA_BASE);
        }
    
        return(SUCCESS);
    }
    
    //
    // I2C A ISR (non-FIFO)
    //
    __interrupt void i2cAISR(void)
    {
        I2C_InterruptSource intSource;
        uint16_t i;
    
        //
        // Read interrupt source
        //
        intSource = I2C_getInterruptSource(I2CA_BASE);
    
        //
        // Interrupt source = stop condition detected
        //
        if(intSource == I2C_INTSRC_STOP_CONDITION)
        {
            //
            // If completed message was writing data, reset msg to inactive state
            //
            if(currentMsgPtr->msgStatus == MSG_STATUS_WRITE_BUSY)
            {
                currentMsgPtr->msgStatus = MSG_STATUS_INACTIVE;
            }
            else
            {
                //
                // If a message receives a NACK during the address setup portion of
                // the EEPROM read, the code further below included in the register
                // access ready interrupt source code will generate a stop
                // condition. After the stop condition is received (here), set the
                // message status to try again. User may want to limit the number
                // of retries before generating an error.
                //
                if(currentMsgPtr->msgStatus == MSG_STATUS_SEND_NOSTOP_BUSY)
                {
                    currentMsgPtr->msgStatus = MSG_STATUS_SEND_NOSTOP;
                }
                //
                // If completed message was reading EEPROM data, reset message to
                // inactive state and read data from FIFO.
                //
                else if(currentMsgPtr->msgStatus == MSG_STATUS_READ_BUSY)
                {
                    currentMsgPtr->msgStatus = MSG_STATUS_INACTIVE;
                    for(i=0; i < NUM_BYTES; i++)
                    {
                        currentMsgPtr->msgBuffer[i] = I2C_getData(I2CA_BASE);
                    }
    
                    //
                    // Check received data
                    //
                    for(i=0; i < NUM_BYTES; i++)
                    {
                        if(i2cMsgIn.msgBuffer[i] == i2cMsgOut.msgBuffer[i])
                        {
                            passCount++;
                        }
                        else
                        {
                            failCount++;
                        }
                    }
    
                    if(passCount == NUM_BYTES)
                    {
                        pass();
                    }
                    else
                    {
                        fail();
                    }
                }
            }
        }
        //
        // Interrupt source = Register Access Ready
        //
        // This interrupt is used to determine when the EEPROM address setup
        // portion of the read data communication is complete. Since no stop bit
        // is commanded, this flag tells us when the message has been sent
        // instead of the SCD flag.
        //
        else if(intSource == I2C_INTSRC_REG_ACCESS_RDY)
        {
            //
            // If a NACK is received, clear the NACK bit and command a stop.
            // Otherwise, move on to the read data portion of the communication.
            //
            if((I2C_getStatus(I2CA_BASE) & I2C_STS_NO_ACK) != 0)
            {
                I2C_sendStopCondition(I2CA_BASE);
                I2C_clearStatus(I2CA_BASE, I2C_STS_NO_ACK);
            }
            else if(currentMsgPtr->msgStatus == MSG_STATUS_SEND_NOSTOP_BUSY)
            {
                currentMsgPtr->msgStatus = MSG_STATUS_RESTART;
            }
        }
        else
        {
            //
            // Generate some error from invalid interrupt source
            //
            asm("   ESTOP0");
        }
    
        //
        // Issue ACK to enable future group 8 interrupts
        //
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    }
    
    //
    // Function to be called if data written matches data read
    //
    void pass(void)
    {
        asm("   ESTOP0");
        for(;;);
    }
    
    //
    // Function to be called if data written does NOT match data read
    //
    void fail(void)
    {
        asm("   ESTOP0");
        for(;;);
    }
    

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

    在给出启动条件后、SCL 和 SDA 引脚立即变为0V。 我 甚至没有在 SCL 引脚上的 CRO 中看到单个时钟脉冲。

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

    请尝试我建议的 driverlib 示例。

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

    正如您所说、我尝试了以下操作。 我得到了相同的结果。

    在 BusScan 函数中  ,在以下例程“I2C_sendStartCondition (base);”之后。 I2C 寄存器访问位未设置(I2C_STS_REG_ACCESS_RDY)。

    //设置从地址
    I2C_setSlaveAddress (base、probeSlaveAddress);


    I2C_sendStartCondition (base);

    //等待从机地址被发送
    while (!(I2C_getStatus (base)& I2C_STS_REG_ACCESS_RDY));

    //#############################################################################
    //
    // FILE:   i2c_ex4_eeprom_polling.c
    //
    // TITLE:  I2C EEPROM Write / Read using polling
    //
    //! \addtogroup driver_example_list
    //! <h1>I2C EEPROM</h1>
    //!
    //! This program will shows how to perform different EEPROM write and read
    //! commands using I2C polling method
    //! EEPROM used for this example is AT24C256
    //!
    //! \b External \b Connections \n
    //!  - Connect external I2C EEPROM at address 0x50
    //!  --------------------------------
    //!    Signal   |  I2CA   |  EEPROM
    //!  --------------------------------
    //!     SCL     | GPIO37 |  SCL
    //!     SDA     | GPIO35 |  SDA
    //!     Make sure to connect GND pins if EEPROM and C2000 device are in different board.
    //!  --------------------------------
    
    //! //Example 1: EEPROM Byte Write
    //! //Example 2: EEPROM Byte Read
    //! //Example 3: EEPROM word (16-bit) write
    //! //Example 4: EEPROM word (16-bit) read
    //! //Example 5: EEPROM Page write
    //! //Example 6: EEPROM word Paged read
    //!
    //! \b Watch \b Variables \n
    //!  - \b TX_MsgBuffer - Message buffer which stores the data to be transmitted
    //!  - \b RX_MsgBuffer - Message buffer which stores the data to be received
    //!
    //!
    //#############################################################################
    //
    //
    // $Copyright:
    // Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################
    
    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    
    #include "i2cLib_FIFO_polling.h"
    
    //
    // Globals
    //
    struct I2CHandle EEPROM;
    
    struct I2CHandle *currentMsgPtr;                   // Used in interrupt
    
    
    uint16_t passCount = 0;
    uint16_t failCount = 0;
    
    uint16_t AvailableI2C_slaves[20];
    uint16_t TX_MsgBuffer[MAX_BUFFER_SIZE];
    uint16_t RX_MsgBuffer[MAX_BUFFER_SIZE];
    uint32_t ControlAddr;
    uint16_t status;
    
    
    void fail(void);
    void pass(void);
    
    void I2C_GPIO_init(void);
    void I2Cinit(void);
    void verifyEEPROMRead(void);
    
    //
    // Main
    //
    void main(void)
    {
    #if 0
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Disable pin locks and enable internal pullups.
        //
        Device_initGPIO();
    #endif 
        //
        // 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();
    
        //I2Cs connected to I2CA will be found in AvailableI2C_slaves buffer
        //after you run I2CBusScan function.
        uint16_t *pAvailableI2C_slaves = AvailableI2C_slaves;
        status = I2CBusScan(I2CA_BASE, pAvailableI2C_slaves);
    
        uint16_t i;
    
        for(i=0;i<MAX_BUFFER_SIZE;i++)
        {
            TX_MsgBuffer[i] = 0;
            RX_MsgBuffer[i] = 0;
        }
    
        EEPROM.SlaveAddr      = 0x48;
        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
    
    #if 0
        //Example 1: EEPROM Byte Write
        //Write 11 to EEPROM address 0x0
        ControlAddr = 0;
        EEPROM.NumOfDataBytes = 1;
        TX_MsgBuffer[0]       = 11;
        status = I2C_MasterTransmitter(&EEPROM);
    #endif
    
        //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: Reading temperature
        ControlAddr = 0;
        EEPROM.pControlAddr   = &ControlAddr;
        EEPROM.NumOfDataBytes = 2;
        status = I2C_MasterReceiver(&EEPROM);
    
        while(I2C_getStatus(EEPROM.base) & I2C_STS_BUS_BUSY);
    
        verifyEEPROMRead();
    
    #if 0
        //Example 3: EEPROM word (16-bit) write
        //EEPROM address 0x1 = 22 &  0x2 = 33
        ControlAddr = 1;   //EEPROM address to write
        EEPROM.NumOfDataBytes  = 2;
        TX_MsgBuffer[0]        = 0x11;
        TX_MsgBuffer[1]        = 0x22;
        EEPROM.pTX_MsgBuffer   = TX_MsgBuffer;
        status = I2C_MasterTransmitter(&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 4: EEPROM word (16-bit) read
         //Make sure EEPROM address 1 has 0x11 and 2 has 0x22
         ControlAddr = 1;
         EEPROM.pControlAddr   = &ControlAddr;
         EEPROM.pRX_MsgBuffer  = RX_MsgBuffer;
         EEPROM.NumOfDataBytes = 2;
    
         status = I2C_MasterReceiver(&EEPROM);
    
         verifyEEPROMRead();
    
    
        //Example 5: EEPROM Page write
        //Program address = data pattern from address 64
    
        for(i=0;i<MAX_BUFFER_SIZE;i++)
        {
            TX_MsgBuffer[i] = i+64;
        }
    
        ControlAddr = 64;   //EEPROM address to write
        EEPROM.NumOfDataBytes  = MAX_BUFFER_SIZE;
        EEPROM.pTX_MsgBuffer   = TX_MsgBuffer;
        status = I2C_MasterTransmitter(&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 6: EEPROM word Paged read
        ControlAddr = 64;
        EEPROM.pControlAddr   = &ControlAddr;
        EEPROM.pRX_MsgBuffer  = RX_MsgBuffer;
        EEPROM.NumOfDataBytes = MAX_BUFFER_SIZE;
    
        status = I2C_MasterReceiver(&EEPROM);
    
        verifyEEPROMRead();
    #endif
    
        if(status)
        {
            fail();
        }
        else
        {
            pass();
        }
    
    }
    
    //
    // 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(EEPROM.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();
            }
        }
    }
    
    
    void I2C_GPIO_init(void)
    {
    	EALLOW;
    
    /* Configuring GPIO0 as SDA */
    GpioCtrlRegs.GPAGMUX1.bit.GPIO0 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 2;
    
    /* Enable Pull Up */
    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;
    
    /* Set Qualification as ASYNCH Only */
    GpioCtrlRegs.GPAQSEL1.bit.GPIO0 = 3;
    
    /* Configuring GPIO0 as SCL */
    GpioCtrlRegs.GPAGMUX1.bit.GPIO1 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 2;
    
    /* Enable Pull Up */
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;
    
    /* Set Qualification as ASYNCH Only */
    GpioCtrlRegs.GPAQSEL1.bit.GPIO1 = 3;
    
    EDIS;
    
    	#if 0
        // 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);
    	#endif
    }
    
    void I2Cinit(void)
    {
        //myI2CA initialization
        I2C_disableModule(I2CA_BASE);
        I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 256000, I2C_DUTYCYCLE_50);  //DEVICE_SYSCLK_FREQ = 92.16MHz
        I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
        I2C_setSlaveAddress(I2CA_BASE, 0x48);    // Slave address is 0x48
        I2C_setOwnSlaveAddress(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_SLAVE | I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
        I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);
        I2C_enableModule(I2CA_BASE);
    }
    
    //
    // End of File
    //
    
    

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

    库鲁瓦、

    您是否更改了示例代码中的任何内容? 您能给我发送示波器快照吗?

    我感觉存在导致此问题的潜在硬件问题。

    此致、

    曼诺伊