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.

[参考译文] TMS320F28379D:从 ADC EOC 到 ADC 中断执行的时间延迟

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1106227/tms320f28379d-time-delay-from-adc-eoc-to-adc-interrupt-execution

器件型号:TMS320F28379D

您好!

我对 ADC 模块转换结束(EOC)后到 ADC 中断实际执行所经历的时间有疑问。 如 数据表中所述、"如果 ADCCTL1寄存器中的 INTPULSEPOS 位置位、t INT 将与锁存到结果寄存器中的转换结果重合"。 我已经根据数据表计算了采样保持时间和 A/D 转换时间。 但是、当我测量从 SOC 到执行 ADC 中断第一行的时间时、会有一段时间下落不明。 我详细阐述了以下问题:

ADCA 模块被配置为转换一个引脚。 采集窗口设置为75ns (t_SH)。 ADC 时钟以50MHz 的频率运行。 系统时钟以200MHz 运行。 根据数据表、t_EOC 时间将为10.3 ADCCLK 周期。 这会使 t_EOC 达到206ns。 因此、t_SH + t_EOC = 281ns。

EPWM1模块配置为 ADC SOC。 SOC 发生在 CTRU = CMPA 时。 动作限定器配置为将通道设置为 CTR =零、并在 CTRU = CMPA 时清除通道。 在示波器上监控 ePWM 通道。

GPIO 引脚(GPIO93)在 ADC 中断例程的第一行被置位、并在例程结束时被清零。 该引脚在示波器上受到监控。

ePWM 通道清零与 GPIO93集之间的时间差测量值为410ns。 测量 GPIO 引脚上的 SET 指令所需的时间约为25ns。 因此、未计算的时间为(410 - 25 - 281) ns = 104ns。 即使我考虑多使用几个周期来锁存 ADC 结果、仍然有很多时间无法计算。

如果在实施或测量中出现错误、请更正我的错误。 如果我能获得一些参考文档 来解释 多余的时间、那将会有所帮助。

如果需要任何其他信息、请告知我。

