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.

[参考译文] TMS320F280039C-Q1:需要帮助将 I2C 总线上的位流传输到 ADS7128

Guru**** 2507255 points
Other Parts Discussed in Thread: ADS7128

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1217294/tms320f280039c-q1-need-help-transmitting-bitstream-on-i2c-bus-to-ads7128

器件型号:TMS320F280039C-Q1
主题中讨论的其他器件:ADS7128

底线:MCU 不会通过 I2C 总线向 ADS7128发出读取命令。 我怎样才能做到这一点?

我正在尝试以这种格式发出读取命令(源在 p27上的此处)

在编辑这张图片时、我已经确认我能够向 ADS7128在某一特定点发出命令(从绿色到红色的转换)

以下是我使用 CCS 发送到器件的特定命令的屏幕截图:

前4 4行会自动覆盖上面以绿色显示的内容。 然后、当我   向总线发出最后一对命令时、它们不会执行。  

我怀疑与 MCU 上 I2CMDR 寄存器中的 STT/STP/RM 字段相关、相关内容 在技术手册的表26-3中进行了概述、如下所示:

查看上面图3中的命令、以下是发出每个命令后 STT/STP/RM 字段的值:

                              STT   STP   RM.

在第1个 putData 命令后:          0      0      0

在第一个 sendStart 命令之后:         0      0      0

在第2个 putData 命令之后:          0      0      0

在执行第二个 sendStart 命令之后:        1.      0      0

在执行第3个 putData 命令后:          1.      0      0

在执行第3个 sendStart 命令之后:         1.      0      0

则绝不会发出 stp 命令。 我曾尝试使用 sendStopCondition 手动使 STOP 命令生效、但此后从未复位、我认为这也会导致一些问题。

