介绍

The enhanced pulse width modulator (ePWM) peripheral is a key element in controlling many of the power
electronic systems found in both commercial and industrial equipment. These systems include digital
motor control, switch mode power supply control, uninterruptible power supplies (UPS), and other forms of
power conversion.
增强型脉宽调制器(ePWM)外设是控制许多商业和工业设备中电力电子系统的关键元素,这些系统一般包括数字电机控制,开关电源控制,不间断电源控制和其他形式的功率转换系统

由上图可见,c2000的epwm被分为了几个子模块,包括时基模块,比较模块,波形发生器模块等

GPIO配置

首先要配置epwm模块工作时需要使用到的引脚,把输出引脚配成推挽就行

void GPIO_setPadConfig(uint32_t pin, uint32_t pinType)

pinType的参数:

  • GPIO_PIN_TYPE_STD specifies a push-pull output or a floating input
  • GPIO_PIN_TYPE_PULLUP specifies the pull-up is enabled for an input
  • GPIO_PIN_TYPE_OD specifies an open-drain output pin
  • GPIO_PIN_TYPE_INVERT specifies inverted polarity on an input

把引脚分配给EPWM

void GPIO_setPinConfig(uint32_t pinConfig)

pinConfig的宏定义可以在pin_map.h里找到,不同的芯片的driverlib可能会有一点区别,比如28379是GPIO_0_EPWM1A,280049就变成了GPIO_0_EPWM1_A我也不知道为什么非要整个不一样的

EPWM点灯流程

首先禁用计数器的时钟信号

SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

配置时基(Time-Base)

时基模块框图

设置分频系数(笔者这里设置了不分频,可以根据需求改)

EPWM_setClockPrescaler(EPWM1_BASE,EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);

This function sets the pre scaler(divider)value for the time base clock counter and the high speed time base clock counter. Valid values for pre-scaler and highSpeedPrescaler are EPWM_CLOCK_DIVIDER_X, where X is 1,2,4,8,16, 32,64 or 128. The actual numerical values for these macros represent values 0,1…7. The equation for the output clock is: TBCLK = EPWMCLK/(highSpeedPrescaler * pre-scaler)

设置计数方向

EPWM_setTimeBaseCounterMode(EPWM1_BASE,EPWM_COUNTER_MODE_UP);

设置重装载值装载方式

EPWM_setPeriodLoadMode(EPWM1_BASE,EPWM_PERIOD_SHADOW_LOAD);
  • EPWM_PERIOD_SHADOW_LOAD 使用影子寄存器
  • EPWM_PERIOD_DIRECT_LOAD 直接访问

设置计数器重装载事件

EPWM_selectPeriodLoadEvent(EPWM1_BASE, EPWM_SHADOW_LOAD_MODE_COUNTER_ZERO);

设置重装载值

EPWM_setTimeBasePeriod(EPWM1_BASE,10000);

配置比较器(Counter Compare)

设置比较值的装载事件

EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);

设置比较值

EPWM_setCounterCompareValue(EPWM1_BASE,EPWM_COUNTER_COMPARE_A,5000);

配置波形发生器(Action Qualifier)

这玩意儿跟st的hrtim里的set/reset source 差不多,就是可以对每个事件设置输出置高、置低、翻转或者无动作

void EPWM_setActionQualifierAction(uint32_t base, EPWM_ActionQualifierOutputModule epwmOutput, EPWM_ActionQualifierOutput output, EPWM_ActionQualifierOutputEvent event)
    
void EPWM_setActionQualifierActionComplete(uint32_t base, EPWM_ActionQualifierOutputModule epwmOutput, uint16_t action)

Driverlib提供了两种API,上面这种可以单独设置某个事件,下面的是一次设置所有事件

举个例子

EPWM_setActionQualifierActionComplete(EPWM1_BASE,EPWM_AQ_OUTPUT_A,EPWM_AQ_OUTPUT_HIGH_ZERO|EPWM_AQ_OUTPUT_LOW_UP_CMPA);
////////////////////////////////////////////////////////////////////////////////////////////
EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);

两种写法效果是一样的

最后重新打开计数器的时钟

SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

完成以上配置之后epwm模块就能输出基本的pwm波形了

高精度PWM(High Resolution Pulse Width Modulation)

笔者没太看懂TI这玩意儿是啥原理,手册上就说使用了一种叫MEP技术可以在一个时钟周期内插入很多个脉冲,根据数据手册的说法F28379的MEP步长一般是150ps,并且会随着温度浮动

