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.

[参考译文] TMS320F28388D:PWM 待处理的 ISR。 我们如何清除它

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1579698/tms320f28388d-pwm-pending-isr-how-do-we-clear-it

器件型号: TMS320F28388D

关于何时开始读取 ADC、我们有一些特定的时序要求。 我们使用 PWM 触发 ISR 并启动 ADC。 我们使用 PWM 计数并验证我们是否接受计数的前 1usec 以开始读取。  

但是、我们所做的是以 48usec 计时器运行 PWM、当被告知将 PWM 同步到 EtherCAT(以 250 个用例运行)上的 SYNC0 ISR 脉冲时。 我们看到和预期的是、在发生时、PWM 将有一个挂起的中断。 因为我们从技术上可以获取 PWM 计数器 ISR、然后用例数稍后会获取 Sync0 Pusle、它应该将 PWM 计数重新设置为零(顺便说一下,这是否正确?)

我认为执行 EPWM_clearEventTriggerInterruptFlag 可以清除当前中断和任何挂起的中断、但在论坛中进行一些读取操作看起来并不是这样。 如果在我们执行 EPWM_clearEventTriggerInterruptFlag 之后 PWM 有一个挂起的 ISR、则会触发挂起的中断、一旦我们离开中断处理程序、就会立即再次回到中断处理程序中(同步任何其他更高的中断)。  

由于我们根据时序知道我们可以得到 1 个中断、所以我们正在处理它并具有一个挂起(因为收到 Sync0 脉冲)、我们将返回到 ISR 处理程序中、其中 PWM 计数为高电平、以启动我们的 ADC 读取、并产生抛出和错误。 我们知道我们会进入这种情况是否有办法解决这个问题。  

我们要做的是在离开 ISR 之前清除当前 PWM 中断和任何挂起的 PWM 中断。 这样就没有任何待处理的内容。 是否有正确的方法?

