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-F28069M:Simulink 中 ePWM 的死区

Guru**** 2563250 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/639661/launchxl-f28069m-deadband-for-epwm-in-simulink

器件型号:LAUNCHXL-F28069M

大家好! ;)

我现在已经完成了构建用于电机控制的三相逆变器的硬件工作。 逆变器应由我的 F28069M-LaunchPad 运行。 为了避免 IGBT 模块(B6桥接拓扑)发生击穿、我想在下降沿和下一个上升沿之间插入一个死区时间。 我 µs 死区时间为1.4 μ s、在我的90MHz MCU 上大约为126个时钟周期。
我在 E2E 论坛上发现了这篇文章、其中介绍了在 Simulink 的"死区单元"选项卡中设置这样一个死区时间所需的所有步骤:

https://e2e.ti.com/support/microcontrollers/c2000/f/171/p/152067/551099#551099

但是、我设置的所有内容都与本文中提到的内容相同、但我的示波器显示在一个开关的下降沿和另一个开关的上升沿之间没有插入死区。 µs、我们最好这样说:确实插入了1.4 μ s 的死区、但不仅上升沿被延迟、而且下降沿也被延迟。 (我发现这是因为在占空比为10%时、ePWM1A 信号一直处于低电平、而 ePWM1B 信号一直处于高电平。) 这不应该发生。 下降沿应立即发生、只应延迟上升沿。
您知道我在这里犯了什么错误吗? 我将在下面附上我的配置的一些屏幕截图。