参考手册上给出了详细的配置流程,笔者依葫芦画瓢做了一遍

时基单元配置

首先配置重装载值

void HRPWM_setTimeBasePeriod(uint32_t base, uint32_t periodCount)

由于使用了高精度模式,这里的重装载值是q16.8的定点数,看函数定义可以发现这个函数是把periodcount的低八位(也就是小数部分)给了TBPRDHR,高十六位给了TBPRD

比较值也是同理

void HRPWM_setCounterCompareValue(uint32_t base, HRPWM_CounterCompareModule compModule, uint32_t compCount)

配置计数模式和装载模式,手册说高精度模式只支持向上计数和中心对齐计数,而且必须使用影子寄存器

void HRPWM_setTimeBaseCounterMode(uint32_t base, EPWM_TimeBaseCountMode counterMode)
void HRPWM_setPeriodLoadMode(uint32_t base, EPWM_PeriodLoadMode loadMode)

设置比较值的装载事件,注意这玩意儿只影响CMPAHR

static inline void HRPWM_setCounterCompareShadowLoadEvent(uint32_t base, HRPWM_Channel channel,HRPWM_LoadMode loadEvent)

剩下的按照一般epwm的方式配置就行,其实除了一些HRPWM特有的设置外其他API都是和EPWM一样的

MEP比例因子自动转换配置

开自动转换

void HRPWM_enableAutoConversion(uint32_t base)

不开自动转换的话MEP的比例因子就要自己算,而且由于MEP的步长会随着温度缓慢漂移,比例因子也是在缓慢发生变化的,所以还是开自动转换比较好

使用自动转换还有一些额外的东西需要配置:

  1. 包含必要的头文件

    #include "F28x7x_Device.h" // F28x7x Headerfile
    #include "F28x7x_EPwm_defines.h" // init defines
    #include "SFO_V8.h" // SFO lib functions (needed for HRPWM
  2. 定义变量(注意一定要定义成全局的)

    int MEP_ScaleFactor = 0; //scale factor value
    volatile struct EPWM_REGS *ePWM[] = {0, &EPwm1Regs, &EPwm2Regs, &EPwm3Regs,
    &EPwm4Regs};

    epwm数组里放芯片各个EPWM模块的基址

  3. 调用SFO()对比例因子进行初始化

    while (SFO() == 0) {} // MEP_ScaleFactor calculated by MEP Cal Module
  4. 在后面的程序里时不时调用一下SFO()来更新比例因子(可以放在大循环里)

手册里其实也给了比例因子的计算方法

MEP控制配置

设置MEP控制的边沿,手册让同时控制上升沿和下降沿,我也不知道为啥反正跟着做就对了

HRPWM_setMEPEdgeSelect(EPWM1_BASE,HRPWM_CHANNEL_A,HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);

使能高精度控制

HRPWM_enablePeriodControl(EPWM1_BASE);

发送一个软件同步脉冲

EPWM_forceSyncPulse(EPWM1_BASE);

到这HRPWM就配置好了

错误信号控制模块(Trip Zone)

c2000的epwm提供了错误信号控制模块,可以从外部引脚或者软件获取错误发生的信号并按照设定在硬件层面上进行保护,还可以产生相应的中断信号方便CPU进行处理,对于电力电子这种经常要加各种保护的应用来说比较有用

实际上笔者一开始是因为在c2000上找不到像st那样的IDLE电平设置才用这个来实现类似的功能

保护类型

错误信号控制模块提供了两种保护方式,一种叫CBC(Cycle-by-Cycle),顾名思义就是在每个PWM周期都重置保护状态,比较适合用于过流保护之类的场景,另一种叫OSHT(One-Shot),这种保护一旦被触发就会一直持续下去直到收到解除的信号

保护动作

c2000可以通过下面这个函数设置保护事件和对应的动作,保护动作有高阻态,拉高输出,拉低输出或者无动作四种