Dorion  

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

    您好 Allison、感谢您的澄清。

    如果我们禁用中断并在执行该启动操作时重新启用、则会停止 PWM 计数器(我们无法这样做)、还是只是阻止 ISR 生成挂起的中断?  

    似乎仍然可能有一个窗口(尽管很小)、在我们到达 ISR 和禁用它之间、如果 Sync0 进入、我们可能会收到挂起的中断。 或者、您是说当我们禁用挂起的中断时、挂起的中断会消失吗?

    因此、在我们清除中断后、无法通过写入寄存器来清除 ISR 中的待处理 PWM ISR、或者这是一个鸡肉和蛋问题吗? 这意味着我们将其清除、然后无论如何都会得到下一个 ISR

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

    尊敬的 Dorion:

    感谢您的跟进。 请允许我再过一天来制定我的回应 感谢您的耐心!

    此致、

    Allison

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

    尊敬的 Dorion:

    禁用中断和重新启用不会以任何方式影响 PWM 计数器。 它只会在中断被禁用时阻止新的中断触发传入。

    禁用会阻止中断事件计数器递增,因此我想知道您是否可以通过使用中断事件计数来防止不必要的中断,但需要首先与同事核实 — 当我可以澄清时,我们会更新您。  

    此致、

    Allison

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

    Allison、  

     与您的同事核对后是否有任何更新?  

    Dorion  

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

    尊敬的 Dorion:

    让我跟进一下、并尝试在今天晚些时候获得更新。 感谢耐心。

    此致、

    Allison

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

    尊敬的 Dorian:

    我目前正在进行测试 — 明天将提供另一个更新。

    此致、

    Allison

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

    尊敬的 Dorian:  

    对不起,我还不能把我想要的时间搁置一旁。 请再过一天或两天。

    此致、

    Allison

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

    尊敬的 Dorian:

    对不起,我只是暂时不在办公室。 请告诉我、自您上次回复以来是否有任何变化、以及您是否仍需要有关此主题的帮助。  

    此致、

    Allison

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

    Allison、

    我仍在等待您的测试。  

    我们离开的原因是您联系了您办公室的另一个人、并且您正在进行测试。 (见 11 月 11 日的答复)。  

    是的、这对我们来说仍然是一个大问题。 我只需要一种方法来清除任何挂起的中断、同时仍处于 PWM 的中断处理程序中、如上所述。  

    Dorion  

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

    尊敬的 Dorion:

    感谢您的跟进。 我仍在试用我的测试用例。 同时、如果 您有一个项目也能隔离问题、请随时将其发送给我进行测试。 您是否还尝试过在 ISR 中实现禁用中断功能?

    此致、

    Allison

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

    尊敬的 Allison:  

     我已经尝试禁用该功能、问题是它会运行一段时间、但由于窗口不为零、我仍然会收到一个待处理的 ISR。 我仍然需要一种方法来清除所有待处理的 ISR、然后再离开 PWM 中断处理程序。  

     要重现此问题、请执行以下操作(我们的代码太专有了,无法在此输入)。 我还没有建立测试程序。  

    1、在 40 个用例中使用 ISR 设置 PWM、然后生成并进入 ISR

     1A。 让 PWM ISR 处理大约 20 个用例、我们所做的是在进入 ISR 时转储 PWM 计数。

     1b 将 PWM 设置为与 sync0 同步(这意味着当 sync0 到达时、PWM 计数将变为零、并生成 ISR)

     1C 当 PWM 计数在 40 个用例后变为零时、您还将获得 ISR

    2.设置 Sync0 脉冲以在 250 个用例下运行

     2A 设置 Sync0 脉冲以触发上述 PWM。  

    您会看到 PWM 应该被中断并且计数器应小于 1-2 个用例(可能更少)的问题、但当 sync0 脉冲出现时、它将出现 10-30 个用例、因为存在一个待处理的 ISR、并且我们已经在触发 Sync0 脉冲时的 ISR 中。  

    对我来说、这感觉是正常情况、但是我们只需要一种方法来在离开 PWM ISR 之前将其清除、包括任何待处理的事件。  

    这有什么用吗?

    Dorion  

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

    尊敬的 Dorion:

    我们已经了解了非零窗口。 感谢您的说明、是的、这在重新创建更接近您的设置的内容方面当然有帮助。 我刚刚 按照您的描述完成了此示例  的编写、并计划明天测试一个解决方法。

    此致、

    Allison

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

    尊敬的 Dorion:

    感谢您的耐心。 我能够为此创建一个测试案例、并相信我为您找到了一个解决方案。 请查看下面随附的示例。  顶部和整个主 C 文件中的注释应该更详细地说明测试用例以及分辨率的工作原理。

    e2e.ti.com/.../epwm_5F00_pending_5F00_counted_5F00_isr_5F00_example.zip

    总结:

    • 在 PWM 初始化中:
      • 将 PWM 中断事件生成设置为每个“x"事件“事件发生(其中 x > 1)。 在本例中、我将我的设置为“2"。“。
      • 将 PWM 中断事件计数初始化为“x-1",“,以便、以便下一个发生的事件将触发 ISR。  
    • 在 PWM ISR 中:
      • 在 ISR 开始时禁用 PWM 中断。
      • 在重新启用 PWM 中断之前、强制在 ISR 中重新加载 PWM 中断事件计数。
      • Re 在 ISR 结束时启用 PWM 中断、以允许下一个 PWM ISR(但防止任何挂起的 ISR 触发不必要的背对背中断)。

    观察结果:

    • 示波器信号:
      • CH1:EPWM2 通道 A(更快的 PWM、每个 CTR = 0 都会触发 ISR)
      • CH2:EPWM1 通道 A(向 EPWM2 发送同步的较慢 PWM)
      • CH3:GPIO25、在 ISR 开始时切换为高电平、在 ISR 结束时切换为低电平
    • 问题
      • 未实施上述方法时:
      • 我们可以看到、当 CH2 PWM 发出同步 脉冲(当 CH2 变为高电平时)时、CH3 显示了背对背中断。

    • 效率较低
      • 通过执行上述方法:
      • 我们可以看到、CH3 不再显示背对背中断。  

    如果您想自行运行、请注意、我使用的是使用 20MHz 晶体的 F2838x controlCARD(而不是某些修订版使用的 25MHz)、因此我在工程属性中添加了“USE_20MHz_XTAL"预定“预定义符号、以确保其正常运行。

    请尝试实施此解决方案、并告诉我您是否能够看到您的最终行为发生了变化!

    此致、

    Allison

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

    尊敬的 Allison:  

     让我看看这一切,我会在几天内回来给你。 好的、我可以通过显示通道 3 来重现挂起的 ISR

     我不明白这样做:  

    • 将 PWM 中断事件生成设置为每个“x"事件“事件发生(其中 x > 1)。 在本例中、我将我的设置为“2"。“。
    • 将 PWM 中断事件计数初始化为“x-1",“,以便、以便下一个发生的事件会触发 ISR

     Dorion  

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

    尊敬的 Dorion:

    控制 PWM ISR 发生的关键不是中断标志、而是 中断事件 内存

    当前(如果您看到问题)、您每个“1"事件“事件生成一个中断。 当您返回到背 ISR 时、这是因为您首先接收到常规 ISR 触发、它会将中断计数递增到“1",“,并、并立即将中断计数器复位为“0"(“(因为(因为 ISR 会立即执行)。 下一个中断请求(发生同步时)将再次将计数递增到“1",“,并、并保持在该值 、直到第一个 ISR 完成。 一旦第二个(不需要的)ISR 被触发、中断计数将复位为 0 并等待下一个中断请求。  

    实际上、中断事件计数器是存储挂起中断的内容。

    通过在重新启用中断之前更改中断事件计数、我们正在复位中断计数器 以清除任何使该计数器递增的挂起中断请求。  我任意选择了值“2",“,但、但 只要您将中断事件计数初始化为比中断生成级别低 1 的值(强制重新加载)、该方法就适用于任何一对值。 我理解你的困惑可能来自哪里-->我实际上做了一个拼写错误、因为“x"实际上“实际上不需要大于 1;我会在我的帖子中修正它Slight smile

    这里是我测试的一些值、它们的工作原理都是相同的、因为我们初始化为低于中断触发电平的 1 个值。

    • 每个“1"事件“事件生成事件
    • 将 PWM 事件计数初始化为“0"</s>“

    • 每 2 个事件生成一次事件
    • 将 PWM 事件计数初始化为“1"</s>“

    • 每 4 个事件生成一次事件
    • 将 PWM 事件计数初始化为“3"</s>“

    希望这有助于解释!

    此致、

    Allison

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

    Allison、  


     解释得很好。   

     我假设除非禁用 PWM、否则您无法复位中断计数、因此为什么在获取 ISR、将其复位并重新启用时将其禁用、从而清除任何待处理的 ISR?

    Dorion  

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

    尊敬的 Dorion:

    很高兴听到这个消息。  是的、出于好奇、我还尝试了另外两种情况:(1)重新启用 ISR 中的中断后重置计数器、以及 (2) 在不禁用/重新启用 ISR 中的中断的情况下重置计数器->这两种情况仍然可以连续检查 ISR。

    此致、

    Allison

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

    尊敬的 Allison:  

     太棒了 让我来研究一下、看看它是否有帮助。 我不明白为什么不、因为它基本上是清除我们待处理的 ISR。  

     感谢您的帮助!

    Dorion  

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

    尊敬的 Dorion:

    太棒了,是的,让我知道,如果你也看到了变化,或有进一步的问题,因为你正在尝试它. 很乐意提供帮助!

    此致、

    Allison

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

    您好 Allison

     我能够尝试您的示例。 有几件事需要我理解、请确认:
     
    1.如果您要获得事件计数,它会告诉您当前有多少个待处理。 这意味着在 ISR 中、在当前中断内出现挂起的中断之前、我的计数从未达到 1(我使用的 ISR 触发器为 1)。  

    2.当我应用您的示例禁用 PWM,重新初始化事件计数器为零,只有当计数为 1 或更大时才启用 PWM,然后它是有效的。  

    我只做了步骤编号以验证我有一个待处理的 ISR、并且它已被清除。  

    在我的示例中、我还在离开 ISR 之前保留了一个变量来指示 PWM 计数。如果我再次进入 ISR、PWM 计数大于我上次知道我回来后进行递增计数的记录。 当我实施您的示例时、此计数器永远不会上升。 它告诉我您的示例代码效果很好。  

    在我得到您对上面第 1 号的回答后、我将表明上述是正确的解决方案。  

    Dorion  

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

    尊敬的 Dorion:

    很高兴听到这个解决方案对您有用! Slight smileμ s

    1 号正确。 当请求传入时、事件计数将递增、当溢出实际执行中断的“阈值“时、事件计数将在 0 时重新启动。 因此、如果您每“1"事件“事件生成一个中断、那么在您首次收到中断请求时、事件计数器将递增、进入 ISR、事件计数器将自动复位为 0。 如果您在该 ISR 期间收到另一个中断请求、那么它将处于挂起状态;因此、事件计数应保持在“1",“,直到、直到该 中断被发送到中断控制器以实际执行下一个 ISR。

    此致、

    Allison

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

    Allison、  

     太棒了! 感谢您的帮助,并帮助我们解决这个问题。 它运行良好。  

    Dorion  

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

    Dorion、

    没问题! 很高兴听到这个消息。 如果您遇到任何其他问题、请随时创建另一个主题。

    此致、

    Allison

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

    Allison、  

     我希望您能回答另一个问题。  

     我们拥有的代码正在运行、但现在我想计算它的发生频率。 如果发生在 ISR 处理程序的前 1 usec 内、则没关系。  

     我们所做的代码基本上会清除任何挂起的 ISR、然后在 ISR 处理程序的末尾、检查是否有任何挂起的 ISR、如果有、我们会计算这些 ISR。  

     具体情况是、当我们清除任何待处理的 ISR(这意味着我们无论如何都会这样做)时、除非我们离开 ISR 处理程序、否则绝不会获得另一个待处理的 ISR。 如果我不仅仅自动清除任何挂起的中断、而是设置一个中断、那么在 ISR 的稍后阶段我们确实会处理一个挂起的中断。

    在您的示例中、如果您更改了代码以使您在 ISR 处理程序顶部清除待处理的 ISR(之前有一个)、然后再检查您是否有一个、我认为您不会看到一个待处理的 ISR。  

     这是预期行为吗?

    Dorion  

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

    Dorion、

    Allison 目前不在办公室、下周回来时会联系您。 谢谢!

    此致、

    Aishwarya

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

    尊敬的 Dorion:

    对延误表示歉意 — 我将在一段较长的时间内离任。 我将尝试在下周得到您的回复。 感谢您的耐心!

    此致、

    Allison

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

    尊敬的 Dorion:  

    我回到办公室 — 感谢耐心。  关于您的询问:

    ]具体情况是、当我们清除任何待处理的 ISR(这意味着我们无论如何都会这样做)时、除非我们离开 ISR 处理程序、否则绝不会获得另一个待处理的 ISR。 如果我不只是自动清除任何挂起的中断、而只是执行如果设置了中断、那么稍后在 ISR 中我们确实有一个挂起的中断。

    为了便于我理解、您能否在第二个案例中简要介绍一下您的 ISR?

    澄清一下、您是否尝试仅在单个 ISR 发生在特定时间范围内时才清除该 ISR? 这意味着、如果您在仍在处理第一个 ISR 时收到挂起的 ISR、但时间在稍后、则需要保留挂起的 ISR?

    此致、

    Allison

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

    尊敬的 Allison:  

     希望您能享受假期。 回答您的问题。 无论是否可以在 ISR 函数中提前获得一个 ISR、我们都需要清除待处理的 ISR。我们希望跟踪是否在 ISR 函数中稍后获得一个 ISR 是非法的  

     代码片段。 如果我们只在下面的第一个检查中清除挂起的 ISR、那么第二个检查将不会显示挂起的 ISR。 在我们的例子中、在为 ADC 提供服务之前、拥有一个待处理的 ISR 是合法的、但在其他任何地方都是非法的。  

    __interrupt void MotorFclISR (void)

       //确保已启用 FCL ISR。
      if (FclServiceISR()){
       //到达此处并拥有一个待处理的 ISR 并不非法
        //如果我们有一个只需清除它。
        IF(FclCheckForPendingISR())
        {
          FclClearPendingISR();
        }

        FclHarvestAllAdcValues ();

        //为正确的项目开始 FCL 处理 motor_last 将被正确设置
        for (int i = motor_A;i < motor_last;i++){
          pMotor =&(gMotorPtrs[i]);
          pFclHwResults = pMotor->pFclHwResults;
          pFclSwResults = pMotor->pFclSwResults;

          //在调用跟踪之前、我们需要从 pFcl 结构中获取外径。
          Cpu2MotorHarvestLocalToOD (pMotor);
        }
      }

      //清除任何挂起的中断需要一段时间
      //在清除之前进行检查以确保存在某种情况。
      IF(FclCheckForPendingISR())
      {
        pFclHwResults = gMotorPtrs[MOTOR_A].pFclHwResults;
        *(pFclHwResults->pFclPendingIsrCount)+= 1;

        FclClearPendingISR();
      }

    这可以回答您的问题吗?

    Dorion  

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

    尊敬的 Dorion:

    非常感谢您的背景。 我相信这回答了我的问题 — 让我看看我能否在第二天或第二天测试您看到的内容,然后我会再报告。

    此致、

    Allison

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

    尊敬的 Dorion:  

    抱歉,我本周无法完成测试。 让我在下周初为您提供最新信息、如果出现更紧急的情况、请让我知道。 感谢您的耐心!

    此致、

    Allison

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

    好的。  

    Dorion  

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

    尊敬的 Dorion:

    很抱歉耽误您的时间、但我没有看到您所描述的相同行为。 我对我们的示例进行了一些修改、在这个示例中、我可以在几个点检查中断事件计数以查看 ISR 中是否发生了中断请求、并且我提高了 EPWM1 的频率、使其能够更快地触发 EPWM2 同步脉冲(和中断请求)。

    我将断点设置为在每次在 ISR 开始(占位符延迟之前)以及稍后在 ISR 中(占位符延迟之后)记录中断计数(只是一个简单的 IntCount 变量)时暂停。 第一次检查 ISR 开始时、我可以看到挂起的中断请求会填充、之后可以立即将其清除/复位、看看 IntCount 是否已清除/复位、再次检查中断事件 count IntCount 时、我也仍然可以在 ISR 中看到挂起的中断填充。 这也是我所期望的。

    因此、在这种情况下、我认为在 ISR 中间检查和清除/复位中断事件计数器似乎是合理的、这样 ISR 中就不会有早期待处理的中断请求、而是允许 ISR 中稍后的待处理中断请求。  

    此致、

    Allison

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

    Allison、  

     感谢您的帮助和回复。 我会在我这边深入研究 在读取您的响应后、我尝试了一些操作、如果我将 ISR 计数更改为 2 而不是 1、我会获得更好的结果。 奇数。  

    Dorion