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.

[参考译文] TMS320F28P650DK:使用基于计时器的采样实现多 GPIO 脉宽测量

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1637398/tms320f28p650dk-multi-gpio-pulse-width-measurement-using-timer-based-sampling

器件型号: TMS320F28P650DK

大家好!

我的要求:
当使用函数发生器施加 36 微秒导通时间脉冲时、该标志应递增。 对于 36 微秒以外的导通时间、标志不应递增。

当我只配置 16 个引脚时、它可以正常工作。 在“Expressions“(表达式)窗口中、我可以看到它 valid_count[3] 正在按预期增加。 但是、当我配置 32 个 GPIO 引脚时、可以在 debug_us[3] “Expressions“窗口中观察到不同的值。

这里的问题是什么?
是否无法配置 32 个引脚、或者是否有任何其他解决方案来捕获信号?

 

 

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

    尊敬的 Saravanan:

    有任何关于该主题的反馈吗?

    此致、

    Zackary Fleenor

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

    尊敬的 Fleenor:

    感谢您的答复。

    我遵循了您的方法、但在配置所有 32 个引脚时仍然看到一些垃圾值。 但是、它在仅使用 16 个引脚时工作正常。

    我使用了您建议的第三个选项。 您能帮助我解决这个问题吗?

    我面临两个问题:

    1. 当我在 36µs 导通时间内生成 50 个脉冲时、可以看到 rising 计数达到 50。 但是、valid_COUNT 仅达到 38、而不是 50。

    2. 在下面的代码中、我配置了 16 个引脚、在“Expressions“窗口中、valid_COUNT[0–15]正常工作。 但是、当我将配置扩展到 32 个引脚时、它无法按预期工作。

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

    您好、

    我使用 C2000 上的计时器 ISR(36µs 采样)在 32 个 GPIO 上测量~μ s 1µs 脉冲。

    问题:
    - Rising_count 匹配预期的脉冲(例如 50 个)
    - valid_count 低于预期值
    -有些脉冲没有得到验证

    配置:
    - CPU 频率:200MHz
    -采样: 1µs (Timer1 ISR)
    -目标脉冲:36µs±5µs
    -噪音抑制< 28µs
    -最大脉冲宽度: 80µs
    -确认边线:2 个样本

    以下是关键逻辑:

    ```c
    #define MIN_CYCLES (((36 - 5)* 200)
    #define MAX_CYCLES ((36 + 5)* 200)
    #define MIN_WIDTH_CYCLES (28 * 200)
    #define MAX_WIDTH_CYCLES (80 * 200)

    静态内联 uint32_t elapsedCycles (uint32_t start、uint32_t end)

    返回(结束-启动);
    }

    静态内联 void 处理器 Fall (uint16_t i、uint32_t fall_t、uint32_t now)

    uint32_t width = elapsedCycles (rise_time[i]、fall_ts);

    If (width < MIN_WIDTH_CYCLES)

    NOISE_COUNT[i]+;
    返回;
    }

    LAST_WIDTH_CYCLES[i]=宽度;

    if (width >= MIN_CYCLES && WIDTH <= MAX_CYCLES)

    VALID_COUNT[i]+;
    }
    }

    __ interrupt void cpuTimer1ISR (void)

    uint32_t now = getTimestamp ();
    uint32_t cu_b = GPIO_readPortData (GPIO_PORT_B);
    uint32_t cur_c = GPIO_readPortData (GPIO_PORT_C);

    对于 (uint16_t i = 0;i < 32;i++)

    if(!pin_enabled[i])continue;

    uint8_t hi =(pin_info[i]。port = 0)?
    (CUR_b 和 PIN_INFO[i].bit):
    (CUR_c 和 PIN_info[i]位);

    如果 (PIN_STATE[i]= 0)//空闲

    IF(高)

    if (confirm_COUNT[i]= 0)
    RISE_TIME[i]=现在;

    确认_COUNT[i]+;

    IF (CONFIRMAT_COUNT[i]>= 2)

    PIN_STATE[i]= 1;
    Confirm_COUNT[i]= 0;
    rising _count[i]+;
    }
    }
    暴露

    Confirm_COUNT[i]= 0;
    }
    }
    否则//高电平

    if(!hi)

    if (confirm_COUNT[i]= 0)
    CAND_FALL_TIME[i]=现在;

    确认_COUNT[i]+;

    IF (CONFIRMAT_COUNT[i]>= 2)

    processFall (i、cand_fall_time[i]、now);
    PIN_STATE[i]= 0;
    Confirm_COUNT[i]= 0;
    }
    }
    暴露

    Confirm_COUNT[i]= 0;

    如果 (elapsedCycles (rISE_TIME[i]、NOW)> MAX_WIDTH_CYCLES)

    ProcessFall(I,现在,现在);
    PIN_STATE[i]= 0;
    }
    }
    }
    }
    }

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

    尊敬的 Saravanan:

    我想查看该主题的状态。 我在上次答复中提供了:

    1. 根本原因分析 、确认您的 ISR 在 32 引脚处超出 1µs 执行预算
    2. 使用基于异或的边沿检测进行特定代码优化、并 __builtin_ctz() 仅处理更改的引脚
    3. 使用 ERAD 测量实际 ISR 执行时间的分析建议

    为了帮助推进这一工作、您能否提供以下方面的最新信息:

    • 您是否实施了基于异或的边沿检测方法? 这样、只需进行转换处理引脚、而不是每刻处理全部 32 个引脚、就可以显著减少 ISR 开销。

    • 您的实际 ISR 执行时间是多少? 您可以通过以下方式来衡量这一点:

      • 使用 ERAD 分析 、或
      • 在进入/退出 ISR 时切换 GPIO、并使用示波器进行测量
    • valid_count 所有 32 个引脚的缺口是否均匀、还是集中在特定的引脚索引上? 这将确认问题是 ISR 内时序偏斜还是总 ISR 溢出问题。

    • 编译器设置: 您使用的优化级别是(,,)-o0 -o2 -o3? ISR 是从闪存还是 RAM 执行?

    • 如果需要、CPU2 是否可用于工作负载拆分?

    如果您使用不同的方法解决了问题、我想了解哪些适用于您的应用。 如果您仍然遇到困难、上面的附加诊断信息将帮助我们确定确切的瓶颈。

    期待您的更新。

    此致、

    Zackary Fleenor