工具/软件:Code Composer Studio
您好!
我需要使用 FIFO 和 UDMA 实现 I2C 通信。
通过分析文档 SPMA073、我找到了示例"ektm4c129_i2c_master_udma_fifo"、但似乎奇怪的中断"I2C_master_INT_RX_DMA_DONE"和"I2C_master_INT_TX_DMA_DONE"未使用。
是这样吗?
是否有使用它们的示例?
哪种方式会更高效?
谢谢、
Simion。
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.
工具/软件:Code Composer Studio
您好!
我需要使用 FIFO 和 UDMA 实现 I2C 通信。
通过分析文档 SPMA073、我找到了示例"ektm4c129_i2c_master_udma_fifo"、但似乎奇怪的中断"I2C_master_INT_RX_DMA_DONE"和"I2C_master_INT_TX_DMA_DONE"未使用。
是这样吗?
是否有使用它们的示例?
哪种方式会更高效?
谢谢、
Simion。
我认为在本示例中使用 dma_done 中断没有任何好处、因为您在主设备事务处理完成时会收到 I2C 中断。 您可以 提前获取 I2C_MASTER_INT_TX_DMA_DONE、但 I2C FIFO 中仍有要传输的数据。 此时不想将状态更改为 I2C_OP_STOP、因为在传输最后一个字节时仍可能会出现错误或 NAK。 简而言之、在本示例中使用 dma_done 中断没有好处。
好的,这是有道理的
我还有一些疑问...
我的情况稍有不同、在示例中、发送一个16位字来引用 I2C 从设备的注册地址、但我需要一个仅为8位的字、这是 I2C 从设备的数据表所要求的。
为此、我在 I2C1IntHandler 函数中添加了注释并更改了一些行。
void I2C1IntHandler (void) { uint32_t ui32I2CMasterInterruptStatus; // //将 PL4切换为高电平以指示进入 ISR // ROM_GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_4、GPIO_PIN_4); // //获取屏蔽的中断状态并清除标志 // ui32I2CMasterInterruptStatus = ROM_I2CMasterIntStatusEx (I2C1_base、true); ROM_I2CMasterIntClearEx (I2C1_base、ui32I2CMasterInterruptStatus); log[CONT]= ui32I2CMasterInterruptStatus; CONT++; // //执行状态机 // 开关(g_ui8MasterCurrent 状态){ I2C_OP_IDLE 情况: // //从空闲状态移动到发送地址状态 // G_ui8MasterPrevState = g_ui8MasterCurrent 状态; // G_ui8MasterCurrent 状态= I2C_OP_TXADDR; G_ui8MasterCurrent 状态= I2C_OP_FIFO; // //将页的高位写入从机 // ROM_I2CMasterSlaveAddrSet (I2C1_base、slave_address_EXT、false); // I2CMasterDataPut (I2C2_base、(g_ui16SlaveWordAddress >> 8)); // I2CMasterControl (I2C2_base、I2C_MASTER_CMD_BURST_SEND_START); ROM_I2CMasterDataPut (I2C1_base、(g_ui16SlaveWordAddress >> 0); ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_START); 中断; I2C_OP_TXADDR 案例: // //将当前状态指定为上一状态 // G_ui8MasterPrevState = g_ui8MasterCurrent 状态; // //如果地址已 NAK'ed,则转至停止状态 //否则进入 FIFO 启动状态 // if (ui32I2CMasterInterruptStatus & I2C_MASTER_INT_NACK) { G_ui8MasterCurrent 状态= I2C_OP_STOP; } 其他 { G_ui8MasterCurrent 状态= I2C_OP_FIFO; } // //将页的低位写入从机 IF //地址已确认 // // ROM_I2CMasterDataPut (I2C1_base、(g_ui16SlaveWordAddress >> 0)); // ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_CONT); 中断; I2C_OP_FIFO 案例: // //如果最后一个数据已 NAK'ed,则转至停止状态 // if (ui32I2CMasterInterruptStatus & I2C_MASTER_INT_NACK) { G_ui8MasterCurrent 状态= I2C_OP_STOP; } // //根据方向移动到适当的状态 //发送或接收。 还发送突发命令 //用于 FIFO 操作。 // 否则 if (!g_bI2CDirection) { G_ui8MasterCurrent 状态= I2C_OP_TXDATA; ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_FIFO_BURST_SEND_FINISH); } 其他 { G_ui8MasterCurrent 状态= I2C_OP_RXDATA; ROM_I2CMasterSlaveAddrSet (I2C1_base、slave_address_EXT、true); ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_FIFO_SINGLE_Receive); } 中断; I2C_OP_TXDATA 案例: // //将当前状态移动到上一状态 //否则继续传输直到最后一个字节 // G_ui8MasterPrevState = g_ui8MasterCurrent 状态; // //如果地址或数据已经 NAK'ed,则转至停止状态 //如果由于获得的字节数而出现停止条件 //完成,然后移动到停止状态 // if (ui32I2CMasterInterruptStatus & I2C_MASTER_INT_NACK) { G_ui8MasterCurrent 状态= I2C_OP_STOP; } 否则、IF (ui32I2CMasterInterruptStatus 和 I2C_MASTER_INT_STOP) { G_ui8MasterCurrent 状态= I2C_OP_STOP; } 否则、IF (ui32I2CMasterInterruptStatus 和 I2C_MASTER_INT_TX_DMA_DONE) { G_ui8MasterCurrent 状态= I2C_OP_STOP; } 其他 { G_ui8MasterCurrent 状态= I2C_ERR_State; } 中断; I2C_OP_RXDATA 示例: // //将当前状态移动到上一状态 //否则继续传输直到最后一个字节 // G_ui8MasterPrevState = g_ui8MasterCurrent 状态; // //如果地址已 NAK'ed,则转至停止状态 //如果由于获得的字节数而出现停止条件 //完成,然后移动到停止状态并读取最后一个数据字节 // if (ui32I2CMasterInterruptStatus & I2C_MASTER_INT_NACK) { G_ui8MasterCurrent 状态= I2C_OP_STOP; } 否则、IF (ui32I2CMasterInterruptStatus 和 I2C_MASTER_INT_STOP) { G_ui8MasterCurrent 状态= I2C_OP_STOP; } 否则、IF (ui32I2CMasterInterruptStatus 和 I2C_MASTER_INT_RX_DMA_DONE) { G_ui8MasterCurrent 状态= I2C_OP_STOP; } 中断; 案例 I2C_OP_STOP: // //将当前状态移动到上一状态 //否则继续传输直到最后一个字节 // G_ui8MasterPrevState = g_ui8MasterCurrent 状态; 中断; 情况 I2C_ERR_STATE: G_ui8MasterCurrent 状态= I2C_ERR_STATE; 中断; 默认值: G_ui8MasterCurrent 状态= I2C_ERR_STATE; 中断; } // //将 PL4切换为低电平以指示退出 ISR // ROM_GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_4、0x0); }
SDA 和 SCL 线路在发送时表现良好、但我中断了4次、其中两次非常接近。
绿线显示每个 I2C 中断。
log 变量存储ui32I2CMasterInterruptStatus 的值每次中断时、我得到以下结果:
log [0]= 0x00;
日志[1]= I2C_MASTER_INT_DATA;
日志[2]= I2C_MASTER_INT_TX_DMA_DONE;
日志[3]= I2C_MASTER_INT_STOP | I2C_MASTER_INT_DATA;
这两种几乎同时发生的中断是否预计? 是否有更好的方法来实现此目的?
谢谢、
Simion