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.

[参考译文] TMS320F280038C-Q1:设置寄存器时的时钟周期计数差异

Guru**** 2537220 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1552625/tms320f280038c-q1-clock-cycle-count-discrepancy-when-setting-register

器件型号:TMS320F280038C-Q1


工具/软件:

您好:

在我上一篇文章 (此处找到)中 、我认为在 CPU 中设置寄存器可能比 CLA 快得多、因为 CPU 可以访问更大的指令集。 我的概念是、我设置代码将 PWM 设置从 CLA 传输到 CPU、以避免我之前看到的每条指令需要 8-10 个周期。 我需要设置大约 12 个不同的寄存器、以便额外的时钟周期快速增加。 不过、我发现在尝试使用 CLA2CPU 消息设置 PWM 寄存器时、我现在再次在 CPU 中看到 8-10 个周期。 我没有尝试调试 CLA 代码、发现以下虚拟代码的行为类似、左侧代码需要 3 个周期来设置 PHSDIR、右侧代码需要 8-10 个周期。  

左侧代码将 uint16 变量(“SET_RESET_BIT")“)设置为 200、递增 1、然后屏蔽该变量以设置 PHSDIR 位。 正确的代码是运行的 uint16 计数器(“set_bit_count")“)会递增、然后屏蔽以设置 PHSDIR 位。 您能帮助我了解为什么正确的代码需要延长 3 倍吗?  
 

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

    您好:

    仍在寻求有关此方面的帮助。

    谢谢

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

    对于左侧的代码 — 编译器知道 SET_RESET_BIT 的值始终为 2,因此它会利用这种知识 — C28x 不必读取变量、它可以直接使用数字 2。

    对于右侧的代码 — SET_BIT_COUNT 是一个变量、因此编译器做了更多的工作。 DP 移动会加载数据页指针、以访问变量和寄存器。  

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

    嗨、Lori、

    感谢您的答复。 我现在看到了第 13 位的 0x2000 常数。

    如果我想用一个可以在 0 和 1 之间交替的变量来设置 phsdir、我可以做的最好的 8 个时钟周期吗? 我知道我可以进行设置/清除

    像 EPwm1Regs.TBCTL |=(1<<13) 一样、 EPwm1Regs.TBCTL &=~μ s (0x2000)、速度更快、但没有太多改进、因为我需要包含其周围的逻辑。

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

    Jason、  

    一种思路 —  C28x 支持 MOV 和 MOV32(启用 FPU 时)指令、这些指令可以加载和存储 0-64K 范围内的地址。 这对于低内存中的外设操作非常有用。  这允许优化以下情况:

    // Define a struct for the peripheral register(s) or data. Must be in <= 64k of memory
    // for the optimization
    
    typedef struct {
        int x;
        int y;
    } PERIPHERAL;
    
    // Use the attribute to tell the compiler where the struct is
    // must match the registers or data struct location
    
    __attribute__((location((<location here>)))) PERIPHERAL peripheral;
    
    // Or address it directly with a pointer as shown
    
    #define peripheral (*(PERIPHERAL*)<location here>)

    这使得加载/存储能够避免 DP 访问“外设“或数据结构:

    global_int1 = peripheral.x;
    
    global_int2 = peripheral.y;
    
    peripheral.x = global_int1;
    
    peripheral.y = global_int2;