此致、
Armin

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

    您是否也可以发布 Simulink 生成的代码? 一个建议是开始调试由 Simulink 生成的代码、并查找 C 代码和 Simulink 设置之间的不匹配情况。 谢谢!

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

    尊敬的 Armin:

    请注意您在本例中使用的 MATLAB 和 TI C2000支持包的版本。

    此致、

    Venkatesh Chilapur

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

    您好、Venkatesh、

    我使用的是 MATLAB 版本9.2.0.538062 (R2017a)和 TI C2000支持包版本17.1.2。 我已安装 CCSv6。

    此致、

    Armin

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

    您好、Chen、

    我附上了下面生成的代码(仅指死区单元设置的部分、如果我应该上传更多内容、请告诉我)。
    您在第一眼看到什么问题了吗? 我能否找到有关 MCU 技术参考手册(有关 ePWM 的一章) C 代码中提到的所有寄存器和设置的详细文档?

    此致、
    Armin

    /*
    *文件:test_end_ePWM_SCI.c
    *
    为 Simulink 模型'test_end_ePWM_SCI'生成的代码。
    *
    *型号版本 :1.145
    * Simulink Coder 版本 :8.12 (R2017a) 2017年2月16日
    *在以下日期生成 C/C++源代码:2017年11月14日14:20:57
    *
    目标选择:ERT.tlc
    *嵌入式硬件选择:德州仪器(TI)->C2000
    *代码生成目标:未指定
    *验证结果:不运行
    */
    
    #include "test_end_ePWM_SCI.h"
    
    
    
    *#include "tb_auto_test_test_sics"*(#tb_test_test_b_test_si/tbt)
    
    /*实时模型*/
    rt_model RTM_;
    rt_model *const RTM =&RTM_;
    static void rate _monotonic_scheduler (void);
    
    /*
    设置运行此基本步骤所需的子速率(基本速率始终运行)。
    *必须在调用模型步进函数之前调用此函数
    *以"记住"运行此基本步进所需的速率。
    事件的*缓冲允许重叠抢占。
    //
    void test_end_ePWM_SCI_SetEventsForThisBaseStep (boole_T * eventFlags)
    {
    //任务在其计数器为零时运行,通过 rtmStepTask 宏计算*/
    eventFlag[1]=((boole_T) rtmStepTask (RTM、1));
    }
    
    //
    *此函数更新该子速
    率任务的活动转换标志和交换速率标志。
    *该函数假定速率单调多任务调度程序。
    *必须以模型基准速率调用该函数
    、以便*生成的代码自行管理其所有子速率和速率
    *转换标志。
    */
    static void rate _monotonic_scheduler (void)
    {
    //计算在下一个基准时步骤中运行的子速率。 子酸
    盐*是基速率计数器的整数倍。 因此、子任务
    *计数器在达到其限值时复位(零表示运行)。
    */
    (RTM->Timing.taskCounters.TID[1])++;
    if ((RTM->Timing.taskCounters.TID[1])> 4){//*采样时间:[0.5s、0.0S]*/
    RTM->Timing.taskCounter.TID[1]= 0;
    }
    }//
    
    TID0的模型步骤函数*/
    void test_end_ePWM_SCI_step0 (void) /*采样时间:[0.1秒、0秒]*/
    {
    /*本地块 I/O 变量*/
    int16_T RTB_Sum;
    
    { /*采样时间:[0.1秒、0秒]*/
    rate_monotonicon_scheduler();
    }/*
    
    S-function (c28xsci_rx):' /SCI 接收'*/
    {
    int i;
    int errFlg = NOERROR;
    unsigned int recbuff [1];
    对于(I = 0;I < 1;I++)
    Recbuff [i]= 0;
    
    /*获取数据标题*/
    {
    unsigned int recHead;
    int cnt = 0;
    int i = 0;
    char * expHead ="S";
    while (I < 1){
    scia_rcv (&recHead、1、SHORTLOOP、1);
    if (recHead =ExpHead[i]){
    i++;
    } 否则{
    I = 0;
    }
    
    if (cnt++> 16){
    errFlg =超时;
    转至 RXERRA;
    }
    }
    
    
    /*获取数据标题的结束*/
    
    /*正在接收数据*/
    errFlg = scia_rcv (recbuff、2、LONGLOOP、2);
    if (errFlg != NOERROR)
    转至 RXERRA;
    
    /*获取数据尾*/
    {
    int i;
    字符 exp尾[1]="E";
    无符号整数反尾数[1];
    scia_rcv (recTail、1、LONGLOOP、1);
    对于(i = 0;i< 1;i++){
    if (expTail[i]!= recTail[i]){
    errFlg = DATAERR;
    转至 RXERRA;
    }
    }
    
    
    /*获取数据尾的结束*/
    memcpy (&rtb.SCIReceive、recbuff、1);
    RXERRA:
    if (errFlg){
    RTB.SCIReceive = 0;
    }
    }/*
    
    总和:' /Sum '包含:
    * constant:' /d_max'
    *增益:' /gain'
    */
    RTB_Sum = RTP.Gain_Gain * RTB.SCIReceive + RTP.d_max_value;
    
    // S 函数(c2802xpwm):' /ePWM'包含:
    *常量:' /T_SW // 2'
    */
    {
    EPwm1Regs.TBPRD =(uint16_T)(rtp.T_SW2_Value * 90000000 / 1 / 1);
    }
    
    /*-更新 ePWM1的 CMPA 值-*/
    {
    EPwm1Regs.CMPA.half.CMPA =(uint16_T)((uint32_T) EPwm1Regs.TBPRD *
    rtb.SCIReceive * 0.01);
    }
    
    /*--更新 ePWM1的 CMPB 值-*/
    {
    EPwm1Regs.CMPB =(uint16_T)((uint32_T) EPwm1Regs.TBPRD * RTB_SUM * 0.01);
    }
    }
    
    // TID1的模型步骤函数*
    / void test_end_ePWM_SCI_STEP1 (void) /*采样时间:[0.5s、0.0s]*/
    {
    /* S-function (c280xgpio_do):' /数字输出'包含:
    *常量:' /LED'
    */
    {
    GpioDataRegs.GPBTOGGL.bit.GPIO39 =(rtp.LED_Value!= 0);
    }
    //
    
    *模型初始化函数*
    / void test_end_ePWM_SCI_initialize (void)
    {
    //
    
    ////*注册码*////(
    void)初始化实时模型*(void *) memset (((void *) RTM、0、0、
    sizeof (rt_model));
    
    //块 I/O *(
    void) memset (((void *)&rTB)、0、
    sizeof (B);
    
    //开始 S 函数(c280xgpio_do):' /数字输出'包含:
    *常量:' /LED'
    */
    EALLOW;
    GpioCtrlRegs.GPBMUX1.ALL &= 0xFFFFFFF;
    GpioCtrlRegs.GPBDIR.ALL |= 0x80;
    EDIS;
    
    //开始 S 函数(c28xsci_Rx):' /SCI 接收'*/
    
    /*初始化 RTB.SCIReceive */
    {
    rtb.SCIReceive=(Int16_T) 0.0;
    }
    
    //开始 S 函数(c2802xpwm):' /ePWM'包含:
    *常量:' /T_SW // 2'
    */***
    
    初始化 ePWM1模块***/
    {
    /*--设置时基(TB)子模块-*/
    EPwm1Regs.TBPRD = 9000; //时基周期寄存器
    
    /*//时基控制寄存器
    EPwm1Regs.TBCTL.bit.CTRMODE = 2; //计数器模式
    EPwm1Regs.TBCTL.bit.SYNCOSEL = 3; //同步输出选择
    EPwm1Regs.TBCTL.bit.PRDLD = 0; //阴影选择
    EPwm1Regs.TBCTL.bit.PHSEN = 0; //相位负载使能
    EPwm1Regs.TBCTL.bit.PHSDIR = 0; //相位方向位
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; //高速 TBCLK 预分频器
    EPwm1Regs.TBCTL.bit.CLKDIV = 0; //时基时钟预分频器
    EPwm1Regs.TBCTL.bit.SWFSYNC = 0; //软件强制同步脉冲
    *
    EPwm1Regs.TBCTL.ALL =(EPwm1Regs.TBCTL.ALL &~0x3FFF)| 0x32;
    
    /*//时基相位寄存器
    EPwm1Regs.TBPHS.Halt.TBPHS = 0; //相位偏移寄存器
    *
    EPwm1Regs.TBPHS.ALL =(EPwm1Regs.TBPHS.ALL &~0xFFFFFF0000)| 0x0;
    
    //时基计数器寄存器
    EPwm1Regs.TBCTR = 0x0000; /*清除计数器*/
    
    /*--设置计数器比较(CC)子模块-*/
    /*//计数器比较控制寄存器
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;//比较 A 寄存器块运行模式
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;//比较 B 寄存器块运行模式
    EPwm1Regs.CMPCTL.bit.LOADAMODE = 2; //活动比较 A 加载
    EPwm1Regs.CMPCTL.bit.LOADBMODE = 2; //活动比较 B 加载
    *
    EPwm1Regs.CMPCTL.ALL =(EPwm1Regs.CMPCTL.ALL &~0x5F)| 0xA;
    EPwm1Regs.CMPA.half.CMPA = 4500;//计数器比较 A 寄存器
    EPwm1Regs.CMPB = 4500; //计数器比较 B 寄存器
    
    /*--设置动作限定符(AQ)子模块-*/
    EPwm1Regs.AQCTLA.ALL = 150; //输出 A 的操作限定器控制寄存器
    EPwm1Regs.AQCTLB.all = 150; //输出 B 的操作限定器控制寄存器
    
    /*//操作限定符软件强制寄存器
    EPwm1Regs.AQSFRC.bit.RLDSF = 0; //从阴影选项重新加载
    *
    EPwm1Regs.AQSFRC.ALL =(EPwm1Regs.AQSFRC.ALL &~0xC0)| 0x0;
    
    /*//操作限定符连续软件强制寄存器
    EPwm1Regs.AQCSFRC.bit.CSFA = 0; //输出 A 上的 Continuous Software Force
    EPwm1Regs.AQCSFRC.bit.CSFB = 0; //输出 B 上的持续软件力
    *
    EPwm1Regs.AQCSFRC.ALL =(EPwm1Regs.AQCSFRC.ALL &~0xF)| 0x0;
    
    /*--设置死区发生器(DB)子模块-*/
    /*//死区发生器控制寄存器
    EPwm1Regs.DBCTL.bit.OUT_MODE = 3; //死区输出模式控制
    EPwm1Regs.DBCTL.bit.IN_MODE = 2; //死区输入选择模式控制
    EPwm1Regs.DBCTL.bit.POLSEL = 2; //极性选择控制
    EPwm1Regs.DBCTL.bit.HALFCYCLE = 0; //半周期计时启用
    *
    EPwm1Regs.DBCTL.ALL =(EPwm1Regs.DBCTL.ALL &~0x803F)| 0x2B;
    EPwm1Regs.DBRED = 126; //死区发生器上升沿延迟计数寄存器
    EPwm1Regs.DBFED = 0; //死区发生器下降沿延迟计数寄存器
    
    /*--设置事件触发器(ET)子模块-*/
    /*//事件触发器选择和预分频寄存器
    EPwm1Regs.ETSEL.bit.SOCAEN = 1; //转换开始 A 使能
    EPwm1Regs.ETSEL.bit.SOCASEL = 3; //转换开始选择
    EPwm1Regs.ETPS.bit.SOCAPRD = 1; // EPWM1SOCA 周期选择
    
    EPwm1Regs.ETSEL.bit.SOCBEN = 0; //转换 B 开始使能
    
    EPwm1Regs.ETSEL.bit.SOCBSEL = 1; //转换 B 选择开始
    EPwm1Regs.ETPS.bit.SOCBPRD = 1; // EPWM1SOCB 周期选择
    EPwm1Regs.ETSEL.bit.INTEN = 0; // EPWM1INTn 使能
    EPwm1Regs.ETSEL.bit.INTSEL = 1; // EPWM1INTn 选择
    
    EPwm1Regs.ETPS.bit.INTPRD = 1; // EPWM1INTn 周期选择
    *
    EPwm1Regs.ETSEL.ALL =(EPwm1Regs.ETSEL.ALL &~0xFF0F)| 0x1B01;
    EPwm1Regs.ETPS.ALL =(EPwm1Regs.ETPS.ALL &~0x3303)| 0x1101;
    
    /*-设置 PWM-Chopper (PC)子模块-*/
    /*// PWM 斩波器控制寄存器
    EPwm1Regs.PCCTL.bit.CHPEN = 0; // PWM 斩波使能
    EPwm1Regs.PCCTL.bit.CHPFREQ = 0; //斩波时钟频率
    EPwm1Regs.PCCTL.bit.OSHTWTH = 0; //单次脉冲宽度
    EPwm1Regs.PCCTL.bit.CHPDUTY = 0; //斩波时钟占空比
    *
    EPwm1Regs.PCCTL.ALL =(EPwm1Regs.PCCTL.ALL &~0x7FF)| 0x0;
    
    /*--设置跳闸区域(TZ)子模块-*/
    EALLOW;
    EPwm1Regs.TZSEL.ALL = 0; //跳匣区域选择寄存器
    
    /*//跳匣区域控制寄存器
    EPwm1Regs.TZCTL.bit.TZA = 3; // EPWM1A 上的 TZ1至 TZ6跳闸动作
    EPwm1Regs.TZCTL.bit.TSB = 3; // EPWM1B 上的 TZ1至 TZ6跳闸动作
    EPwm1Regs.TZCTL.bit.DCAEVT1 = 3; // DCAEVT1上的 EPWM1A 动作
    EPwm1Regs.TZCTL.bit.DCAEVT2 = 3; // DCAEVT2上的 EPWM1A 动作
    EPwm1Regs.TZCTL.bit.DCBEVT1 = 3; //对 DCBEVT1执行 EPWM1B 操作
    EPwm1Regs.TZCTL.bit.DCBEVT2 = 3; //对 DCBEVT2执行 EPWM1B 操作
    *
    EPwm1Regs.TZCTL.ALL =(EPwm1Regs.TZCTL.ALL &~0xFFF)| 0xFFF;
    
    /*//跳匣区域启用中断寄存器
    EPwm1Regs.TZEINT.bit.OST = 0; //跳匣区域一次性内部启用
    EPwm1Regs.TZEINT.bit.CBC = 0; //跳匣区域逐周期内部启用
    EPwm1Regs.TZEINT.BIT.DCAEVT1 = 0; //数字比较 A 事件1内部启用
    EPwm1Regs.TZEINT.BIT.DCAEVT2 = 0; //数字比较 A 事件2内部启用
    EPwm1Regs.TZEINT.BIT.DCBEVT1 = 0; //数字比较 B 事件1内部启用
    EPwm1Regs.TZEINT.BIT.DCBEVT2 = 0; //数字比较 B 事件2内部启用
    *
    EPwm1Regs.TZEINT.ALL =(EPwm1Regs.TZEINT.ALL &~0x7E)| 0x0;
    
    /*//数字比较 A 控制寄存器
    EPwm1Regs.DCACTL.bit.EVT1SYNCE = 0; // DCAEVT1同步使能
    EPwm1Regs.DCACTL.bit.EVT1SOCE = 0; // DCAEVT1 SOC 启用
    EPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL = 0; // DCAEVT1强制同步信号
    EPwm1Regs.DCACTL.bit.EVT1SRCSEL = 0; // DCAEVT1源信号
    EPwm1Regs.DCACTL.bit.EVT2FRCSYNCSEL = 0; // DCAEVT2强制同步信号
    EPwm1Regs.DCACTL.bit.EVT2SRCSEL = 0; // DCAEVT2源信号
    *
    EPwm1Regs.DCACTL.ALL =(EPwm1Regs.DCACTL.ALL &~0x30F)| 0x0;
    
    /*//数字比较 B 控制寄存器
    EPwm1Regs.DCBCTL.bit.EVT1SYNCE = 0; // DCBEVT1同步使能
    EPwm1Regs.DCBCTL.bit.EVT1SOCE = 0; // DCBEVT1 SOC 启用
    EPwm1Regs.DCBCTL.bit.EVT1FRCSYNCSEL = 0; // DCBEVT1强制同步信号
    EPwm1Regs.DCBCTL.bit.EVT1SRCSEL = 0; // DCBEVT1源信号
    EPwm1Regs.DCBCTL.bit.EVT2FRCSYNCSEL = 0; // DCBEVT2强制同步信号
    EPwm1Regs.DCBCTL.bit.EVT2SRCSEL = 0; // DCBEVT2源信号
    *
    EPwm1Regs.DCBCTL.ALL =(EPwm1Regs.DCBCTL.ALL &~0x30F)| 0x0;
    
    /*//数字比较跳闸选择寄存器
    EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = 0; //数字比较 A 高 COMP 输入选择
    
    EPwm1Regs.DCTRIPSEL.bit.DCALCOMPSEL = 1; //数字比较 A 低 COMP 输入选择
    EPwm1Regs.DCTRIPSEL.bit.DCBHCOMPSEL = 0; //数字比较 B 高 COMP 输入选择
    EPwm1Regs.DCTRIPSEL.bit.DCBLCOMPSEL = 1; //数字比较 B 低 COMP 输入选择
    *
    EPwm1Regs.DCTRIPSEL.ALL =(EPwm1Regs.DCTRIPSEL.ALL &~ 0xFFFF)| 0x1010;
    
    /*//跳匣区域数字比较器选择寄存器
    EPwm1Regs.TZDCSEL.bit.DCAEVT1 = 0; //数字比较输出 A 事件1
    EPwm1Regs.TZDCSEL.bit.DCAEVT2 = 0; //数字比较输出 A 事件2
    EPwm1Regs.TZDCSEL.bit.DCBEVT1 = 0; //数字比较输出 B 事件1
    EPwm1Regs.TZDCSEL.bit.DCBEVT2 = 0; //数字比较输出 B 事件2
    *
    EPwm1Regs.TZDCSEL.ALL =(EPwm1Regs.TZDCSEL.ALL &~0xFFF)| 0x0;
    
    /*//数字比较滤波器控制寄存器
    EPwm1Regs.DCFCTL.bit.Blanke = 0; //消隐启用/禁用
    EPwm1Regs.DCFCTL.bit.PULSESEL = 1; //针对消隐和捕捉对齐的脉冲选择
    EPwm1Regs.DCFCTL.bit.BLANKINV = 0; //消隐窗口反转
    EPwm1Regs.DCFCTL.bit.SRCEL = 0; //过滤器块信号源选择
    *
    EPwm1Regs.DCFCTL.ALL =(EPwm1Regs.DCFCTL.ALL &~0x3F)| 0x10;
    EPwm1Regs.DCFOFFSET = 0; //数字比较滤波器偏移寄存器
    EPwm1Regs.DCFWINDOW=0; //数字比较滤波器窗口寄存器
    
    /*//数字比较捕捉控制寄存器
    EPwm1Regs.DCCAPCTL.bit.Cape = 0; //计数器捕获启用
    *
    EPwm1Regs.DCCAPCTL.ALL =(EPwm1Regs.DCCAPCTL.ALL &~0x1)| 0x0;
    
    /*// HRPWM 配置寄存器
    EPwm1Regs.HRCNFG.bit.SWAPAB = 0; //交换 EPWMA 和 EPWMB 输出位
    EPwm1Regs.HRCNFG.bit.SELOUTB = 1; // EPWMB 输出选择位
    *
    EPwm1Regs.HRCNFG.ALL =(EPwm1Regs.HRCNFG.ALL &~0xA0)| 0x20;
    EDIS;
    }
    }/*
    
    
    生成的代码的文件尾部。
    *
    *[EOF]
    */
    

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

    请取消选中图3中的选项"ePWMxA 的反转版本"。
    图4中的"高电平有效互补"选项无论如何都会反转。
    请告诉我们这是否适合您。

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

    您好、Venkatesh、

    非常感谢! 这就是它不起作用的原因。 我也不知道死区单元也会使输入信号反相。
    现在一切都按照我的要求工作。 如果将来有人遇到同样的问题、我将在这篇文章中附加我的工作设置的屏幕截图。

    此致、
    Armin