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.

[参考译文] MSP430FR6043:EIC 中断缺少边沿

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1487533/msp430fr6043-eic-interrupt-missing-edges

器件型号:MSP430FR6043

工具与软件:

我将尝试通过中断来检测 GPIO 上的上升沿和下降沿。

由于 MSP430FR6043仅允许检测一种类型的边沿、因此我将通过读取引脚的电流值来更改 ISR 内的 PxIES。

这种方法在大多数情况下都适用、但有时 无法检测 边沿。

到目前为止、我只看到了它缺失下降沿的情况、但我不能说检测到了所有上升沿。

该引脚连接到125Hz 的 PWM 信号、因此每次发生 ISR 之间存在4ms 的间隙。  当我测量引脚时、高电平为3.32V、低电平为 0V。

如何确保检测到所有边沿?

#pragma vector = PORT6_VECTOR
__interrupt void EIC_PORT6_ISR(void)
{
    HWREG16(P6_BASE + OFS_PAIFG) &= ~(GPIO_PIN0 << 8);
    
    if((HWREG16(P6_BASE + OFS_PAIN) & (GPIO_PIN0 << 8)) > 0)
    {
        HWREG16(P6_BASE + OFS_PAIES) |= (GPIO_PIN0 << 8);          
        GPIO_PIN0_Value = true;
    }
    else
    {
        HWREG16(P6_BASE + OFS_PAIES) &= ~(GPIO_PIN0 << 8);
        GPIO_PIN0_Value = false;
    }
    
    HWREG16(P6_BASE + OFS_PAIFG) &= ~(GPIO_PIN0 << 8);  
}

