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_ex1_loopback 示例代码、我看不到如何通过 I2C 接收数据。
在回送模式下、代码按通告运行。 当我将其从环回模式中取出时、我看不到它是如何从 I2C 接收缓冲器中获取数据的。 我不知道数据是否进入缓冲区。
发送命令不是问题。 我已连接到显示器、我发送给它的所有命令都按预期响应、除了应通过 I2C 返回的值。
我正在获取 FIFO 接收中断、因此我以为我从 I2C 总线获取数据、但它提供的所有数据都是0x00。
我知道显示屏工作正常、因为我有一些 Arduino 示例代码可用于显示。
下面是我对 ISR 的接收部分进行的更改、以获取单字节数据:
// // I2C A 发送和接收 FIFO ISR。 // __interrupt void i2cFIFOISR (void) { uint16_t i; // //如果接收 FIFO 中断标志被置位,则读取数据 // if ((I2C_getInterruptStatus (I2CA_BASE)& I2C_INT_RXFF)!= 0) { uint16_t bytes_received; Bytes_received = I2C_getRxFIFOStatus (I2CA_BASE); 对于(i = 0;i < 1;i++) { RDATA[i]= I2C_getData (I2CA_BASE); if (RDATA[i]!= 0) { bytes_received = bytes_received + 1; bytes_received = bytes_received - 1; } DEVICE_DELAY_US (10); } // //清除中断标志 // I2C_clearInterruptStatus (I2CA_BASE、I2C_INT_RXFF); Example_PassCount++; }
我看到的是我要发送的内容的副本。 DLB 位清零、因此我认为 I2CDRR 寄存器不会从内部加载传出数据。 下面是寄存器设置:
我怀疑我没有正确设置寄存器。 让我知道你想看的是什么、我会很高兴地要求你这么做。
您能不能向正确的方向指出我?
谢谢、
Robin
Robin、
在数字回路模式下、从 I2CDXR 寄存器发出的数据通过内部路径直接在 I2CDRR 寄存器中接收。 禁用 DLB 时、断开此路径、将不会接收在 I2CDXR 上传输的数据。
如果您正在寻找一个示例代码、希望让两个 I2C 像在实际应用中一样与 eachother 通信、则需要使用中提供的 i2c_ex3_external_loopback 示例代码
路径: \driverlib\f2837xd\examples\cpu1\i2c
示例工程:i2c_ex3_external_loopback
在此示例代码中、您从外部连接 I2CA 和 I2CB
此致、
曼诺伊
感谢 Manoj 的快速响应。
我知道、通过禁用 DLB、I2CDXR xmit 数据不会在内部传递到 I2CDRR。 但我认为 I2CDRR 会从与其通信的外设显示屏中拾取 I2C 总线响应。 我希望它们被传递到 FIFO 接收缓冲区中、在那里可以通过我的代码检索它们。
从 MASTER_SEND_MODE TMS320F28379D 向显示屏发送命令应会触发该显示屏的 I2C 响应。 这很可能会导致该响应发生、但 TMS320F28379D 的 I2C 硬件/软件似乎没有对此做出选择。
FIFO 接收中断正在发生、但是接收缓冲区中的数据只有以下两个值中的一个:
我将再次查看 i2c_ex3_external_loopback 示例代码。 我可能会在那里找到一些在 I2C_ex1_loopback 示例的修改版本中不存在的配置。
如果您能帮助我了解 TMS320F28379D 上的 I2C 端口如何接收从器件响应的流程、我将不胜感激。 有很多配置选项、我怀疑我可能忽略(或误解)一个或多个设置。
我们非常感谢您的帮助。
Robin
Robin、
您是否尝试过探测 I2C 总线? 您是否在其中看到任何有效数据? 此外、您尝试使用什么显示器连接 I2C?
此致、
曼诺伊
如果可能、请共享逻辑分析仪(或)示波器快照?
此致、
曼诺伊
尊敬的 Minoj:
显示屏为来自矩阵轨道的 eGTT50A。 它具有一个 I2C 接口、该接口仅将命令从 MCU 主设备(在本例中为 TMS320F28379D)传输到从设备(eGTT50A)、并将从设备显示屏的响应传回主 MCU。 有关绘图图形和文本以及解密触摸屏操作的所有繁重工作都在显示模块内进行处理。 在大型方案中、两者之间的通信非常少。
从《矩阵轨道手册》中可以看出、MCU 主设备请求在显示寄存器中嵌入值、以指示模块类型:(0x28-write 0xFE 0x37)
这是从机显示屏对该模块类型请求的预期响应:(0x28-read 0xFC 0x37 0x00 0x02 0x93 0x10)
以下是时钟和数据信号的示波器图像: (appx、50kHz 时钟速率)
以下是 Arduino 连接系统上工作正常、完整事务的逻辑分析仪图像: (I2C 地址= 0x28)
以下是 TMS320F28379D 系统上失败事务的逻辑分析仪图像:
TMS320F28379D 接收0x00至其 I2CDRR 无限量。
我运行了 i2c_ex3_external_loopback 示例代码并找到类似的结果。 未修改的代码在运行时不会出现故障、这似乎是因为 I2CDRR 正在填充通过 I2CDXR 寄存器输出的数据。 一旦我断开连接并依赖 I2CDRR 来拉取写入 I2C 总线上的从器件数据、系统将停止接收除0x00以外的任何内容。
我想我只是错过了一个关键的拼图、但我已经反复阅读了文档、但我看不到它。
感谢你的帮助。
更新了
尊敬的 Minoj:
在操作 I2C 寄存器配置后、以及从 I2CDRR 提取数据的位置和时间后、我现在接收到从器件正在传输的数据。
但是、从 I2CDRR 捕获的数据将丢失其 lsb。 lsb 在那里、但它始终为零。 通过 I2CDXR 传输的数据是完美的。 传输的数据不存在 lsb 问题。
我知道这些结果会让人相信问题在于显示屏发送错误数据、但当使用 Arduino Uno 作为 MCU 而不是 TMS320F28379D 时、系统工作正常。
我希望这种解释会激发一些新的想法。 您对下一步检查的内容有什么建议吗?
谢谢、
Robin
Robin、
1) 1)检查 I2CMDR.BC 位域是否配置为0 (或) 7? 该 I2CMDR.BC 位域控制 I2C 模块要发送(或)接收的位数。
I2CMDR.BC = 0对应于8位/数据包
I2CMDR.BC = 7对应于7位/数据包。
2)您在读取 I2CDRR 寄存器之前是否正在等待接收数据就绪中断位(I2CSTR.RRDY = 1)被置位?
3)您的逻辑分析仪是否正确读取了数据包(包括 LSB 位)?
4) 4)有可能违反 VIL/VIH/上升时间。 尽管极不可能、但还是建议您检查上升时间? 如果上升时间较慢。 请检查以下各项:
此致、
曼诺伊
按下错误"TI 认为已解决"。 不用担心这个线程仍然被认为是打开的
您好、Manoj、
感谢您的回答。
我已将修改版本的 i2c_ex1_loopback 示例代码转发到 Matrix loopback、但我不知道它们能提供多少帮助。 他们不熟悉 C2000系列、因此他们是否愿意花大量时间了解 TMS320F28379D 是值得怀疑的。
谢谢、
Robin
Robin、
C2000 I2C 仅支持高达400KHz 的频率。 一切都在400 KHz 左右工作吗?
此致、
曼诺伊
您是否尝试以400KHz 运行 I2C? 在400KHz 下一切都能正常工作吗?
此致、
曼诺伊
您好、Manoj、
我进行了新的发现。
以下是我们已经了解的内容:
每个数据字节的 lsb 被莫名调零。 下面是预期的 I2C 命令和回复与逻辑分析仪读数中显示的命令和回复的系列:
命令:(查询模块类型)
0x28 W - 0xFE - 0x37
预期响应:
0x28 R–0xFC–0x37–0x00–0x02–0x93–0x10
实际响应:
0x28 R–0xFC–0x36–0x00–0x02–0x92–0x10
为了证实 lsb 理论、我发送了以下命令:(查询模块字符串)
0x28 W - 0xFE - 0x38
预期响应:
0x28 R–0xFC–0x38–0x00–0x06–0x47–0x54–0x54–0x35–0x30–0x41
实际响应:
0x28 R–0xFC–0x38–0x00–0x06–0x46–0x54–0x54–0x34–0x30–0x40
我发送了其他命令、所有这些命令都有将 lsb 返回为零的相同问题。 我相信这种现象是一致的。 我将其定义为:从器件返回的所有数据字节在 lsb 处都为零。 地址字节不受影响、仅数据字节受影响。
下面是几个示波器迹线、它们放大了其中一个错误数据字节:(应为0x47、而不是0x46)
并进一步放大数据字节:
下面是同一字节的逻辑分析仪读数:
以下是新增功能:
我注意到 lsb 没有像返回的数据字节中的其他位那样被保持在接近零的位置。 我怀疑是因为 MCU 降低了它、而不是显示器。 通过添加一个与数据线(SDA)串联的电阻器,我们可以看到 TI MCU (TMS320F28379D)实际上在数据字节的 lsb 期间将 SDA 降低。 由于显示屏正在返回此数据字节、因此 MCU 应在发生 NACK 之前被停止。
我添加了一个与 SDA 串联的电阻器、因此我可以精确地确定哪个器件将数据线拉低。 下面是我添加电阻器的位置:
以下是示波器迹线的图像。 蓝色走线取自电阻器的显示侧、绿色走线取自 MCU 侧。 上拉电阻器位于 I2C 总线的显示屏端。 很明显、MCU 将 SDA 驱动为低电平、蓝色线迹中的线路不会接近接地即可证明这一点。 其中包括:
最后:
那么、问题是:“为什么 TI TMS320F28379D MCU 在显示屏返回的数据字节的最低有效位期间将数据线(SDA)置为低电平?”
这不是因为 I2CMDR.BC 设置。 它始终设置为零,这意味着8位(而不是7位)。
这不是 I2C 时钟速度的问题。 我现在让 MCU 以~113kHz 的频率为 SCL 计时。 显示默认速度为115.2kHz。 无论如何,在任何合理的速度下都存在同样的问题。
我正在使用 FIFO 接收中断来确定何时复制 I2CDRR 内容。 发送中断被禁用。 我没有等待 RRDY 设置。 (如果您认为这可能是一个问题、请告诉我。)
我认为这不是 SCL 或 SDA 上升时间问题。 如示波器图像中所示、边缘非常清晰。 以下是特写图像:(下降时间更短)
SDA 上升时间为~46ns、SCL 为~38ns。 SPRS880K 规范的最大计时要求为300ns:
感谢你的帮助。
谢谢、
Robin
Robin、
我不确定。 但是、我猜问题是因为 I2C 从设备(115KHz)和 I2C 主设备(113KHz)之间存在微小的时序差异。 是否可以确保 I2C 主设备和从设备以相同的频率工作?
此致、
曼诺伊
您好、Manoj、
使用 I2C 时、时钟速度由主器件决定。 从器件将使用主器件的时钟信号为数据计时。 不需要速度匹配。
这里 是 一个包含更多信息的链接。
谢谢、
Robin
Robin、
嗯、很遗憾、我有很多想法、如果没有主动硬件 /示波器、可能会发生这种情况的原因是什么。 我不会怀疑 F28379D.I2C、因为许多客户多年来一直在使用该外设、没有任何问题。
此致、
曼诺伊
您是否已经尝试以上一帖子中建议的相同速度(100KHz)运行它们。 我认为值得一试。
此致、
曼诺伊
您好、Manoj、
是的、我拨入 I2C 时钟以产生115.2kHz 的频率、但存在完全相同的问题。
这很好:
所有数据均由 F28379完美传输、显示屏也能完美接收。
这是坏的:
但是、F28379在从显示屏接收到的所有数据字节的 lsb 期间将 SDA 置为低电平。
再说一次、换言之、从显示器传输的所有数据都被 F28379破坏。
F28379在显示屏数据的 lsb 期间将 SDA 置为低电平、从而干扰显示屏对 SDA 的控制。
F28379不会干扰显示屏的地址响应、但会干扰显示屏的所有数据响应。
这是图像、其中添加了一些蓝色的新信息:
如果您不完全了解具体症状、请告诉我。 我对其进行了明确定义、并能够在需要时进一步解释。
毫无疑问、TMS320F28379D 能够通过 I2C 正常通信。 我并不完全理解所有的寄存器设置及其效果。 我需要精通这些操作的人的帮助。 毫无疑问、我的设置有误。 我正在使用 FIFO 中断来确定传入数据何时可用。 我没有使用中断来发送数据。
您是否有要与之通信的 LaunchXL-F28379D 和外设? 如果确实如此、我很乐意向您发送我从 i2c_ex1_loopback 示例修改的代码。
我还可以通过 Skype 浏览代码并共享代码、逻辑分析仪、示波器等的屏幕图像。
我很快就要到达最后期限、并且感到有取得进展的压力。 请帮助。
谢谢、
Robin
Robin、
您能否对您的硬件设置提供一些见解?
您如何为 I2C 配置 GPIO 引脚? 请提供配置详细信息?
您可以跨修改后的示例代码发送。 我可以简单看一下、看看我是否看到任何明显的错误。
此致、
曼诺伊
根据您的说明、当 I2C 配置为主接收器时、您似乎遇到问题。 我需要确认显示屏未将 LSB 拉低。 为此、请在进入 I2C 主接收器模式之前将 SDA 引脚配置为 GPIO 输入引脚。 这样、F28379D.I2C 引脚不控制 SDA 引脚。 如果将 LSB 拉至低电平、则为显示屏、而不是 F28379D I2C。
此致、
曼诺伊
您好、Manoj、
SCL 或 SDA 线路上没有串联电阻器。
从器件端的 SCL 和 SDA 上有一个909Ohm 电阻器上拉至3.3V
下面是一个快速方案:
下面是我的工作台设置图像:
在 LaunchXL-F28379上、示例代码中分配的 I2C 端口(GPIO32和33)不会向用户公开。 我分配了 GPIO 104和105。 下面是分配:
// //初始化 GPIO 104和105,分别用作 SDA A 和 SCL A // GPIO_setPinConfig (GPIO_104_SDAA); GPIO_setPadConfig (104、GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode (104、GPIO_QUAL_异 步); GPIO_setPinConfig (GPIO_105_SCLA); GPIO_setPadConfig (105、GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode (105、GPIO_QUAL_ASYNC_A);
要遵循的代码...
谢谢、
Robin
您好、Manoj、
附件是我修改的 i2c_ex1_loopback 示例代码。
在读取期间、我尝试添加代码以将 SDA 引脚更改为 GPIO 输入、但无法使其正常工作。 如果未接收数据、则不会生成 ACK。 如果没有 ACK、数据流会突然结束。
相反、我再次查看了与 SDA 线路串联的电阻器的总线电平。 我非常确信是 f28379将 SDA 线路拉低。 下面是对它的另一个观察:
其工作原理如下:
情形1: 从器件将 SDA 取至逻辑零
进行蓝色连接、连接蓝色示波器探针的电压电平变为零。 绿色示波器探针上的电压电平也变为零、因为总线主端没有上拉电阻器。
场景2: 主器件将 SDA 置于逻辑零
建立红色连接、连接绿色示波器探针的电压电平变为零。 由于分压器由270欧姆电阻器与909欧姆上拉电阻器串联而导致、蓝色示波器探针上的电压电平略高于零。
蓝色探针处的电压应为:
(270 /(270 + 909))* 3.3V = 756mV
如上图所示、绿色和蓝色示波器迹线之间的差值非常接近756mV。
这是相当肯定的。 如果你想让我进一步试验一下、让我知道你想看的是什么。
我希望您会看到随附的代码出现问题。
谢谢、
Robin
您好、Manoj、
这是漫长的一天(月),我有点讨厌,但我认为我发现了问题。
在初始化过程中、我将 I2COAR 寄存器设置为与从机相同的地址。
我将在早上进行详细介绍、但我很确定就是这样。
我将告诉您我发现的内容。
谢谢、
Robin
好的。 请告诉我们。
此致、
曼诺伊
您好、Manoj、
我已确认双向 I2C 通信的最后一个问题是、我不小心将相同的 I2C 地址分配给了主设备和从设备。
因此、从器件(显示屏)的响应受到主器件不需要的响应的干扰。
感谢您的患者帮助。
Robin