void EPWM_setTripZoneAction(uint32_t base, EPWM_TripZoneEvent tzEvent, EPWM_TripZoneAction tzAction)
  • tzEvent

    • EPWM_TZ_ACTION_EVENT_DCBEVT2 - DCBEVT2 (Digital Compare B event 2)
    • EPWM_TZ_ACTION_EVENT_DCBEVT1 - DCBEVT1 (Digital Compare B event 1)
    • EPWM_TZ_ACTION_EVENT_DCAEVT2 - DCAEVT2 (Digital Compare A event 2)
    • EPWM_TZ_ACTION_EVENT_DCAEVT1 - DCAEVT1 (Digital Compare A event 1)
    • EPWM_TZ_ACTION_EVENT_TZB - TZ1 - TZ6, DCBEVT2, DCBEVT1
    • EPWM_TZ_ACTION_EVENT_TZA - TZ1 - TZ6, DCAEVT2, DCAEVT1
  • tzAction

    • EPWM_TZ_ACTION_HIGH_Z - high impedance output
    • EPWM_TZ_ACTION_HIGH - high output
    • EPWM_TZ_ACTION_LOW - low low
    • EPWM_TZ_ACTION_DISABLE - disable action

软件触发保护

void EPWM_forceTripZoneEvent(uint32_t base, uint16_t tzForceEvent)

解除保护状态

void EPWM_clearTripZoneFlag(uint32_t base, uint16_t tzFlags)

死区发生器(Dead Band)配置

死区也是电力电子经常用到的功能,下图是DB模块的框图,该模块可以分别配置上升沿和下降沿的死区时间和输出极性等

从左到右每一部分在Driverlib里面都有对应的函数进行操作

设置RED和FED的信号源

void EPWM_setRisingEdgeDeadBandDelayInput(uint32_t base, uint16_t input)
void EPWM_setFallingEdgeDeadBandDelayInput(uint32_t base, uint16_t input)
  • EPWM_DB_INPUT_EPWMA - Input signal is ePWMA(Valid for both Falling Edge and Rising Edge)
  • EPWM_DB_INPUT_EPWMB - Input signal is ePWMB(Valid for both Falling Edge and Rising Edge)
  • EPWM_DB_INPUT_DB_RED - Input signal is the output of Rising Edge delay. (Valid only for Falling Edge delay)

设置RED和FED的延迟时间

void EPWM_setRisingEdgeDelayCount(uint32_t base, uint16_t redCount)
void EPWM_setFallingEdgeDelayCount(uint32_t base, uint16_t fedCount)    

设置输出极性

void EPWM_setDeadBandDelayPolarity(uint32_t base, EPWM_DeadBandDelayMode delayMode, EPWM_DeadBandPolarity polarity)
  • delayMode

    • EPWM_DB_RED - Rising Edge delay
    • EPWM_DB_FED - Falling Edge delay
  • polarity

    • EPWM_DB_POLARITY_ACTIVE_HIGH - polarity is not inverted.
    • EPWM_DB_POLARITY_ACTIVE_LOW - polarity is inverted.

设置是否使用死区生成

void EPWM_setDeadBandDelayMode(uint32_t base, EPWM_DeadBandDelayMode delayMode, bool enableDelayMode)

设置输出交换(我不知道这功能应用场景是啥)

void EPWM_setDeadBandOutputSwapMode(uint32_t base, EPWM_DeadBandOutput output, bool enableSwapMode)
  • output

    • EPWM_DB_OUTPUT_A - ePWM output A
    • EPWM_DB_OUTPUT_B - ePWM output B
  • enableSwapMode

    • true - the output is swapped
    • false - the output and the signal path are the same.

手册上给了几种配置对应的输出波形,可以结合前面的框图理解

如何进行时基间的同步

电力电子经常涉及多个定时器之间的同步,用过stm32的应该知道它的定时器可以通过设置触发事件来实现同步,c2000的epwm也有类似的功能,但是和stm32的玩法不太一样,c2000的时基单元的同步信号是一个串一个的,可以看底下这个图

考虑同步的时候可以把每个epwm模块简化成下面这样

要进行同步主要要做两步,第一步是把前面的模块的同步输出信号打开,第二步是把要进行同步的模块的移相输入打开

void EPWM_setSyncOutPulseMode(uint32_t base, EPWM_SyncOutPulseMode mode)
void EPWM_enablePhaseShiftLoad(uint32_t base)    

这样两个epwm模块就可以同步了

总结

本文介绍了c2000 epwm模块的基本使用方法,其实还有很多功能笔者暂时没有用上,日后用上了再回来补充,如果文章有什么错误也欢迎批评指正

参考链接

F28379D Driverlib API手册

F28379数据手册

F28379技术参考手册

最后修改:2023 年 08 月 13 日
V我五十