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.
工具与软件:
大家好!
我正在开发 I2C 驱动程序以满足客户端的应用要求。 我将 I2C 控制器操作分解成了几个阶段:
i2c_start_write
i2c_start_read
i2c_write
i2c_read
i2c_stop
目前、写操作(start_write
→write
)工作正常。 但是,我遇到了读取操作(start_read
→read
→stop
)的问题。 下面是发生的情况:
问题:
当我执行以下序列时:
start_write > write > start_read > read > stop
在start_read
该阶段、函数DL_I2C_startControllerTransferAdvanced
自动触发数据读取操作。 这会导致读取数据时钟意外生成。 尽管addr
正在发送目标地址()、但读取的数据应该是 不会 在此阶段自动启动。
预期行为:
在start_read
该阶段、系统应:
addr
()。 read
阶段手动触发。 相关代码片段:
static bool i2c_start_read(void) { // Wait until I2C controller is idle if (!retry_until_condition(BUS0_I2C_INST, MAX_RETRIES, 10, is_i2c_idle)) { uart_printf("%s I2C not idle; retry limit reached before starting read transfer\n", TAG); return false; } // Flush RX FIFO and reset transfer DL_I2C_flushControllerRXFIFO(BUS0_I2C_INST); DL_I2C_resetControllerTransfer(BUS0_I2C_INST); // Set only the START condition, print debug message #if DEBUG_START uart_printf("%s Starting I2C read transfer (START only)\n", TAG); #endif DL_I2C_startControllerTransferAdvanced( BUS0_I2C_INST, addr, DL_I2C_CONTROLLER_DIRECTION_RX, 0, // Transmission length set to 0 DL_I2C_CONTROLLER_START_ENABLE, DL_I2C_CONTROLLER_STOP_DISABLE, DL_I2C_CONTROLLER_ACK_ENABLE ); // Check for transfer errors if (DL_I2C_getControllerStatus(BUS0_I2C_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) { uart_printf("%s Read start transfer error\n", TAG); return false; } return true; }
其他上下文:
根据 I2C 控制器文档:
START
MCTR
寄存器中的位置位以生成启动条件。 一旦控制器检测到总线空闲、就应发送启动条件、后跟目标地址。 MBLEN
域指定要发送的字节数。 将设置MBLEN
为0
可能会阻止正确发送地址。 我尝试过的:
确保MBLEN
设置正确:
MBLEN
字段至少设置为1
以保证发送地址。 BURSTRUN
以开始操作。 调节i2c_start_read
功能:
尽管进行了这些更改、但问题仍然存在、在DL_I2C_startControllerTransferAdvanced
i2c_start_read
该阶段仍会自动触发数据读取、从而导致意外生成读取数据时钟。
正常行为示例:
执行时i2c_start_read
、系统应:
addr
()。 read
阶段读取的数据。 有任何建议或解决方案?
我如何修改 I2C 控制器操作、以确保在start_read
该阶段仅生成启动条件、而不自动启动数据读取? 是否存在可能缺失的特定寄存器设置或操作顺序?
提前感谢您的帮助!
此致、
蔡奕迅
您好、 EASON
[报价 userid="620660" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1464589/mspm0l1228-how-to-prevent-dl_i2c_startcontrollertransferadvanced-from-automatically-triggering-data-read-during-i2c-read-phase "] STOP (停止) 而不生成读取数据时钟。[/报价]此停止的工作原理是什么?
只需停止发送时钟、然后等待调用 i2c_read、然后逐个字节地发送读取时钟?
在start_read
该阶段、该函数DL_I2C_startControllerTransferAdvanced
自动触发数据读取操作。 这会导致读取数据时钟意外生成。 尽管addr
正在发送目标地址()、但读取的数据应该是 不会 在此阶段自动开始。
所以在您的测试结果中、设置 len = 1、MSPM0的 I2C 不仅可以发送 I2C 地址、而且还可以包括第一个读取字节?
设置 len = 0的测试结果是什么? I2C 不会发送任何包含地址的内容?
此致、
Helic
尊敬的 Helic:
感谢您的快速响应和建议。
关于您的问题:
1.停止的工作原理:
停止条件应在发送启动条件和地址后终止 I2C 事务。 在调用 i2c_read 函数来手动启动数据读取之前、不应生成任何读取数据时钟。
2.测试长度设置:
设置长度= 1:
I2C 控制器成功发送出目标地址(addr)。
但是、它会立即触发读取数据时钟、从而自动启动数据读取操作、这在该阶段不需要。
设置长度= 0:
奇怪的是、I2C 控制器仍然发送目标地址(addr)。
也会自动触发读取数据时钟、就像 len = 1时一样。 我预计设置 len = 0可能会阻止发送地址、但实际上不会。
我 有一种方法可以配置 I2C 控制器、以便在该start_read
阶段仅生成起始条件并发送目标地址、而不自动启动数据读取? 是否有特定的寄存器设置或可能缺失的操作序列?
感谢您的帮助!
此致、
蔡奕迅
您好、 EASON
我已经尝试了一些方法来避免从目标中读取第一个字节、所有这些字节都不起作用。
此致、
Helic