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.

[参考译文] LAUNCHXL-F280049C:启用 ePWM (3A/B、4A/B、5A/B)

Guru**** 2524550 points
Other Parts Discussed in Thread: C2000WARE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1179590/launchxl-f280049c-enable-epwm-3a-b-4a-b-5a-b

器件型号:LAUNCHXL-F280049C
主题中讨论的其他器件:C2000WARE

您好!  

我尝试通过将 GPAPUD.bit.GPIO8设置为1并 设置 GPAMUX1.bit.GPIO8=1 (更改了 PWM_CH=3)来修改 C2000内置示例"hrowm_ex1_Duty_SFO_v8.c"、以同时启用 EPWM5A、我想 ePWM5A、GPAMUX1.bit.GPIO8=1或 GPIO8=1、它不总是启用。

两个不常见的情况:GPIO0、GPIO1 (ePWM[0]、ePWM[1])良好、而我发现 ePWM[2]的值为0??? 这里有问题。 SWFSYNC=1在 ePWM[2]的情况下,我发现在线解释说这个数字应该为零,但我不知道如何解决这个问题。  

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

    华、

    您的代码是基于任何示例还是您编写的?

    ePWM 寄存器的基地址如下所示:

    您能否检查在何处分配阵列中 EPWM 的基址?

    此致、Santosh

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

    Santosh、

    Bulit 输入示例: hrowm_ex1_Duty_SFO_v8.c.

     

    我检查了多个子代码文件、不确定它在何处分配地址。 上一张图片显示了右上角的地址。 还检查了新的放大附件。 我们可以从这方面得到什么提示?  

    请提供建议!

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

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

    您好!

    您能否共享项目以便我可以查看它?

    我很难评论其他方面

    此致、Santosh

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

    //########################################################################################################################

    //

    //文件:  HRPWM_ex1_Duty_SFO_v8.c

    //

    //标题: HRPWM SFO V8高分辨率周期

    //      (向上计数)示例

    //

    //! addtogroup bitfield_example_list

    //!

    HRPWM 占空比递增计数

    //!

    //! 此示例修改 MEP 控制寄存器以显示边沿位移

    //! ePWM 处于向上计数模式时的高分辨率周期

    //! 相应 ePWM 模块的 HRPWM 控制扩展。

    //!

    //! 此示例调用以下 TI 的 MEP 比例因子优化器(SFO)

    //! 软件库 v8函数:

    //!

    //! b int \b SFO ();\n

    //! 使用 HRPWM 时动态更新 MEP_ScaleFactor

    //! 更新 HRMSTEP 寄存器(只存在于 EPwm1Regs 寄存器空间中)

    //! 具有 MEP_ScaleFactor 值

    //! -如果错误:MEP_ScaleFactor 大于最大值255、则返回2

    //!  (在这种情况下、自动转换可能无法正常工作)

    //! -完成指定通道时返回1

    //! -如果指定通道的值没有完成、则返回0

    //!

    //! 本示例旨在说明 HRPWM 功能。 代码可以是

    //! 针对代码效率进行了优化。 请参阅 TI 的数字电源应用

    //! 示例和 TI 数字电源软件库以了解详情。

    //!

    //! 要运行此示例:

    //! -#在最大 SYSCLKOUT 上运行此示例

    //! -#激活实时模式

    //! -#运行代码

    //!

    //! b 外部连接\n

    //!  -监控示波器上的 ePWM1 A/B 引脚。

    //!

    //! b 监视\b 变量\n

    //!  -状态-运行状态示例

    //!  - UpdateFine -设置为1使用 HRPWM 功能并在精细 MEP 中观察

    //!         步骤(默认)

    //!         设置为0可禁用 HRPWM 功能并在中观察

    //!         粗略 SYSCLKOUT 周期步长

    //!

    //

    //########################################################################################################################

    //

    //

    //版权所有:

    //版权所有(C) 2022德州仪器(TI)公司- http://www.ti.com/

    //

    //以源代码和二进制形式重新分发和使用,有无  

    //如果满足以下条件,则允许进行修改  

    //满足:

    //  

    // 重新分发源代码必须保留上述版权  

    // 注意、此条件列表和以下免责声明。

    //  

    // 二进制形式的重新分发必须复制上述版权

    // 注意、中的条件列表和以下免责声明  

    // 随提供的文档和/或其他材料   

    // 分布。

    //  

    // 德州仪器公司的名称和的名称都不是

    // 其贡献者可用于认可或推广衍生产品

    // 未经特定的事先书面许可,从该软件下载。

    //  

    //本软件由版权所有者和作者提供  

    //“原样”以及任何明示或暗示的保证,包括但不包括  

    //限于对适销性和适用性的暗示保证

    //一个特定的目的是免责的。 在任何情况下、版权均不得  

    //所有者或贡献者应对任何直接、间接、偶然、  

    //特殊、典型或必然的损害(包括但不包括)  

    //仅限于采购替代货物或服务;

    //数据或利润;或业务中断)

    //责任理论,无论是合同责任、严格责任还是侵权行为  

    //(包括疏忽或其他)以任何方式因使用而产生  

    //此软件,即使已被告知可能会发生此类损坏。

    //$

    //########################################################################################################################

    //

    //包含的文件

    //

    #include "F28x_Project.h"

    #include "SFO_V8.h"

    //

    //定义

    //

    #define PWM_CH       3    // PWM 通道数- 1  //从2更改为4。

    #define STATUS_SUCCESS   1.

    #define STATUS_FAIL    0

    #define AUTOCONVERT    0    // 1 =开启自动转换

                     // 0 =关闭自动转换

    //

    //全局

    //

    uint16_t UpdateFine;

    uint16_t DutyFine;

    uint16_t status;

    uint16_t CMPA_REG_val;

    uint16_t CMPAHR_REG_val;

    uint16_t CMPB_REG_val;

    uint16_t CMPBHR_REG_val;

    int MEP_ScaleFactor;// SFO 库使用的全局变量

               //结果可用于所有 HRPWM 通道

               //此变量也被复制到 HRMSTEP

               //按 SFO ()函数注册。

    //由 SFO 库使用(ePWM[0]是不使用的虚拟值)

    volatile struct ePWM_regs * ePWM[PWM_CH]={&EPwm1Regs、&EPwm1Regs};

    //

    //函数原型

    //

    void initHRPWM1GPIO (void);

    void configHRPWM (uint16_t period);

    void 错误(void);

    //

    //主函

    //

    void main (void)

      uint16_t i

      uint32_t temptemp1

      //

      //初始化设备时钟和外设

      //

      InitSysCtrl()

      //

      //初始化 GPIO

      //

      InitGpio()

      initHRPWM1GPIO()

      //

      //初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。

      //

      Dint;

      InitPieCtrl()

      IER = 0x0000

      IFR = 0x0000

      //

      //使用指向 shell 中断的指针初始化 PIE 矢量表

      //服务例程(ISR)。

      //

      InitPieVectTable()

      //

      //设置示例变量

      //

      UpdateFine = 1

      DutyFine = 0

      状态= SFO_INCOMPLETE;

      //

      //启用全局中断(INTM)和实时中断(DBGM)

      //

      EINT;

      ERTM;

      //

      // ePWM 和 HRPWM 寄存器初始化

      //

      对于(i=1 <PWM_CH; i++)

      

        //将时钟分频器更改为/1

        //(PWM 时钟需要> 60MHz)

        (* ePWM[i]).TBCTL.bit.HSPCLKDIV=0

      

      CONFIGHRPWM (10);  

       

      //

      //调用 SFO ()用校准更新 HRMSTEP 寄存器

      // MEP_ScaleFactor。 HRMSTEP 必须被填充一个比例因子值

      //在启用高分辨率周期控制之前。

      //

      while (status =SFO_Incomplete)

      

        状态= SFO ();

        if (status =SFO_ERROR)

        

          ERROR() // SFO 函数在发生错误时返回2,MEP 的编号为

               //步进/粗步进超出最大255。

      

      EALLOW;

      for (;;)

      

        //

        //将 DutyFine 扫描为0.2 - 0.999之间的 Q15数字

        //

        //for (DutyFine = 0x199A;DutyFine < 0x7FDF;DutyFine ++) //origin 代码

        对于(DutyFine = 0x199A;DutyFine < 0x199F;DutyFine++)

        

          if (UpdateFine)(更新)

          

            /*

            //下面的所有计算也适用于 CMPB

            // CMPA_REG_val,CMPA_REG_val 计算为 Q0。

            //因为 DutyFine 是一个 Q15数字,周期是 Q0

            //产品为 Q15。 为了存储为 Q0、我们向右移位

            // 15位。

            CMPA_REG_Val =((long) DutyFine *(EPwm1Regs.TBPRD + 1))>> 15;

            //接下来的步骤是获取剩余的内容

            //在上面的15位移位期间被截断。

            //计算整个值、然后减去 CMPA_REG_val

            //向左移动15位:

            temp =((long) DutyFine *(EPwm1Regs.TBPRD + 1));

            temp = temp -((long) cmpa_reg_val <15);

            //如果禁用自动转换,可以执行以下步骤

            //已跳过。 如果启用了自动转换、SFO 函数将会

            //将 MEP_ScaleFactor 写入 HRMSTEP 寄存器和

            //硬件将自动缩放中的其余部分

            // CMPAHR 寄存器中的 MEP_ScaleFactor。

            //因为上面计算的余数(temp)在 Q15中

            //格式、它必须向左移动1才能转换为 Q16

            //硬件正确转换的格式。

            CMPAHR_REG_val = temp<<1

            //如果启用了自动转换,则执行以下步骤

            //在硬件中自动执行,可以跳过

            //这从获取以数字表示的 MEP 计数

            // 0、1、... MEP_ScaleFactor。

            // 0x0080 (Q8中为0.5)通过移位转换为 Q15中的0.5

            //左7. 这被添加到中的分数 Duty*MEP_SF 产品中

            //顺序将产品的十进制部分向上舍入到

            //如果十进制部分>=0.5,则为下一个整数。

            //

            //因为这是 Q15,所以再次出现

            //通过移位转换为 Q0:

            CMPAHR_REG_Val =(temp*MEP_ScaleFactor+(0x0080<7))>15;

            //如果启用了自动转换,则执行以下步骤

            //在硬件中自动执行,可以跳过

            //现在低8位包含 MEP 计数。

            //因为 MEP 计数需要位于的高8位

            // 16位 CMPAHR 寄存器,向左移8位。

            CMPAHR_REG_val = CMPAHR_REG_val << 8;

            //如果启用了自动转换,则执行以下步骤

            //在硬件中自动执行,可以跳过

            //添加偏移和舍入

            CMPAHR_REG_Val += 0x0080;

            //将值作为一个32位写入寄存器

            //或两个16位

            EPwm1Regs.CMPA.bit.CMPA = CMPA_REG_val;

            EPwm1Regs.CMPA.bit.CMPAHR = CMPAHR_REG_val;

            *

            //

            //上述所有操作均可压缩

            //以下形式:

            // EPWM1计算

            //

            对于(i=1 <PWM_CH; i++)

            

              CMPA_REG_Val =((long) DutyFine *((* ePWM[i]).TBPRD + 1))>> 15

              CMPB_REG_val =((long) DutyFine *(* ePWM[i]).TBPRD + 1)>> 15

              temp =((long) DutyFine *(* ePWM[i]).TBPRD+1);

              TEMP1 =((long) DutyFine *(* ePWM[i]).TBPRD+1);

              temp = temp -((long) CMPA_REG_val << 15);

              TEMP1 = temp1 -((long) CMPB_REG_val << 15);

              #if (AUTOCONVERT)

              CMPAHR_REG_val = temp << 1//转换为 Q16

              CMPBHR_REG_val = temp << 1//转换为 Q16

              其他

              CMPAHR_REG_val =(temp * MEP_ScaleFactor)+

                       (0x0080 << 7))>> 15

              CMPAHR_REG_val = CMPAHR_REG_val << 8

              CMPBHR_REG_val =((temp1 * MEP_ScaleFactor)+

                       (0x0080 << 7))>> 15

              CMPBHR_REG_val = CMPBHR_REG_val << 8

              #endif

              //

              //向 CMPA:CMPAHR 写入32位的示例

              //

              (* ePWM[i]).cmpa.all =((long) cmpa_reg_val)<< 16 |

                         CMPAHR_REG_val;//丢失低8位

              //

              //对 CMPB:CMPBHR 进行32位写操作的示例

              //

              (* ePWM[i]).CMPB.ALL =((long) CMPB_REG_val)<< 16 |

                         CMPBHR_REG_val;//丢失低8位

            

          

          其他

          

            //

            // CMPA_REG_val 计算为 Q0。

            //因为 DutyFine 是一个 Q15数字,周期是 Q0

            //产品为 Q15。 为了存储为 Q0、我们向右移位

            // 15位。

            //

            对于(i=1 <PWM_CH; i++)

            

              (* ePWM[i]).cmpa.bit.cmpA =(((long) DutyFine *

                            ((* ePWM[i]).TBPRD + 1)>> 15);

              (* ePWM[i]).CMPB.bit.CMPB =(((long) DutyFine *

                            ((* ePWM[i]).TBPRD + 1)>> 15);

            

          

          //

          //调用换算系数优化器库函数 SFO ()

          //定期跟踪温度/电压引起的任何变化。

          //此函数通过运行生成 MEP_ScaleFactor

          HRPWM 逻辑中的// MEP 校准模块。 该比例

          //系数可用于所有 HRPWM 通道。 SFO ()

          //函数也使用更新 HRMSTEP 寄存器

          //比例因子值。

          //

          STATUS = SFO ();//在后台,MEP 校准模块

                  //持续更新 MEP_ScaleFactor

          如果(status =SFO_ERROR)

          

            ERROR() // SFO 函数在发生错误时返回2 &#

                  // MEP 步长/粗步长超过最大255。

          

        //结束循环的 DutyFine

      }//循环无限结束

    //

    // configHRPWM -配置所有 ePWM 通道并设置 HRPWM

    //         在 ePWMxA/ePWMxB  通道上

    //

    void configHRPWM (uint16_t 周期)

      uint16_t j

      (j=1<PWM_CH;j++)

      

        (* ePWM[j]).TBCTL.bit.PRDLD = TB_SHADOW; //设置立即加载

        (* ePWM[j]).TBPRD = 10*(周期-1);       // PWM 频率= 1/周期 ///比例上升10次[12/22]

        (* ePWM[j]).cmpa.bit.cmpA = 10*(周期/ 2); //初始设置占空比50% //系数为10个问题

        (* ePWM[j]).cmpa.bit.cmpaHR =(1 << 8); //初始化 HRPWM 扩展

        (* ePWM[j]).CMPB.bit.CMPB = 10*(周期/2); //开始时将占空比设置为50%

        (* ePWM[j]).CMPB.ALL |=(1 << 8);     //初始化 HRPWM 扩展

        (* ePWM[j]).TBPHS.ALL = 0

        (* ePWM[j]).TBCTR = 0

        (* ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UP;

        (* ePWM[j]).TBCTL.bit.PHSEN = TB_DISABLE;

        (* ePWM[j]).TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

        (* ePWM[j]).TBCTL.bit.HSPCLKDIV = TB_DIV1;

        (* ePWM[j]).TBCTL.bit.CLKDIV = TB_DIV1;

        (* ePWM[j]).TBCTL.bit.free_soft = 11

        (* ePWM[j]).cmPCTL.bit.LOADAMODE = CC_CTR_ZERO;

        (* ePWM[j]).cmPCTL.bit.LOADBMODE = CC_CTR_ZERO;

        (* ePWM[j]).cmPCTL.bit.SHDWAMODE = CC_SHADOW;

        (* ePWM[j]).cmPCTL.bit.SHDWBMODE = CC_SHADOW;

        (* ePWM[j]).AQCTLA.bit.ZRO = AQ_SET;   // PWM 切换为高电平/低电平

        (* ePWM[j]).AQCTLA.bit.CAU = AQ_CLEAR;

        (* ePWM[j]).AQCTLB.bit.ZRO = AQ_SET;

        (* ePWM[j]).AQCTLB.bit.CBU = AQ_CLEAR;

        EALLOW;

        (* ePWM[j]).HRCNFG.ALL = 0x0

        (* ePWM[j]).HRCNFG.bit.EDGMODE = HR_FEP; //下降沿上的 MEP 控制

        (* ePWM[j]).HRCNFG.bit.CTLMODE = HR_CMP;

        (* ePWM[j]).HRCNFG.bit.HRLOAD  = HR_CTR_ZERO;

        (* ePWM[j]).HRCNFG.bit.EDGMODEB = HR_FEP;//下降边沿上的 MEP 控制

        (* ePWM[j]).HRCNFG.bit.CTLMODEB = HR_CMP;

        (* ePWM[j]).HRCNFG.bit.HRLOADB  = HR_CTR_ZERO;

        #IF (AUTOCONVERT)

        (* ePWM[j]).HRCNFG.bit.AUTOCONV = 1  //启用自动转换

                            //逻辑

        #endif

        (* ePWM[j]).HRPCTL.bit.HRPE = 0//关闭高分辨率周期

                        //控制。

        EDIS;

      

    //

    // initHRPWM1GPIO -初始化 HRPWM1 GPIO

    //

    initHRPWM1GPIO ()

      EALLOW;

      //

      //禁用所选输出引脚的内部上拉

      //以降低功耗

      //用户可以启用或禁用上拉。

      //

      GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1  //禁用 GPIO0上的上拉电阻(EPWM1A)

      GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1  //禁用 GPIO1上的上拉电阻(EPWM1B)

      GpioCtrlRegs.GPAPUD.bit.GPIO8=1  //禁用 GPIO1 (EPWM5A) 上的上拉电阻器/12/22.

      //

      //使用 GPIO 寄存器配置 EPW-1引脚

      //这指定哪个可能的 GPIO 引脚将是 EPWM1功能

      //引脚。

      //

      GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1 //将 GPIO0配置为 EPWM1A

      GpioCtrlRegs.GPAMUX1.bit.GPIO1=1 //将 GPIO1配置为 EPWM1B

      GpioCtrlRegs.GPAMUX1.bit.GPIO8=1 //将 GPIO0配置为 EPWM5A

      EDIS;

    //

    //错误-调用时停止调试器

    //

    错误()

      ESTOP0;     //在此处停止并处理错误

    //

    //文件结束

    //

    第2nd2号

    第2nd2号

    第2nd2号

    第2nd2号

    第2nd2号

    GPIO_c 代码:

    //######################################################################################################################

    //

    //文件: f28004x_gpio.c

    //

    //标题: f28004x GPIO 模块支持函数

    //

    //######################################################################################################################

    //

    //

    //版权所有:

    //版权所有(C) 2022德州仪器(TI)公司- http://www.ti.com/

    //

    //以源代码和二进制形式重新分发和使用,有无  

    //如果满足以下条件,则允许进行修改  

    //满足:

    //  

    // 重新分发源代码必须保留上述版权  

    // 注意、此条件列表和以下免责声明。

    //  

    // 二进制形式的重新分发必须复制上述版权

    // 注意、中的条件列表和以下免责声明  

    // 随提供的文档和/或其他材料   

    // 分布。

    //  

    // 德州仪器公司的名称和的名称都不是

    // 其贡献者可用于认可或推广衍生产品

    // 未经特定的事先书面许可,从该软件下载。

    //  

    //本软件由版权所有者和作者提供  

    //“原样”以及任何明示或暗示的保证,包括但不包括  

    //限于对适销性和适用性的暗示保证

    //一个特定的目的是免责的。 在任何情况下、版权均不得  

    //所有者或贡献者应对任何直接、间接、偶然、  

    //特殊、典型或必然的损害(包括但不包括)  

    //仅限于采购替代货物或服务;

    //数据或利润;或业务中断)

    //责任理论,无论是合同责任、严格责任还是侵权行为  

    //(包括疏忽或其他)以任何方式因使用而产生  

    //此软件,即使已被告知可能会发生此类损坏。

    //$

    //######################################################################################################################

    //

    //包含的文件

    //

    #include "f28004x_device.h"

    #include "f28004x_examples.h"

    //

    // GPIO 配置的低级函数

    //

    //

    // InitGpio -设置所有引脚在带有上拉的输入模式下复用为 GPIO

    //启用。同时将 CPU 控制重置为 CPU1并禁用开漏

    //和极性反转、并将鉴定设置为同步。

    //也解锁所有 GPIO。 只能有一个 CPU 调用此函数。

    //

    无效

    InitGpio()

      易失性 uint32 *gpioBaseAddr

      uint16 regOffset

      //

      //禁用引脚锁定

      //

      EALLOW;

      GpioCtrlRegs.GPALOCK.ALL = 0x00000000

      GpioCtrlRegs.GPBLOCK.ALL = 0x00000000

      GpioCtrlRegs.GPHLOCK.ALL = 0x00000000

      //

      //用零填充所有寄存器。 分别写入每个寄存器

      //对于三个 GPIO 模块,此函数*非常*长。

      //幸运的是,我们无论如何都要用零来写入它们,

      //这样可以节省大量空间。

      //

      gpioBaseAddr =(uint32 *) GpioCtrlRegs;

      对于(regOffset = 0regOffset < sizeof (GpioCtrlRegs)/2regOffset++)

      

        //

        //必须避免在所有引脚上启用上拉。 GPyPUD 偏移量

        //每个0x40字的寄存器组中的0x0C。 因为这是 A

        // 32位指针,地址必须除以2。

        //

        //此外、为了避免将仿真器引脚的引脚复用更改为常规

        // GPIO、跳过 GPBMUX1 (0x46)和 GPBGMUX1 (0x60)。

        //

        if ((regOffset %(0x40/2)!=(0x0C/2)))&&(regOffset!=(0x46/2))&&

          (regOffset!=(0x60/2)))

        

          gpioBaseAddr[regOffset]= 0x00000000

        

      

      gpioBaseAddr =(uint32 *) GpioDataRegs;

      对于(regOffset = 0regOffset < sizeof (GpioDataRegs)/2regOffset++)

      

        gpioBaseAddr[regOffset]= 0x00000000

      

      EDIS;

    //

    // GPIO_SetupPinMux -设置指定引脚的外设多路复用。

    //可以在引脚分配电子表格中找到相应的参数。

    //

    无效

    GPIO_SetupPinMux (UINT16 gpioNumberUINT16 CPUUINT16 muxPosition)

      易失性 uint32 *gpioBaseAddr

      易失性 uint32 * mux、* gmux、* csel

      uint16 pin32pin16PIN8

      pin32 = gpioNumber % 32

      pin16 = gpioNumber % 16

      PIN8 = gpioNumber % 8

      gpioBaseAddr =(uint32 *)&GpioCtrlRegs +(gpioNumber/32)*GPY_CTRL_OFFSET;

      //

      //健全性检查有效的 CPU 和外设值

      //

      IF (CPU > GPIO_MUX_CPU1CLA ||多位置> 0xF)

      

        返回;

      

      //

      //创建指向相应寄存器的指针。 这是一种权变措施

      //表示 GPIO 寄存器的定义方式。 标准定义

      //在头文件中,可以很容易地对其中一个进行命名访问

      //寄存器或位,但很难执行任意的数字访问。 是的

      //更容易拥有一组具有相同寄存器的 GPIO 模块、

      //包括多寄存器组的数组,如 GPyCSEL1-4。 但是

      //头文件不定义任何可以转换为数组的内容,

      //因此使用手动指针算术。

      //

      MUX = gpioBaseAddr + GPYMUX + pin32/16

      gmux = gpioBaseAddr + GPYGMUX + pin32/16

      CSEL = gpioBaseAddr + GPYCSEL + pin32/8

      //

      //现在用于实际函数

      //

      EALLOW;

      //

      //要更改多路复用、先将外设多路复用器设置为0/GPIO 以避免

      //毛刺脉冲、然后更改组多路复用器、然后将外设多路复用器设置

      //其目标值。 最后、设置 CPU 选择。 此过程是

      //在 TRM 中进行了说明。 遗憾的是、由于我们不知道中的引脚

      //提前我们无法位字段引用进行硬编码,因此存在一些棘手的问题

      //此处的位变宽

      //

      *mux &=~(0x3UL <<(2*pin16));

      *gmux &=~(0x3UL <<(2*pin16));

      *gmux |=(uint32)((muxPosition >> 2)& 0x3UL)<<(2*pin16);

      *mux |=(uint32)(muxPosition & 0x3UL)<<(2*pin16);

      *CSEL &=~(0x3L <<(4*PIN8));

      *CSEL |=(uint32)(CPU & 0x3L)<<(4*PIN8);

      //

      //警告:此代码不会触及模拟模式选择寄存器。

      //

      EDIS;

    //

    // GPIO_SetupPinOptions -为设置 GPIO 输入/输出选项

    //指定的引脚。 这些标志是一个由 ORing 一起生成的16位掩码

    //选项。 对于输入引脚、有效标志为:

    // GPIO_PULLUP  使能上拉

    // GPIO_invert  启用输入极性反转

    // GPIO_SYNC  将输入锁存器同步到 PLLSYSCLK

    //        (默认值--您无需指定此值)

    // GPIO_QUAL3 使用3样本限定

    // GPIO_QUAL6 使用6样本鉴定

    // GPIO_异 步 不使用同步或限定

    //(注:只允许同步、QUAL3、QUAL6或异步中的一个)

    //

    //对于输出引脚、有效标志为:

     开漏模式下的// GPIO_OPENDRAIN 输出

    // GPIO_PULLUP   如果启用了漏极开路、也会启用上拉

    //和上面列出的输入限定标志(SYNC/QUAL3/QUAL6/SYNC)。

    //

    //没有标志,默认输入状态为同步,没有标志

    //上拉或极性反转。 默认输出状态为

    //标准数字输出。

    //

    无效

    GPIO_SetupPinOptions (UINT16 gpioNumberUINT16输出UINT16标志)

      易失性 uint32 *gpioBaseAddr

      volatile uint32 *dir、*pud、*inv、*OODR、*qsel

      uint32 pin32pin16pinMaskqual

      pin32 = gpioNumber % 32

      pin16 = gpioNumber % 16

      pinMask = 1UL << pin32

      gpioBaseAddr =(uint32 *)&GpioCtrlRegs +(gpioNumber/32)*GPY_CTRL_OFFSET;

      //

      //创建指向相应寄存器的指针。 这是一种权变措施

      //表示 GPIO 寄存器的定义方式。 标准定义

      //在头文件中,可以很容易地对其中一个进行命名访问

      //寄存器或位,但很难执行任意的数字访问。 是的

      //更容易拥有一组具有相同寄存器的 GPIO 模块、

      //包括多寄存器组的数组,如 GPyQSEL1-2。 但是

      //头文件不定义任何可以转换为数组的内容,

      //因此使用手动指针算术。

      //

      Dir = gpioBaseAddr + GPYDIR;

      Pud = gpioBaseAddr + GPYPUD;

      INV = gpioBaseAddr + GPYINV;

      ODR = gpioBaseAddr + GPYODR;

      qsel = gpioBaseAddr + GPYQSEL + pin32/16

      EALLOW;

      //

      //设置数据方向

      //

      *dir &=~pinMask

      如果(输出= 1)

      

        //

        //输出、具有可选的开漏模式和上拉电阻

        //

        *dir |= pinMask

        //

        //必要时启用开漏

        //

        IF (FLAGS & GPIO_OPENDRAIN)

        

          *ODR |= pinMask

        

        其他

        

          *ODR &=~pinMask

        

        //

        //如有必要,启用上拉。 开漏模式必须激活。

        //

        IF (flags &(GPIO_OPENDRAIN | GPIO_PULLUP))

        

          *pud &=~pinMask

        

        其他

        

          *pud |= pinMask

        

      

      其他

      

        //

        //输入、具有可选的上拉、限定和极性反转

        //

        *dir &=~pinMask

        //

        //如有必要,启用上拉

        //

        IF (FLAGS & GPIO_PULLUP)

        

          *pud &=~pinMask

        

        其他

        

          *pud |= pinMask

        

        //

        //必要时反极性

        //

        if (flags & GPIO_invert)

        

          *inv |= pinMask

        

        其他

        

          *inv &=~pinMask

        

      

      //

      //提取鉴定参数并将其加载到寄存器中。

      //开漏输出也需要这样做,所以我们也可以这样做

      //始终。

      //

      质量=(标志和 GPIO_异 步)/GPIO_QUAL3;

      * qsel &=~(0x3L <<(2 * pin16));

      如果(qual!= 0x0)

      

        *qsel |= qual <<(2 * pin16);

      

      EDIS;

    //

    // GPIO_SetupLock -为启用或禁用 GPIO 寄存器位锁定

    //指定的引脚。 有效标志为:

    // GPIO_UNLOCK  解锁指定引脚的引脚设置寄存器位

    // GPIO_LOCK  锁定指定引脚的引脚设置寄存器位

    //

    无效

    GPIO_SetupLock (UINT16 gpioNumberUINT16标志)

      易失性 uint32 *gpioBaseAddr

      易失性 uint32 *lock

      uint32 pin32pinMask

      pin32 = gpioNumber % 32

      pinMask = 1UL << pin32

      gpioBaseAddr =(uint32 *)&GpioCtrlRegs +(gpioNumber/32)*GPY_CTRL_OFFSET;

      //

      //创建指向相应寄存器的指针。 这是一种权变措施

      //表示 GPIO 寄存器的定义方式。 标准定义

      //在头文件中,可以很容易地对其中一个进行命名访问

      //寄存器或位,但很难执行任意的数字访问。 是的

      //更容易拥有一组具有相同寄存器的 GPIO 模块、

      //包括多寄存器组的数组,如 GPyQSEL1-2。 但是

      //头文件不定义任何可以转换为数组的内容,

      //因此使用手动指针算术。

      //

      LOCK = gpioBaseAddr + GPYLOCK;

      EALLOW;

      if (标志)

      

        //

        //锁定引脚

        //

        *lock |= pinMask

      

      其他

      

        //

        //解锁引脚

        //

        *lock &=~pinMask

      

      EDIS;

    //

    //外部中断设置

    //

    无效

    GPIO_SetupXINT1Gpio (uint16 gpioNumber)

      EALLOW;

      InputXbarRegs.INPUT4SELECT = gpioNumber   //将 XINT1源设置为 GPIO 引脚

      EDIS;

    无效

    GPIO_SetupXINT2Gpio (uint16 gpioNumber)

      EALLOW;

      InputXbarRegs.INPUT5SELECT = gpioNumber   //将 XINT2源设置为 GPIO 引脚

      EDIS;

    无效

    GPIO_SetupXINT3Gpio (uint16 gpioNumber)

      EALLOW;

      InputXbarRegs.INPUT6SELECT = gpioNumber   //将 XINT3源设置为 GPIO 引脚

      EDIS;

    无效

    GPIO_SetupXINT4Gpio (uint16 gpioNumber)

      EALLOW;

      InputXbarRegs.INPUT13SELECT = gpioNumber   //将 XINT4源设置为 GPIO 引脚

      EDIS;

    无效

    GPIO_SetupXINT5Gpio (uint16 gpioNumber)

      EALLOW;

      InputXbarRegs.INPUT14SELECT = gpioNumber  //将 XINT5源设置为 GPIO 引脚

      EDIS;

    //

    // GPIO_ReadPin -读取指定引脚的 GPyDAT 寄存器位。

    //请注意,这将返回引脚的实际状态,而不是的状态

    //输出锁存。

    //

    uint16

    GPIO_ReadPin (uint16 gpioNumber)

      volatile uint32 *gpioDataReg

      uint16 pinVal

      gpioDataReg =(volatile UINT32 *)&GpioDataRegs +(gpioNumber/32)*GPY_DATA_OFFSET;

      PinVal =(gpioDataReg[GPYDAT]>>(gpioNumber % 32))和0x1

      返回 pinVal

    //

    // GPIO_WritePin -设置指定引脚的 GPyDAT 寄存器位。

    //

    无效

    GPIO_WritePin (UINT16 gpioNumberUINT16 outVal)

      volatile uint32 *gpioDataReg

      uint32引脚掩码

      gpioDataReg =(volatile UINT32 *)&GpioDataRegs +(gpioNumber/32)*GPY_DATA_OFFSET;

      pinMask = 1UL <<(gpioNumber % 32);

      如果(outVal = 0)

      

        gpioDataReg[GPYCLEAR]= pinMask

      

      其他

      

        gpioDataReg[GPYSET]= pinMask

      

    //

    //文件结束

    //

    如果您需要其他代码文件、请告诉我。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="546927" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1179590/launchxl-f280049c-enable-epwm-3a-b-4a-b-5a-b/4445221 #4445221"] volatile struct ePWM_regs * ePWM[PWM_CH]={&EPwm1Regs、&EPwm1Regs};

    看起来您没有在数组中正确分配寄存器。

    这是您的定制应用程序、还是您使用 C2000Ware SDK 中的示例并对其进行了修改?

    此致、Santosh

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

    我 正在使用 C2000Ware SDK 中的一个示例,并尝试分配 ePWM 3ab、4ab、5ab。

    如何正确分配地址?

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

    您使用了哪个示例?

    我刚刚在我的系统上打开、它的初始化如下所示。

    volatile uint32_t ePWM[]=

      {0、myEPWM1_base、myEPWM2_base、myEPWM3_base、myEPWM4_base};

    请根据您的应用进行相应更改。

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

    JHA、

    谢谢! 我有想法。  

    在351/352/353行之间、我们分配了 CMPA.bit.CMPA=PERIOD/2、CMPB.bit.CMPB=PERIOD/2。我们是否使用这些变量来确定 PWM 的占空比? 我不确定我们是否在同一代码程序中使用此代码? 或者我们是否在使用其他不同的代码?

    在375行、EALLOW? 该变量来自哪里? 它首先分配在哪里?  

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

    请从此处尝试示例:

    C:/ti/c2000/C2000Ware_4_02_00_00/driverlib/f28004x/examples/hrpwm/hrpwm_ex1_duty_sfo.c

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

    我找到了它、在使用(不同文件夹) C:/ti/c2000/C2000Ware_4_02_00_00/driverlib/f28004x/examples/hrpwm/hrpwm_ex1_duty_sfo.c 中的代码之间有何不同

    C:/ti/c2000/C2000Ware_4_02_00_00/devicesupport/f28004x/examples/hrpwm/hrpwm_ex1_duty_sfo.c.

     

    而且、我仍然找不到 link 375 (上面) EALLOW 命令的源代码。  

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

    您好!

    它是 driverlib cpu.h 中的一个宏

    #ifndef EALLOW

    #ifndef __TMS320C28XX_CLA__

    #define EALLOW __EALLOW ()

    其他

    #define EALLOW __meallow()

    #endif //__TMS320C28XX_CLA__

    #endif // EALLOW

    看起来您已修改路径、否则您不应看到此错误。

    请 尝试导入任何 C2000Ware driverLib 示例、然后应该导入该示例。 重新编译它并打开 SYSCTRL.h、它应该多次调用 EALLOW。

    此致、Santosh

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

    您好 Santosh、

    这个  C:/ti/c2000/C2000Ware_4_02_00_00/driverlib/f28004x/examples/hrpwm/hrpwm_ex1_duty_sfo.c 是递增计数 PWM 输出 发生器吗?

    HRPWM_COUNTER_COMPARE_A 和...... Comparate_B 设置 HRPWMxA 和 HRPWMxB 输出的递增计数点?

    我看到这个代码文件已经通过 Device_initGPIO();(第120行)初始化 GPIO、但是我们如何知道哪个 GPIO 输出? 它们是 ePWM1A/1B 还是 ePWM2A/2B?

    如果我需要一个互补 PWM 输出对吗? (相同的频率、相同的占空比、180度相移、我可以使用此程序吗? 我应该修改什么?

    随附了下面的程序代码和谨致问候、

    ------------------------

    //########################################################################################################################

    //

    //文件: HRPWM_ex1_Duty_SFS.c

    //

    //标题: 具有 SFO 的 HRPWM 占空比控制。

    //

    //! \addtogroup driver_example_list

    //!

    具有 SFO 的 HRPWM 占空比控制

    //!

    //! 此示例修改 MEP 控制寄存器以显示边沿位移

    //! ePWM 处于向上计数模式时的高分辨率周期

    //! 相应 ePWM 模块的 HRPWM 控制扩展。

    //!

    //! 此示例调用以下 TI 的 MEP 比例因子优化器(SFO)

    //! 软件库 v8函数:

    //!

    //! b int \b SFO ();\n

    //! -使用 HRPWM 时动态更新 MEP_ScaleFactor

    //! -更新 HRMSTEP 寄存器(只存在于 EPwm1Regs 寄存器空间中)

    //! 具有 MEP_ScaleFactor 值

    //! -如果错误:MEP_ScaleFactor 大于最大值255、则返回2

    //!  (在这种情况下、自动转换可能无法正常工作)

    //! -完成指定通道时返回1

    //! -如果指定通道的值没有完成、则返回0

    //!

    //! 本示例旨在说明 HRPWM 功能。 代码可以是

    //! 针对代码效率进行了优化。 请参阅 TI 的数字电源应用

    //! 示例和 TI 数字电源软件库以了解详情。

    //!

    //! b 外部连接\n

    //!  -监控示波器上的 ePWM1/2/3/4 A/B 引脚。

    //

    //########################################################################################################################

    //

    //

    //版权所有:

    //版权所有(C) 2022德州仪器(TI)公司- http://www.ti.com/

    //

    //以源代码和二进制形式重新分发和使用,有无  

    //如果满足以下条件,则允许进行修改  

    //满足:

    //  

    // 重新分发源代码必须保留上述版权  

    // 注意、此条件列表和以下免责声明。

    //  

    // 二进制形式的重新分发必须复制上述版权

    // 注意、中的条件列表和以下免责声明  

    // 随提供的文档和/或其他材料   

    // 分布。

    //  

    // 德州仪器公司的名称和的名称都不是

    // 其贡献者可用于认可或推广衍生产品

    // 未经特定的事先书面许可,从该软件下载。

    //  

    //本软件由版权所有者和作者提供  

    //“原样”以及任何明示或暗示的保证,包括但不包括  

    //限于对适销性和适用性的暗示保证

    //一个特定的目的是免责的。 在任何情况下、版权均不得  

    //所有者或贡献者应对任何直接、间接、偶然、  

    //特殊、典型或必然的损害(包括但不包括)  

    //仅限于采购替代货物或服务;

    //数据或利润;或业务中断)

    //责任理论,无论是合同责任、严格责任还是侵权行为  

    //(包括疏忽或其他)以任何方式因使用而产生  

    //此软件,即使已被告知可能会发生此类损坏。

    //$

    //########################################################################################################################

    //

    //包含的文件

    //

    #include "board.h"

    #include "SFO_V8.h"

    #define ePWM_TIMER_TBPRD       100 UL

    #define MIN_HRPWM_Duty_Percent    4.0/((float32_t) ePWM_TIMER_TBPRD)* 100.0

    //

    //定义

    //

    #define LAST_ePWM_index_for_example   5.

    //

    //全局

    //

    float32_t dutyFine = min_HRPWM_Duty_percent;

    uint16_t status;

    int MEP_ScaleFactor;// SFO 库使用的全局变量

               //结果可用于所有 HRPWM 通道

               //此变量也被复制到 HRMSTEP

               //按 SFO ()函数注册。

    volatile uint32_t ePWM[]=

      0、myEPWM1_base、myEPWM2_base、myEPWM3_base、myEPWM4_base};

    //

    //函数原型

    //

    void 错误(void);

    //__interrupt void epwm1ISR (void);

    //__interrupt void epwm2ISR (void);

    //__interrupt void epwm3ISR (void);

    //__interrupt void epwm4ISR (void);

    //

    //主函

    //

    void main (void)

      uint16_t i = 0

      //

      //初始化设备时钟和外设

      //

      device_init()

      //

      //禁用引脚锁定并启用内部上拉。

      //

      DEVICE_initGPIO()

      //

      //初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。

      //

      interrupt_initModule()

      //

      //使用指向 shell 中断的指针初始化 PIE 矢量表

      //服务例程(ISR)。

      //

      interrupt_initVectorTable()

      //

      //将中断服务例程分配给 ePWM 中断

      //

      //中断寄存器(INT_EPWM1、epwm1ISR);

      //中断寄存器(INT_EPWM2、epwm2ISR);

      //中断寄存器(INT_EPWM3、epwm3ISR);

      //中断寄存器(INT_EPWM4、epwm4ISR);

      //

      //调用 SFO ()使用校准的 MEP_ScaleFactor 更新 HRMSTEP 寄存器。

      // HRMSTEP 必须在启用前填充比例因子值

      //高分辨率周期控制。

      //

      while (status =SFO_Incomplete)

      

        状态= SFO ();

        if (status =SFO_ERROR)

        

          ERROR() // SFO 函数在发生错误时返回2,MEP 的编号为

               //步进/粗步进超出最大255。

      

      //

      //禁用同步(也冻结 PWM 的时钟)

      //

      SYSCTL_DisablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);

      //

      //初始化 ePWM GPIO 引脚并将 XBAR 输入从使用 GPIO0更改为使用 GPIO0

      //

      Board_init()

      //

      //启用到 PWM 的同步和时钟

      //

      SYSCTL_enablePeripheral (SYSCTL_Periph_CLK_TBCLKSYNC);

      //启用 ePWM 中断

      //

      //中断_ENABLE (INT_EPWM1);

      //中断_ENABLE (INT_EPWM2);

      //中断_ENABLE (INT_EPWM3);

      //中断_ENABLE (INT_EPWM4);

      //

      //启用全局中断(INTM)和实时中断(DBGM)

      //

      EINT;

      ERTM;

      for (;;)

      

         //

         //扫描 DutyFine

         //

         对于(dutyFine = min_HRPWM_Duty_percent;dutyFine < 99.9;dutyFine += 0.01)

         

           DEVICE_DELAY_US (1000);

           对于(i=1 <LAST_EPWM_INDEX_FOR_EXAMPLE; i++)

           

             float32_t 计数=(dutyFine *(float32_t)(ePWM_TIMER_TBPRD << 8)))/100

             uint32_t compCount =(count);

             HRPWM_setCounterCompareValue (ePWM[i]HRPWM_COUNTER_COMPARE_AcompCount);

             HRPWM_setCounterCompareValue (ePWM[i]HRPWM_COUNTER_COMPARE_BcompCount);

           

           //

           //调用换算系数优化器库函数 SFO ()

           //定期跟踪温度/电压引起的任何变化。

           //此函数通过运行生成 MEP_ScaleFactor

           HRPWM 逻辑中的// MEP 校准模块。 该比例

           //系数可用于所有 HRPWM 通道。 SFO ()

           //函数也使用更新 HRMSTEP 寄存器

           //比例因子值。

           //

           STATUS = SFO ();//在后台,MEP 校准模块

                   //持续更新 MEP_ScaleFactor

           如果(status =SFO_ERROR)

           

             ERROR() // SFO 函数在发生错误时返回2 &#

                  // MEP 步进/粗步进

                  //超过最大255。

         

       

    //

    // epwm1ISR - ePWM 1 ISR

    //

    //__interrupt void epwm1ISR (void)

    //{

    //   ePWM_clearEventTriggerInterruptFlag (EPWM1_BASE);

    //   Interrupt_clearACKGroup (interrupt_ACK_Group3);

    //}

    //

    // epwm2ISR - ePWM 2 ISR

    //

    //__interrupt void epwm2ISR (void)

    //{

    //   ePWM_clearEventTriggerInterruptFlag (EPWM2_base);

    //   Interrupt_clearACKGroup (interrupt_ACK_Group3);

    //}

    //

    // epwm3ISR - ePWM 3 ISR

    //

    //__interrupt void epwm3ISR (void)

    //{

    //   ePWM_clearEventTriggerInterruptFlag (EPWM3_base);

    //   Interrupt_clearACKGroup (interrupt_ACK_Group3);

    //}

    //

    // epwm4ISR - ePWM 4 ISR

    //

    //__interrupt void epwm4ISR (void)

    //{

    //   ePWM_clearEventTriggerInterruptFlag (EPWM4_base);

    //   Interrupt_clearACKGroup (interrupt_ACK_Group3);

    //}

    //

    //错误-调用时停止调试器

    //

    错误()

      ESTOP0;     //在此处停止并处理错误

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

    您好!

    为什么要使用 HRPWM? 正常 PWM 是否适合您? 您的应用有什么要求?

    我建议您首先熟悉 ePWM 并检查它是否满足您的要求。 C2000Ware SDK DriverLib 示例中提供了多个示例。   

    C:/ti/c2000/C2000Ware_4_02_00_00/driverlib/f28004x/examples/epwm/CCS

    请通过 C2000 Academy 了解 ePWM、然后您可以尝试 ePWM 实验练习。

    当您的初始问题得到解决时、我现在将关闭此主题。 如果您有任何特定的 ePWM 问题、请创建新主题。

    此致、Santosh