谢谢!

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

    您曾提到您的信号为 PWM (125Hz/4ms)。 它是否接近50%占空比、或者至少不接近0%或100%? 这将是主要的危险:如果两个边缘看起来非常接近。

    您如何辨别边缘是否被漏掉? (范围? 计数器? 调试器?)

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

    如果是我、我会使用两个引脚。 一个配置为上升沿、另一个配置为下降沿。 然后、读取 ISR 中的 P6IV、了解是哪一个引发了中断。 无需读取 P6IN 或更改 P6IES。

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

    其占空比接近50%。 高电平4ms、低电平4ms、周期8ms。  

    我将这些引脚连接到示波器、将 MSP430FR6043连接到调试器、并监控 GPIO_PIN0_VALUE。

    我将以下代码插入到 ISR 处理程序和主函数中。 在 ISR 处理程序中、我添加了一个序列来在未应用中断边沿切换的情况下检查 HWREG16 (P6_BASE + OFS_PAIES)值。

    从我观察到的内容中可以看出、在 ISR 处理程序中、 HWREG16 (P6_BASE + OFS_PAIES)具有正确的值(我通过 HWREG16 (P6_BASE + OFS_PAIES)和调试器读取的寄存器值进行了检查)。 此外、GPIO_PIN0_VALUE 与 ISR 处理程序中的痛值匹配。

    但是、在 main 函数中、我检测到几种 GPIO_PIN0_VALUE 为1的情况、但疼痛和示波器都指示信号电平较低。

    这就是我怀疑它有时缺少下降沿的原因。

    if((HWREG16(P6_BASE + OFS_PAIN) & (GPIO_PIN0 << 8)) > 0)
    {
        if(GPIO_PIN0_Value != true)
        {
            ISR_Missed = true;
        }
        else
        {
            ISR_Missed = false;
        }
    }
    else
    {
        if(GPIO_PIN0_Value != false)
        {
            ISR_Missed = true;
        }
        else
        {
            ISR_Missed = false;
        }
    }

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

    我曾考虑过该操作、或者随中断一起轮询 GPIO 值。  

    但最好知道问题的原因、确保 不会发生同样的情况。

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

     GPIO_PIN0_VALUE 是否被声明为"volatile"? 我想知道 main ()是否正在保留它的一个过时的副本。

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

    是的、GPIO_PIN0_VALUE 被声明为易失性

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

    您好、 

    如何 在调试中检查 GPIO_PIN0_VALUE? 但将它与示波器进行实时比较、我认为调试器和示波器之间可能会有一些时间延迟。

    您是否可以尝试设置 GPIO 输出来指示中断中检测到的偏置/下降沿? 此外、还尝试捕捉输入125Hz PWM 和输出 GPIO 以进行实时调试。

    此外、我建议您使用此方法、减少软件步骤并提高稳定性:

    如果是我、我将使用两个引脚。 一个配置为上升沿、另一个配置为下降沿。 然后、读取 ISR 中的 P6IV、了解是哪一个引发了中断。 无需读取 P6IN 或更改 P6IES。[/QUOT]

    此致、

    Helic

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

    事实,这是只可见在主要,而不是在 ISR ,告诉我,主要的观察是受害者的种族(或其他幻想)。

    但是、我很可能会遇到一些延迟问题(是的、4ms 是很长的时间)、我将观察到:

    用户指南(SLAU367P)第 12.2.6.2节中的表描述了切换 IES 可能触发 IFG 的情况。 事实证明、这些条件与漏掉边沿时能够看到的条件完全相同。 例如、当切换到下降沿时、如果 PxIN 已经为低电平、则设置 IFG。

    实际上、这些条件可追溯显示您 未看到的边线。 IFG 将立即返回到 ISR 进行注意。 这允许(渐近)长达一个完整周期的延迟。  

    战略是:

    1) 1)根据 IES (而不是 PxIN)推断触发了哪个边沿;如果是下降沿、则认定引脚转换为0、否则转换为1。

    2)始终反转("^=") IES。

    3) 3)请勿在 ISR 结束时清除 IFG、仅在开始时清除、因为您想了解 IES 触发器。

    这可能看起来类似(未经测试):

    __interrupt void PORT6_ISR(void)
    {
        P6IFG &= ~BIT0;        // We "know" it's P6.0 that got us here.
        if (P6IES & BIT0)      // Falling edge?
           GPIO_PIN0_Value = false; // Must have become 0
        else
           GPIO_PIN0_Value = true;  // Must have become 1
        P6IES ^= BIT0;         // Reverse sense; set IFG if we missed an edge
        return;
    }

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

    你好、Helic、

    我最初有一个使用4ms 计时器和 GPIO 控制生成 PWM 的单独 MCU。  

    为 检查 GPIO 中断操作、我将4ms 计时器和 GPIO 操作移到了 MSP430FR6043、并建立了单独的 MCU 来 输出从  MSP430FR6043接收到的镜像 GPIO 信号、并将其发送回 MSP430FR6043上的 P6.0。 我创建了一个变量、用于检查 PWM 输出电平以进行调试。 我确认了 MSP430FR6043生成的 PWM 以及单独 MCU 对信号进行镜像可以正常运行、而示波器上也没有问题。 然后、我在 MSP430FR6043上连接了调试器、并为上面的代码设置一个断点、在这个断点处它检查 GPIO_PIN0_VALUE 是否与 P6.0输入值不匹配。

    从该过程中、我确认了   当 MSP430FR6043 PWM 信号为低电平、并且单独的 MCU 也在输出低电平信号时 GPIO_PIN0_VALUE 与 P6.0输入值不匹配的情况。 停止的断点位于 main 函数中、而不是 ISR 中。  

    基于此、我得出结论、ISR 错过了下降沿。

    谢谢!

    最小

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

    Bruce、您好!

    我会尝试您的建议、但我需要几天时间来分析行为、因为发生是随机的、不频繁。

    谢谢!

    最小

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

    等待您的回复。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [报价 userid="558447" url="~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1487533/msp430fr6043-eic-interrupt-missing-edges/5727778 #5727778"]然后我连接了 MSP430FR6043上的调试器并为我的上述代码设置一个断点、在这个断点处它检查 GPIO_PIN0_VALUE 是否与 P6.0输入值不匹配。

    用于比较 PIN0_VALUE 与 P6.0的代码不是单个指令。 如果中断到达中间、会发生什么情况呢? 发生变化、您会得到不匹配情况。

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

    我还意识到该指令太长、因此我修改了代码、 如下所示:

    if(GPIO_PIN0_Value != ((HWREG16(P6_BASE + OFS_PAIN) & (GPIO_PIN0 << 8)) > 0))
    {
        ISR_Missed = true;
    }
    else
    {
        ISR_Missed = false;
    }

    此外、由于 PWM 电平每4ms 发生一次改变、我将 CCR 中断设置为2ms、从而延迟 GPIO_PIN0_VALUE 检查。 结果是相同的

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

    读取这两个值之间的任何间隙都是危险的。 将它们放入一条 C 语句不会 产生单个汇编语言指令。

    处理类似这样的临界区的正确方法是在进入中断之前先将其禁用、然后再启用。

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

    我曾尝试 建议在 ISR 中使用 PxIES 而不是 PxIN 来确定 GPIO 电平并切换 PxIES。

    我还在 GPIO 电平一致性检查指令前后添加了禁用/启用中断。

    不过、结果仍然与 缺少下降沿相同。

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

    我确信这个函数需要多长时间。

    您可以在此处添加一些 GPIO 设置/清除函数、以检查任务运行持续时间。

    方法是使用示波器观察 GPIO 正脉冲宽度。

    // Debug GPIO set here
    
    if(GPIO_PIN0_Value != ((HWREG16(P6_BASE + OFS_PAIN) & (GPIO_PIN0 << 8)) > 0))
    {
        ISR_Missed = true;
    }
    else
    {
        ISR_Missed = false;
    }
    
    // Debug GPIO clear here

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

    在使用一些代码在 G2553 Launchpad 上测试此功能时、我意识到存在第二个危险。 除了在检查过程中触发中断之外、引脚也可能发生变化。

    一旦我添加了代码以禁用边缘附近的检查、问题就会消失。

    因此、我怀疑这种不一致性是代码的产物、而不是实际中断缺失的结果。