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.

[参考译文] TMS320F28377S:在 ISR 中高效实现滤波

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/587039/tms320f28377s-efficient-implementation-of-filtering-in-isr

器件型号:TMS320F28377S
主题中讨论的其他器件:C2000WARE

在我的项目中、我将在 ISR 例程中过滤 ADC 数据。 我希望尽快执行该数据采集环路、因此我对优化滤波过程的速度感兴趣。 我使用的是简单的 CIC 滤波器。 我很惊讶地发现、简单的加法或赋值每个加法或赋值都需要花费很多时钟周期来执行。 这对整个应用来说是非常有限的。 作为一个示例、我在下面包含了 C 代码和汇编代码。 我尝试更改 CCS 中的编译器优化设置、但在执行时间方面没有发现任何显著差异。 另请注意、这些变量是64位整数。 是与汇编指令数量相关的变量的大小。

如果能就更有效的执行提出任何建议,将不胜感激。

谢谢、
Matt  

C 代码:

//更新梳状过滤器的输出
CICFilter_com_v[0]= CICFilter_int_v[2]-CICFilter_com_v_old[0];
CICFilter_com_i[0]= CICFilter_int_i[2]- CICFilter_com_I_OLD[0];
CICFilter_com_v[1]= CICFilter_com_v[0]–CICFilter_com_v_old[1];
CICFilter_com_i[1]= CICFilter_com_i[0]–CICFilter_com_I_OLD[1];
CICFilter_com_v[2]= CICFilter_com_v[1]-CICFilter_com_v_old[2];
CICFilter_com_i[2]= CICFilter_com_i[1]-CICFilter_com_i_old[2];

//存储下一个循环的输入值;
CICFilter_com_v_old[0]= CICFilter_int_v[2];
CICFilter_com_i_old[0]= CICFilter_int_i[2];
CICFilter_com_v_old[1]= CICFilter_com_v[0];
CICFilter_com_i_old[1]= CICFilter_com_i[0];
CICFilter_com_v_old[2]= CICFilter_com_v[1];
CICFilter_com_i_old[2]= CICFilter_com_i[1];

汇编代码:

