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.
你(们)好。
使用 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 //
库鲁瓦、
您是否更改了示例代码中的任何内容? 您能给我发送示波器快照吗?
我感觉存在导致此问题的潜在硬件问题。
此致、
曼诺伊