谢谢 James

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    James:

    在非重复模式(RM=0)下、I2C 事务直到 I2CCNT 字节数的事务完成才完成。 您是否已经看过控制套件中的 i2c_ex4_eeprom_polling 示例。

    EEPROM 字节读取的命令结构与您正在显示的命令结构类似。 ControlAddr 应该为0x10A5、而不是下面所述的0x0

       //示例2:EEPROM 字节读取
       //确保将11写入 EEPROM 地址0x0
       ControlAddr = 0;
       EEPROM.pControlAddr  =&ControlAddr;
       EEPROM.NumOfDataBytes = 1;
       状态= I2C_ControllerReceiver (&EEPROM);

    此致、

    Manoj

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 Manoj! 我更改了 I2CNT 以匹配 TX-ing 中的字节数、并已验证它们都连接到 I2C 总线。 :)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的监控 Manoj、 既然我已经能够向下游发送所有命令、ADS7128对我发送的命令没有响应。

    由于我是这样设置文件的、我将此命令100x (在循环中)发送给它、以便我可以使用我的示波器捕获它、防止它从 I2C 总线消失。 最终的情况是、ADS7128绝不会向主器件发出响应、即使它会确认每个命令字节。 我应该希望此返回值出现在 MCU 的 I2CDRR 寄存器中、前提 是从器件在 I2C 总线上发送信息、对吗? 如果我发送这些命令、该寄存器永远不会进行更新。  

    我可以想到三个可能的原因:

    1、 S/P/SR 序列不正确/但是、我觉得 CCS 对这些操作给予了很大的控制。 该软件只会按所需方式生成它们(AFAIK)、因为它似乎对 sendStopCondition 方法的响应不是很好)。  

    2.我不是给从机在循环中发出下一条命令之前的响应时间? 尽管我认为这是不正确的、因为在发送/接收命令之后、我希望主器件像对待 ACK 位一样向从器件响应屈服。  

    3.缺少一个清除某些标志/中断或者其他东西的设置。   

    我仍在关注数据表中的8.5.1.1示例。 下面是一个快照:  

    下面是我在示波器上看到的:

     图1.

      图2.

      图3.

     图4.

    以及用于生成它的代码 im:

    有什么想法吗? 您可以轻松地看到所有位字段都是正确的、但看一下示例、S/P/SR 序列是正确的

    1.S、

    2.P/SR,

    3.

    4.电源

    而我的序列是  

    1.S.

    2. P1 (在错误位置)

    3. p2 (后面没有启动命令,但在示例中它应该是这样)

    4. s (由于我的循环、这实际上与步骤1中的启动条件相同)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    由于我设置文件的方式,我向它发送此命令100x (在循环中),以便我可以使用我的示波器捕获它,然后它才会从 I2C 总线中消失。 最终的情况是、ADS7128绝不会向主器件发出响应、即使它会确认每个命令字节。 我应该希望此返回值出现在 MCU 的 I2CDRR 寄存器中、前提 是从器件在 I2C 总线上发送信息、对吗? 如果我发送这些命令、该寄存器永远不会进行更新。  [/报价]

    您为什么不能在示波器中使用触发信号、而不是循环100次? 这样、只要您在 I2C 总线示波器上看到任何事务、就会捕获到数据。 您需要记住、I2C 发送/接收数据的速度比以120 MHz 运行的 CPU 慢得多。 在执行下一步之前、您需要等待每个 I2C 字节事务完成

    I2C_setConfig (base、(I2C_CONTROL_SEND_MODE | I2C_REPEAT_MODE));

    I2C_setTargetAddress (base、0x17);

    I2C_sendStartCondition (base);

    while (!(I2C_getStatus (base)和 I2C_STS_REG_ACCESS_RDY));//等待发送目标地址

    I2C_putData (base、0x10);//单个寄存器读取

    while (!(I2C_getStatus (base)和 I2C_STS_REG_ACCESS_RDY));//等待传输数据

    I2C_putData (base、0xA4);//ADS7128寄存器

    while (!(I2C_getStatus (base)和 I2C_STS_REG_ACCESS_RDY));//等待传输数据

    I2C_setConfig (base、(I2C_CONTROL_RECEIVE_MODE| I2C_REPEATE_MODE));//配置 I2C 以接收来自 ADS7128的数据

    I2C_sendStartCondition (base);//重复的启动条件

    while (!(I2C_getStatus (base)和 I2C_STS_REG_ACCESS_RDY));//等待发送目标地址

    RxData = I2C_getData (base);

    I2C_sendStopCondition (base);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Manoj、非常感谢您的全面响应。 我现在将尝试实施。  

    I2C_setConfig (base、(I2C_CONTROL_SEND_MODE | I2C_REPEAT_MODE));

    I2C_setTargetAddress (base、0x17);

    I2C_sendStartCondition (base);

    [/报价]

    它已为我自动生成。 如果我必须进行猜测、可能会由 SYCONFIG 文件进行。 希望我可以跳到接下来的几行

    I2C_putData (base、0xA4);//ADS7128寄存器[/报价]

    这甚至是我需要的寄存器吗? 我正在将.5V 施加到 Ch2 (引脚1)、Vref 为3V3。 我将跳过数学函数、但我需要一个位模式(大约) xxxx0010 01101100  其中最低的8个(白色文本/黑色背景)是 LSB、前 8个是 MSB。 我应该读取的寄存器是0xA4和0xA5吗? 我已经对这进行了深入细致的研究、但是我找不到任何 能够真正解释 每个寄存器所包含内容的东西

    I2C_setConfig (base、(I2C_CONTROL_RECEIVE_MODE|
    [/quote]

    我为什么需要告诉控制器进入 Rx 模式? 数据表 (p2638)的表26-2指出:"当使用任何7位/10位寻址格式时、I2C 模块在发送从地址字节且 R/ W = 1后进入主接收器模式。" 理解这可能是一个不同的论坛,但它的编写方式使它似乎是自动的过程   

    [/quote][/quote]
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是否这也是我需要的寄存器? 我正在将.5V 施加到 Ch2 (引脚1)、Vref 为3V3。 我将跳过数学函数、但我需要一个位模式(大约) xxxx0010 01101100  其中最低的8个(白色文本/黑色背景)是 LSB、前 8个是 MSB。 我应该读取的寄存器是0xA4和0xA5吗? 我仔细地研究了这一点,但我找不到任何能 真正解释 每个寄存器所包含的内容的地方

    很遗憾、我不适合回答这个问题。 您需要检查 ADS7128中的人员才能得到此问题的答案。 我刚刚告诉过您、如何根据您发送的示波器实现想要传输的数据。

    为什么需要告诉控制器进入 Rx 模式? 数据表 (p2638)的表26-2指出:"当使用任何7位/10位寻址格式时、I2C 模块在发送从地址字节且 R/ W = 1后进入主接收器模式。" 理解这可能是为一个不同的论坛,但它的编写方式使它似乎是自动的这个过程  [/报价]

    该语句适用于目标(从器件)配置、而不适用于控制器(主器件)。 在本例中、F280039 I2C 是控制器(主 器件)、ADS7128是目标器件(从器件)。 您需要指定您是控制器发送器(还是)控制器接收器模式。

    此致、

    Manoj

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 Manoj。 我尝试了你发送的代码,但它不起作用:(不幸的是,它永远无法逃脱第一个"等待"循环。 查看 条件、这意味着从未设置"I2C_STS_REG_ACCESS_RDY"。  

    此外、该代码向其发送的最后一项操作是 ADS7128寄存器值(0xA4)。 我需要包含另一个同时将7位从地址和 Write 位放入总线的行(在本例中为0b00101111)、还是隐式行?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢 Manoj. 我尝试了你发送的代码,但它不起作用:(不幸的是,它永远无法逃脱第一个"等待"循环。 查看 条件、这意味着从未设置"I2C_STS_REG_ACCESS_RDY"。

    如果未设置 ARDY、您会在示波器上观察到什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    没有任何内容,因为 代码永远不会进入有关将数据放入 I2CDXR (即 putData() cmd )的部分,因为它无法退出 while 循环

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    I2C_setConfig (base、(I2C_CONTROL_SEND_MODE | I2C_REPEAT_MODE));

    I2C_setTargetAddress (base、0x17);

    I2C_sendStartCondition (base);

    while (!(I2C_getStatus (base)和 I2C_STS_REG_ACCESS_RDY));//等待发送目标地址

    [/报价]

    当您执行发送启动条件时、您应该会看到起始+从器件地址+ W + ACK/NACK。 如果你没有看到这一点、我会感到惊讶。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    早上好、Manoj、给我们带来任何问题的唯一 while 循环似乎是我们进入 Controller_Rx 模式后的最后一个循环。 我能够稍微单步执行一下命令、某些寄存器会改变值(虽然、不是 I2CDRR 寄存器)。 在最终 while 循环中发生变化的寄存器为:

    RXFFST (看上去只是递增)和 RXFFINT (变为高电平)。 而 getData()调用则不起任何作用,因为就我 tell...it 所处的位置而言,没有任何东西会移入该寄存器  

    仅指 I2CSTR 寄存器的 RSFULL 位。 它变为高电平、表明新数据被推到 I2CRSR (我们无法观察到它)、但没有移入 I2CDRR 寄存器。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    RXFFST 的价值是什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它从1开始递增。

    下面是代码 im 实现。 这是一个弗兰肯斯坦版本的 ex1 b/c 我不够精明开始从零开始,所以你会看到一些文物在那里。 大多数情况下可以忽略它们。  

    //##################################################################出########################
    //
    //文件:i2C_ex1_loopback.c
    //##################################################################出########################
    //
    //
    //包含的文件
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"

    //全局变量
    uint16_t sData[2];//发送数据缓冲区
    uint16_t RDATA[2];//接收数据缓冲区
    uint16_t rDataPoint = 0;//以记录我们在中的位置
    //数据流以检查接收的数据

    //函数原型
    _interrupt void i2cFIFOISR (void);//告知编译器这些函数的存在以便它们的时间
    //在 main 中调用编译器不会引发错误

    //主菜单
    空 main (void)

    uint16_t i;

    device_init ();//初始化设备时钟和外设
    device_initGPIO ();//禁用引脚锁定和启用内部上拉。
    interrupt_initModule ();//初始化 PIE 和清除 PIE 寄存器。 禁用 CPU 中断。
    interrupt_initVectorTable();//使用指向 shell ISR 的指针初始化 PIE 矢量表
    Board_init ();// Board initialization
    //I2C_setOwnAddress (myI2C0_BASE、0x3C);//仅适用于环回模式
    interrupt_register (INT_I2CA_FIFO、&i2cFIFOISR);//此示例中使用的中断被重新映射到此文件内的 ISR 函数。

    //初始化数据缓冲区
    for (I = 0;I < 2;I++)

    sData[i]= i;
    RDATA[I]= 0;
    }

    Interrupt_enable (INT_I2CA_FIFO);//启用中断
    EINT;//启用全局中断(INTM)
    ERTM;//启用实时中断(DBGM)


    //永久循环。 暂停或放置断点以观察缓冲区。
    while (1)

    //在配置的中断级别上。
    // ISR 将处理 TX 和的推送/拉取数据
    // RX FIFO 响应
    }

    }

    //
    // I2C A 发送和接收 FIFO ISR。
    //
    __interrupt void i2cFIFOISR (void)

    uint16_t i;

    //如果设置了接收 FIFO 中断标志,则读取数据
    if ((I2C_getInterruptStatus (myI2C0_base)和 I2C_INT_RXFF)!= 0)

    for (I = 0;I < 2;I++)

    RDATA[i]= I2C_getData (myI2C0_BASE);
    }

    //
    //检查接收的数据
    //
    // for (I = 0;I < 2;I++)
    //{
    // if (RDATA[i]!=(rDataPoint + I)& 0xFF)
    //{
    ////
    ////出错了。 RDATA 不包含预期数据。
    ////
    // ESTOP0;
    //}
    //}

    rDataPoint =(rDataPoint + 1)& 0xFF;

    //清除中断标志
    I2C_clearInterruptStatus (myI2C0_BASE、I2C_INT_RXFF);

    }
    //
    //如果设置了发送 FIFO 中断标志,则将数据放入缓冲区
    //
    否则为((I2C_getInterruptStatus (myI2C0_base)和 I2C_INT_TXFF)!= 0)

    for (I = 0;I < 2;I++)

    // I2C_putData (myI2C0_BASE、sData[i]);
    }

    ********************* /
    //ADS7128
    //
    //ADC 命令

    I2C_setConfig (myI2C0_BASE、(I2C_CONTROL_SEND_MODE | I2C_REPEATE_MODE));//将控制器置于主 XMTR 模式并启用重复模式
    I2C_setTargetAddress (myI2C0_BASE、0x17);//设置目标地址(对于 ADC 为0x17/6/5/4/3/2/1)

    I2C_sendStartCondition (myI2C0_BASE);//初始启动条件(S)
    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));//等待发送目标地址
    I2C_putData (myI2C0_BASE、0x08);//单个寄存器写入操作码

    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));
    I2C_putData (myI2C0_BASE、0x11);//通道选择寄存器

    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));
    I2C_putData (myI2C0_BASE、0x02);//将 Manual_Chid 设置为 AIN2 (pin1)

    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));

    I2C_sendStartCondition (myI2C0_BASE);//发送重复启动条件(SR)-执行此操作时会自动发送目标地址和写入位。
    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));
    I2C_putData (myI2C0_BASE、0x08);//单个寄存器写入操作码

    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));
    I2C_putData (myI2C0_BASE、0x01);//通用配置寄存器

    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));
    I2C_putData (myI2C0_BASE、0b00001000);


    I2C_sendStartCondition (myI2C0_BASE);//重复起始(SR)-执行此操作时会自动发送目标地址和写入位。
    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));
    I2C_putData (myI2C0_BASE、0x10);//针对单个寄存器读取使用操作码

    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));
    // I2C_putData (myI2C0_BASE、0xA4);//ADS7128寄存器我想读取(0xA4 - Ch2 (pin1)最近的 LSB 转换)
    I2C_putData (myI2C0_BASE、0xA5);//ADS7128寄存器我想读取(0xA5 - Ch2 (引脚1)最近的 MSB 转换)
    // I2C_sendStopCondition (myI2C0_BASE);

    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY));
    I2C_putData (myI2C0_BASE、0x2F);//7bit 从器件地址(0x17)和读取命令(0b1)

    I2C_setConfig (myI2C0_BASE、(I2C_CONTROL_RECEIVE_MODE|I2C_REPEATE_MODE));

    while (!(I2C_getStatus (myI2C0_BASE)和 I2C_STS_REG_ACCESS_RDY))
    //
    I2C_sendStopCondition (myI2C0_BASE);

    //
    //清除中断标志
    //
    I2C_clearInterruptStatus (myI2C0_base、I2C_INT_TXFF);
    }
    I2C_setConfig (myI2C0_BASE、(I2C_CONTROL_SEND_MODE | I2C_REPEAT_MODE));

    //发出 ACK
    INTERRUPT_clearACKGROUP (INTERRUPT_ACK_group8);
    }


    //文件结束

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我忘记了添加我的.syscfg 文件设置。但说实话、我认为这没什么重要的、因为我们在.c 代码中对它进行修改

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    James:

    您能给我提供您的电子邮件地址吗?

    此致、

    Manoj

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    此问题是否已得到解决? 我可以关闭该主题吗?