2649 CICFilter_com_v[0]= CICFilter_int_v[2]-CICFilter_com_v_old[0];
08b610:761F0444 MOVW DP、#0x444
08b612:A308 MOVL P、@0x8
08b613:060A MOVL ACC、@0xA
08b614:565D0030 Subul P、@0x30
08b616:56540032 SUBBL ACC、@0x32
08b618:761F0445 MOVW DP、#0x445
08b61a:A900 MOVL @0x0、P
08b61b:1E02 MOVL @0x2、ACC
2650 CICFilter_com_i[0]= CICFilter_int_i[2]- CICFilter_com_I_OLD[0];
08b61c:761F0444 MOVW DP、#0x444
08b61e:A32C MOVL P、@0x2C
08b61f:062E MOVL ACC、@0x2e
08b620:761F0445 MOVW DP、#0x445
08b622:565D0018 Subul P、@0x18
08b624:A90C MOVL @0xc、P
08b625:5654001A SUBBL ACC、@0x1A
08b627:1E0E MOVL @0xe、ACC
2651 CICFilter_com_v[1]= CICFilter_com_v[0]–CICFilter_com_v_old[1];
08b628:A300 MOVL P、@0x0
08b629:0602 MOVL ACC、@0x2
08b62a:761F0444 MOVW DP、#0x444
08b62c:565D0034 Subul P、@0x34
08b62e:56540036 SUBBL ACC、@0x36
08b630:761F0445 MOVW DP、#0x445
08b632:A904 MOVL @0x4、P
08b633:1E06 MOVL @0x6、ACC
2652 CICFilter_com_i[1]= CICFilter_com_i[0]-CICFilter_com_I_OLD[1];
08b634:A30C MOVL P、@0xc
08b635:060E MOVL ACC、@0xe
08b636:565D001C Subul P、@0x1c
08b638:5654001E SUBBL ACC、@0x1E
08b63a:A910 MOVL @0x10、P
08b63b:1E12 MOVL @0x12、ACC
2653 CICFilter_com_v[2]= CICFilter_com_v[1]-CICFilter_com_v_old[2];
08b63c:A304 MOVL P、@0x4
08b63d:0606 MOVL ACC、@0x6
08b63e:761F0444 MOVW DP、#0x444
08b640:565D0038 Subul P、@0x38
08b642:5654003A SUBBL ACC、@0x3a
08b644:761F0445 MOVW DP、#0x445
08b646:A908 MOVL @0x8、P
08b647:1E0A MOVL @0xA、ACC
2654 CICFilter_com_i[2]= CICFilter_com_i[1]-CICFilter_com_i_old[2];
08b648:A310 MOVL P、@0x10
08b649:0612 MOVL ACC、@0x12
08b64a:565D0020 Subul P、@0x20
08b64c:56540022 SUBBL ACC、@0x22
08b64e:A914 MOVL @0x14、P
08b64f:1E16 MOVL @0x16、ACC
2659 CICFilter_com_v_old[0]= CICFilter_int_v[2];
08b650:761F0444 MOVW DP、#0x444
08b652:C40A MOVL XAR6、@0xA
08b653:0608 MOVL ACC、@0x8
08b654:1E30 MOVL @0x30、ACC
08b655:C232 MOVL @0x32、XAR6
2660 CICFilter_com_i_old[0]= CICFilter_int_i[2];
08b656:C42E MOVL XAR6、@0x2e
08b657:062C MOVL ACC、@0x2C
08b658:761F0445 MOVW DP、#0x445
08b65a:1E18 MOVL @0x18、ACC
08b65b:C21A MOVL @0x1A、XAR6
2661 CICFilter_com_v_old[1]= CICFilter_com_v[0];
08b65c:C402 MOVL XAR6、@0x2
08b65d:0600 MOVL ACC、@0x0
08b65e:761F0444 MOVW DP、#0x444
08b660:1E34 MOVL @0x34、ACC
08b661:C236 MOVL @0x36、XAR6
2662 CICFilter_com_i_old[1]= CICFilter_com_i[0];
08b662:761F0445 MOVW DP、#0x445
08b664:C40E MOVL XAR6、@0xe
08b665:060C MOVL ACC、@0xc
08b666:1E1C MOVL @0x1c、ACC
08b667:C21E MOVL @0x1E、XAR6
2663 CICFilter_com_v_old[2]= CICFilter_com_v[1];
08b668:C406 MOVL XAR6、@0x6
08b669:0604 MOVL ACC、@0x4
08b66a:761F0444 MOVW DP、#0x444
08b66c:1E38 MOVL @0x38、ACC
08b66d:C23A MOVL @0x3a、XAR6
2664 CICFilter_com_i_old[2]= CICFilter_com_i[1];
08b66e:761F0445 MOVW DP、#0x445
08b670:C412 MOVL XAR6、@0x12
08b671:0610 MOVL ACC、@0x10
08b672:1E20 MOVL @0x20、ACC
08b673:C222 MOVL @0x22、XAR6

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

    Matt、

    C28x 上的两个独立运算支持减去64位整数:无符号减法(SUBUL)和带硼减法(SUBBL)。 在每行 C 的交错汇编代码中、您都可以看到这两行代码。 这是使用手工编码的装配体进行此操作的方法。

    可以节省几个周期的一件事是将所有三个数组链接到同一个数据页。 您可以使用 DATA_SECTION pragma 来实现该目的。 这将删除大多数 MOVW DP 指令。 否则、这与我对 C 代码的预期有关。 如果您使用的是32位数据、则周期计数将会相当大。

    您使用的器件具有 CLA、因此、一种可能提高效率的方法是使用 CLA 进行滤波。 CLA 任务将由 ADC 转换触发、并且您会在滤波数据准备就绪时触发 CPU 中断。 如果您没有考虑过它、只需提及它。

    此致、

    Richard

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

    感谢 Richard、

    我将尝试将数组链接到相同的数据页。 遗憾的是、我使用整数的所有64位、因此使用32位并不是真正的选择。  
    在 ISR 中完成滤波的同时、我在 CLA 中运行了一个控制器。 我确实考虑使用 CLA 进行滤波、但是、我认为我在某处读到 CLA 不支持 C 代码中的64位整数。 那么、如果我尝试将滤波移动到 CLA、我需要手动对汇编进行编码吗? 对我来说、这似乎是一项艰巨的任务、因为我对汇编代码没有任何经验、但可能是值得的。 有什么建议吗?
    Matt
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Matt、

    正确;CLA 不能很好地处理64位整数。 我想您可能会将浮点用于滤波器、在这种情况下、您可以使用 C 语言对其进行编码、您应该能够在 CLA 上获得良好的性能。 C2000Ware 中的 DCL 中有二阶和三阶控制器(DF22和 DF23结构)、这些控制器在 CLA 汇编语言中手动编码、因此如果可以选择浮点、并且您没有连接到 CIC 滤波器、它们的运行速度会非常快。

    此致、

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

    Matt、

    请先尝试重新排序代码。 编译器应足够智能、并将数组放在一个数据页中。

    BTW、您是否尝试提高编译器优化选项?

    我会这样尝试:

    //更新梳状过滤器的输出
    CICFilter_com_v[0]= CICFilter_int_v[2]-CICFilter_com_v_old[0];
    CICFilter_com_v[1]= CICFilter_com_v[0]–CICFilter_com_v_old[1];
    CICFilter_com_v[2]= CICFilter_com_v[1]-CICFilter_com_v_old[2];

    CICFilter_com_i[1]= CICFilter_com_i[0]–CICFilter_com_I_OLD[1];
    CICFilter_com_i[0]= CICFilter_int_i[2]- CICFilter_com_I_OLD[0];
    CICFilter_com_i[2]= CICFilter_com_i[1]-CICFilter_com_i_old[2];

    //存储下一个循环的输入值;
    CICFilter_com_v_old[0]= CICFilter_int_v[2];
    CICFilter_com_v_old[1]= CICFilter_com_v[0];
    CICFilter_com_v_old[2]= CICFilter_com_v[1];

    CICFilter_com_i_old[0]= CICFilter_int_i[2];
    CICFilter_com_i_old[1]= CICFilter_com_i[0];
    CICFilter_com_i_old[2]= CICFilter_com_i[1];