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.
工具与软件:
我在 MSPM0C1104 EVB 上开发软件代码。
现在、我们需要从 I2C 从器件中读取寄存器内容。
而不是规格。 I2C 器件的读取时序是多少
此器件的读取流程为:
I2C_START、Slave_Addr + W、Reg_Addr、
I2C_START、 DATA+R、Slave_Addr、Data1、Data2、Data3、 DATA4、I2C_STOP。
我使用并从示例代码"C:\ti\mspm0_sdk_2_03_00_07\examples\nortos\LP_MSPM0C1104\driverlib\i2c_controller_rw_multibyte_fifo_polar"中修改。
#include "ti_msp_dl_config.h" /* * Number of bytes to send from Controller to target. * This example uses FIFO with polling, and the maximum FIFO size is 4. * Refer to interrupt examples to handle larger packets */ #define I2C_TX_PACKET_SIZE (3) /* * Number of bytes to received from target. * This example uses FIFO with polling, and the maximum FIFO size is 4. * Refer to interrupt examples to handle larger packets */ #define I2C_RX_PACKET_SIZE (3) /* Data sent to the Target */ uint8_t gTxPacket[I2C_TX_PACKET_SIZE] = {0x00, 0x61, 0x00}; /* Read Register Address*/ uint8_t gRegisterAddr[2] = {0x10, 0x14}; /* Data received from Target */ volatile uint8_t gRxPacket[I2C_RX_PACKET_SIZE]; /* I2C Target address */ #define I2C_TARGET_ADDRESS (0x29) int main(void) { SYSCFG_DL_init(); /* Set LED to indicate start of transfer */ DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN); /* * Fill FIFO with data. This example will send a MAX of 4 bytes since it * doesn't handle the case where FIFO is full */ DL_I2C_fillControllerTXFIFO(I2C_INST, &gTxPacket[0], I2C_TX_PACKET_SIZE); /* Wait for I2C to be Idle */ while (!( DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) ; /* Send the packet to the controller. * This function will send Start + Stop automatically. */ DL_I2C_startControllerTransfer(I2C_INST, I2C_TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, I2C_TX_PACKET_SIZE); /* Poll until the Controller writes all bytes */ while (DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) ; /* Trap if there was an error */ if (DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) { /* LED will remain high if there is an error */ __BKPT(0); } /* Wait for I2C to be Idle */ while (!( DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) ; /* Add delay between transfers */ delay_cycles(1000); /* Send a read request to Target */ DL_I2C_startControllerTransfer(I2C_INST, I2C_TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_RX, I2C_RX_PACKET_SIZE); /* * Receive all bytes from target. LED will remain high if not all bytes * are received */ for (uint8_t i = 0; i < I2C_RX_PACKET_SIZE; i++) { while (DL_I2C_isControllerRXFIFOEmpty(I2C_INST)) ; gRxPacket[i] = DL_I2C_receiveControllerData(I2C_INST); } // Test: read target register data /* 1: Do Dummy Write */ DL_I2C_fillControllerTXFIFO(I2C_INST, &gRegisterAddr[0], 1); // Wait for I2C to be Idle */ while (!( DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) ; // Transfer register address w/o i2c_STOP DL_I2C_startControllerTransferAdvanced(I2C_INST, I2C_TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX,\ 1, DL_I2C_CONTROLLER_START_ENABLE, DL_I2C_CONTROLLER_STOP_DISABLE, DL_I2C_CONTROLLER_ACK_ENABLE); // wait Poll until the Controller writes all bytes */ while (DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) ; /* 2: Read data */ /* Wait for I2C to be Idle */ while (!( DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) ; /* Add delay between transfers */ delay_cycles(1000); /* Send a read request to Target */ //DL_I2C_startControllerTransfer(I2C_INST, I2C_TARGET_ADDRESS, // DL_I2C_CONTROLLER_DIRECTION_RX, I2C_RX_PACKET_SIZE); DL_I2C_startControllerTransferAdvanced(I2C_INST, I2C_TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_RX,\ I2C_RX_PACKET_SIZE, DL_I2C_CONTROLLER_START_ENABLE, DL_I2C_CONTROLLER_STOP_ENABLE, DL_I2C_CONTROLLER_ACK_DISABLE); /* * Receive all bytes from target. LED will remain high if not all bytes * are received */ for (uint8_t i = 0; i < I2C_RX_PACKET_SIZE; i++) { while (DL_I2C_isControllerRXFIFOEmpty(I2C_INST)) ; gRxPacket[i] = DL_I2C_receiveControllerData(I2C_INST); } /* If write and read were successful, toggle LED */ while (1) { DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN); delay_cycles(12000000); } }
在主函数中、我在最后一个 while 循环之前添加该读取函数。
遗憾的是、程序在 I2C 读取中停止、因为 SCK 保持低电平
有人能解决这个问题吗? 谢谢
我认为这应该是2、而不是1。 可以重试吗?
您好、EASON
作为您的建议、该号码已修改为2
您能否将其更改为启用、并将值从1更改为2。
>while (DL_I2C_getControllerStatus(I2C_INST)&
> DL_I2C_CONTROLLER_STATUS_BUS_BUS)
BUSBSY 将被设定、直到停止、所以它不会在这里清除。 请尝试改用:
>while (DL_I2C_getControllerStatus(I2C_INST)&
> DL_I2C_CONTROLLER_STATUS_BUSY)
---
或者更好的是:使用 RD_ON_TXEMPTY 特性。 不进行初始(TX)半事务、而是调用:
DL_I2C_resetControllerTransfer(I2C_INST); // Set MCTR=0 to avoid enableControllerReadOnTXEmpty hazard DL_I2C_enableControllerReadOnTXEmpty(I2C_INST); // Write then read
然后执行事务的 RX 部分。 I2C 单元将在 Tx FIFO 中写入字节、然后执行 Rx 事务。