谢谢你。

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

    Somenath、

    请多给我一天时间来回答您的问题、我相信我有我需要的所有信息。

    最棒的

    Matthew

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

    Somenath、

    我将参考 TRM https://www.ti.com/lit/pdf/spruhm8第1581页上的时序图 、以进行以下计算。

    上一页包含 SYSCLK 的时序、因此它将变得更简单、因为我们可以使用下面的5ns 周期。  对于50MHz ADC 时钟、我假设 ADCCTL2.prescale = 6、这样会得到200/4 = 50MHz

    根据该表、SYSCLK 中从采样结束到 TLATCH 的时间= 44个周期。  因此、这将是44 * 5ns = 220ns。  将75ns 的采集时间相加、我们得到220ns+75ns =从接收触发器开始的总时间295ns。

    如果我们看图、还会有一个标记、用于标记 ADCTRIG 信号被 ADC 锁存、这将是您的情况下的 EPWM ADCSOC、让我们假设发生2个额外 SYSCLK 周期的较差情况、那么我们就会这样做

    2ns (锁存触发器的时间)+ 75ns (采样保持时间)+ 220ns (转换和锁存时间)= 297ns

    我们在应该观察的内容和 o 范围所捕获的内容方面仍然存在差距

    297ns + 25ns (GPIO 切换时间)= 322ns   

    410ns (观测值)- 322ns (预期值)= 88ns。

    对于器件处理 ISR 时发生的操作、我们仍需要考虑一些周期。  发生这种情况时、C28x CPU 必须清空其指令流水线(完成已进入管线 https://www.ti.com/lit/SPRU430 D2阶段的任何操作)、并将寄存器内容推送到堆栈

    基本上、在获取 ADC ISR 之前、我们将会发生8个周期的损失、因此我们现在可以:

    322ns+(8*5ns)= 362ns

    410ns-362ns = 48ns 增量时间。

    此时、有~10个 CPU 周期未加说明。 我认为、ADC ISR 指令在获取后需要额外的4-5个 CPU 周期才能执行、但不确定这是否已在 GPIO 时序中进行计数。

    您能评论一下您的 ADC ISR 是从闪存还是 RAM 存储器运行吗?  如果我们从闪存运行、在200MHz 时、由于时序原因、它具有3WS、因此这可能会增加一些我们尚未包含的额外周期

    另一种可能是、当 ADC ISR 进入 C28x 时运行的代码需要周期才能从闪存或 RAM 完成其操作。

    如果您对上述内容有任何其他问题、请告诉我。

    最棒的

    Matthew

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

    Matthew、

    感谢您的详尽和及时的回答。

    在回答您的问题时、我正在从 RAM 存储器运行代码。

    我从上面的讨论中收集的是、如果我们能够确保触发 ADC 中断时 CPU 处于空闲状态、那么可能需要最少的时间来开始处理 ADC ISR。 在等待中断时、我将在主代码中运行一个空的无限循环。 这应该确保在触发中断时 CPU 不会处理任何指令。 我将报告我的调查结果。

    请告诉我是否 应该继续。

    谢谢、

    Somenath。

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

    Somenath、

    如果您确保 CPU 处于空闲状态、从而为 ISR 提供最佳响应时间、则您是正确的。

    最棒的

    Matthew

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

    Matthew、

    我已实施了我在上次答复中提到的修改。 现在无限循环内部没有指令。 这确实减少了测量时间。 现在、总时间已从410ns 减少到395ns。 我将使用 while (1)循环来实现此目的。

    谢谢、

    Somenath。

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

    Somenath、

    我认为、就预期行为而言、我们就在那里。  我在前面的计算中发现了一个错误、从 PWM 锁存 ADCINT 的时间是2个 SYSCLK 周期、而不是2ns。  因此、如果没有任何 ISR 开销、我们应该为370ns。  那么、我们现在有了

    395 (测量值)-370ns (预期值)= 25ns 或5个增量周期。  我认为这可能是在 CPU 流水线获取该程序代码地址后从 ADCISC 执行该第一条指令所需的时间内考虑的。

    最棒的

    Matthew

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

    Matthew、

    我认为在上述计算中、执行 ADC ISR 第一行(在本例中为 GPIO 引脚切换)的25ns 或5个周期被考虑两次。

    总结到目前为止的讨论、时间安排如下:

    从 ePWM SOC 锁存触发器的2个周期:10ns

    采样保持时间:75ns

    转换和锁存时间(锁存 ADC 结果44个周期):220ns

    获取 ADC ISR 前的8个周期损失:40 ns

    执行 ISR 第一行的时间(在本例中,GPIO 切换为5个周期):25ns

    总时间(计算值):370ns

    从示波器测得的时间:395ns

    我还对审议44个周期的转换和锁存时间表示怀疑。 参考同一文档、时间 t_INT 被称为41个周期。 我从该信息中收集的是在第41个周期之后、设置 ADC 中断触发器。 但是、转换结果 需要44个周期才能锁存到结果寄存器。 我认为、在我们的计算中、我们应该考虑41个周期、而不是44个周期。 这是因为在 CPU 获得 ADC 中断触发器(位于第41个周期)后、8个周期的损失应该开始。

    如果我的计算和假设不正确、请更正我。

    谢谢、

    Somenath。

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

    Somenath、

    我也注意到、让我与其他人核实一下、看看这是41还是44。

    最棒的

    Matthew

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

    Somenath、

    感谢您在这里的耐心等待。  我已经确认表中列出的时序是正确的、因此从采样结束到转换完成的41个 CPU 周期。  此时、较晚的 ADCINT 也将触发、这将有助于抵消我们之前讨论过的 ISR 周期/流水线清除。

    这也意味着我还有3个 CPU 周期未加说明、或15ns。

    因此、我们测得的值为395ns、而预期值为355ns、或者40ns/5ns = 8个 CPU 周期丢失。

    我想尝试使用 Code Composer 周期计数来测量此值、以便将其与范围进行比较。  为此、我们还需要将 ADC 触发器从 PWM 更改为仅使用 SW 中的 ADCSOCFRC 位。  我们可以在该指令设置一个 BP、在 ADC ISR 的第一条指令设置另一个 BP、并观察我们得到的周期计数。  然后、我们可以在 GPIO 切换等之后移动 BP、然后与 o 示波器进行比较。

    我已经设置了屏幕上限的 CCS、以展示如何实现这一点。  完成此操作后、您应该会在 CCS 窗口的右下角看到一个小时钟。  一旦您按下 BP、您可以双击时钟进行重置。  这将从 C28x CPU 的角度提供周期计数、并且我们可以减少知道 CPU 时钟的时间。

    我只想尽可能消除可变性、然后我们可以向后添加更多代码(PWM 触发器等)、并确保我们得到正确的计数以及它与 o 范围的关系。

    最棒的

    Matthew

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

    Matthew、

    感谢您努力调查此问题。 我尝试了您的建议。 我要附上我用于此目的的代码。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "F28x_Project.h"
    //
    // Function Prototypes
    //
    void ConfigureADC(void);
    void SetupADC(void);
    interrupt void adca1_isr(void);
    void main(void)
    {
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();
    EALLOW;
    PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    我希望这符合您的建议。 如果实施中出现错误、请更正。

    我在 ADC ISR 内的"AdcaRegs.ADCSOCFRC1.bit.SOC0 = 1"行设置了一个 BP、在"DELAY_US (10000);"行设置了下一个 BP。 我在第一个断点处将 CCS 时钟复位为0。 下一个 BP 时钟的读数为93。

    我收集这意味着两个 BPS 之间的时间为465 ns (因为系统时钟设置为200 MHz)。 这高于 在 o 示波器上测得的395ns。 我想 ePWM SOC 触发器(在原始实现中)与比较事件在 o 示波器上的实际反射之间可能存在滞后。

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

    Somenath、

    感谢您的观看、这正是我想要看到的内容。  正如您所注意到的、我们现在看到的延时时间比以前更大、而这是我们所期望的、说实话、这有点令人惊讶。  在 ADC ISR 中点击 BP 后、您是否可以打开拆分窗口来查看/确认我们没有执行任何其他指令?

    对于代码放置、您能否确认代码执行的 RAM 地址?  我需要检查以确保该器件上的所有 RAM 都是0WS (我认为是)、但如果对此有任何疑问、这将有助于我缩小范围。

    最棒的
    Matthew

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

    Matthew、

    我确实观察了两个断点的反汇编。 我正在为两个瞬间附加反汇编窗口的快照。

    在进入 ADC ISR 和 ISR 内的第一行代码之间、我观察到17条指令。 但是、我无法理解这些指令的用途。

    至于代码放置、我要在链接器文件中附加负责 RAM 分配的代码部分。 如果我弄错了、请原谅我、但我收集您的信息是为了查看代码组件在存储器中的存储位置。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    SECTIONS
    {
    codestart : > BEGIN, PAGE = 0
    .text : >>RAMM0 | RAMD0 | RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4, PAGE = 0
    .cinit : > RAMM0, PAGE = 0
    .pinit : > RAMM0, PAGE = 0
    .switch : > RAMM0, PAGE = 0
    .reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */
    .stack : > RAMM1, PAGE = 1
    .ebss : > RAMLS5, PAGE = 1
    .econst : > RAMLS5, PAGE = 1
    .esysmem : > RAMLS5, PAGE = 1
    Filter_RegsFile : > RAMGS0, PAGE = 1
    ramgs0 : > RAMGS0, PAGE = 1
    ramgs1 : > RAMGS1, PAGE = 1
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    希望这对您有所帮助。

    谢谢、

    Somenath。

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

    Somenath、

    欣赏屏幕截图。  这17条指令是任何 ISR 上下文保存的一部分(您还将在 ISR 结束时看到还原)。  当任何函数被声明为 ISR 并且我在之前的计算中没有考虑到这一点时、这些函数会自动生成。

    如果你可以在这些开始和结束时设置一个 BP 并测量 CPU 周期计数、我认为这将解决我们从理论到实际的时间增量。  如果我假设每个 CPU 指令都是单个 CPU 指令(乐观)、则总时间为435ns、而您看到的时间为465ns 或6个周期的差异。  正如我提到的、我认为其中的一些指令可能需要一个以上的周期、但配置文件应该会揭示这一点。

    另一种优化从 ADC 转换到读取的延迟的方法是使用早期中断(发生在信号采样后、但未转换时)。  我们可以使用上面的信息来确定新的 ADC 结果何时准备就绪、一旦我们进入 ISR 中的代码、并根据需要延迟这几个周期(或者执行其他系统操作)。

    最棒的

    Matthew

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

    Matthew、

    感谢您深入了解上下文保存。 我在 ISR 结束时也会看到它们。 因此、我在这17条指令的开头和末尾放置了 BPS。 但是、在这种情况下、右下角的时钟计数为17。 我想它们都是单周期指令。 我已经连接了一个屏幕盖、将 BPS 放置在拆卸中、并将周期计数放置在底部。

    我还通过在 ADCSOCFRC 上放置一个 BP、并 在 while (1)行上放置下一个 BP、测量了 ADCSOCFRC 锁存的周期计数。 这需要4个周期。

    总结到目前为止的讨论:  

    ADCSOCFRC 锁存的4个周期

    采样保持时间为15个周期

    针对 ADC 转换和 ADC 中断触发的41个周期

    获取 ADC ISR 之前的8个周期损失

    17个运行环境保存周期

    总周期数:85个周期

    从 ADCSOCFRC 到 ISR 第一行的测量周期数:93个周期

    请告诉我是否遗漏了以前的内容。

    我也 很欣赏使用早期中断的建议、我一定会尝试这一点。

    谢谢、

    Somenath。

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

    Somenath、

    感谢您打破循环。  让我在其他几个方面进行回放、看看我们是否可以解释从器件到规格的8周期增量。

    最棒的

    Matthew

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

    Somenath、

    我们对此进行了一些内部讨论、现在对周期进行了以下细分、以便更准确地说明触发 ISR 时发生的 CPU 流水线刷新/重新加载。

    ADCSOCFRC 锁存的4个周期

    采样保持时间为15个周期

    针对 ADC 转换和 ADC 中断触发的41个周期

    获取 ADC ISR 之前的14个周期损失(管道刷新、主 CPU 寄存器的硬件上下文保存以及获取/调用 ISR 矢量)

    在 ISR 内部保存上下文的17个周期

    91个 CPU 周期与测得的93个周期

    此时、我想我们可以相信您将通过延迟的 ADCINT 获得最佳/可预测的周转时间。  

    至于2个周期、我认为这取决于 ADC ISR 进入 C28x CPU 时 CPU 所执行的操作、意识到我们在这里有一些空闲循环、 但是、如果我们看看拆分、我们很可能会看到某种类型的分支指令、这种指令会将其自身的中断连续性引入流水线。

    此致、
    Matthew

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

    Matthew、

    感谢您耐心地解决问题。 您提供的时序摘要实际上让我对该过程有了一些了解。

    再次感谢您、

    Somenath。