C6748_PWM

来源:互联网 发布:python win32ui 编辑:程序博客网 时间:2024/06/13 01:01
  1. 主函数执行流程

此程序的作用是实现eHRPWM(高精度脉冲宽度调制器)输出功能。OMAPL138/TMS320C6748共有两个eHRPWM模块,此处测试模块1的EPWM1_A引脚。主函数执行流程如下:

主函数如下:

intmain(void)

{

    //外设使能配置

    PSCInit();

     

    // GPIO管脚复用配置

    GPIOBankPinMuxSet();

 

    // DSP中断初始化

    InterruptInit();

 

    // PWM中断初始化

    PWMInterruptInit();

 

    //产生波形

    PWM1ABasic(10000,50);

 

    //斩波实验

//  ChopperWaveform();

 

    //主循环

    for(;;)

    {

 

    }

}

  1. 外设使能配置

函数首先使能外设,这里是eHRPWM模块1,外设使能配置函数PSCInit如下:

voidPSCInit(void)

{

    //使能 EHRPWM模块

    //对相应外设模块的使能也可以在 BootLoader中完成

PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_EHRPWM, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

}

函数在PSC中使能HW_PSC_EHRPWM(#17)模块,该模块的Power Domain是ALWAYS_ON域(POWER DOMAIN 0),PSCModuleControl细节可参考这里:

C6748_UART_EDMA

  1. GPIO管脚复用配置

将EHRPWM1模块所在的引脚的功能(function)配置为EHRPWM1功能,GPIO管脚复用配置函数GPIOBankPinMuxSet如下:

voidGPIOBankPinMuxSet(void)

{

    EHRPWM1PinMuxSetup();

}

EHRPWM1PinMuxSetup函数在demoPlatform工程下的EHRPWM.c文件中,函数如下:

voidEHRPWM1PinMuxSetup(void)

{

 

// EPWM1A

HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(5))=

         (HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(5))& (~(SYSCFG_PINMUX5_PINMUX5_3_0)))|

         (PINMUX5_EPWM1A_ENABLE);

 

// EPWM1B

HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(5))=

         (HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(5))& (~(SYSCFG_PINMUX5_PINMUX5_7_4)))|

         (PINMUX5_EPWM1B_ENABLE);

 

// EPWM1TZ[0]

HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(2))=

         (HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(2))& (~(SYSCFG_PINMUX2_PINMUX2_3_0)))|

         (PINMUX2_EPWM1TZ0_ENABLE);

 

// EPWMSYNCO

HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(3))=

         (HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(3))& (~(SYSCFG_PINMUX3_PINMUX3_15_12)))|

         (PINMUX3_EPWMSYNCO_ENABLE);

 

// EPWMSYNCI

HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(3))=

         (HWREG(SOC_SYSCFG_0_REGS+SYSCFG0_PINMUX(3))& (~(SYSCFG_PINMUX3_PINMUX3_11_8)))|

         (PINMUX3_EPWMSYNCI_ENABLE);

 

//使能 PWM时钟

HWREG(SOC_SYSCFG_0_REGS+ SYSCFG0_CFGCHIP1) |= SYSCFG_CFGCHIP1_TBCLKSYNC;

}

函数将EPWM1模块的相关引脚配置为EPWM1A、EPWM1B、EPWM1TZ[0]、EPWMSYNCO、EPWMSYNCI功能引脚,然后设置CFGCHIP1(Chip Configuration 1 Register)寄存器的TBCLKSYNC位,将所有被使能的eHRPWM模块同步到时基时钟(time base clock,TBCLK),使能PWM时钟。

(指南P228)

(指南P222)

(指南P224)

(CFGCHIP1,指南P266)

  1. DSP中断初始化

    DSP中断初始化函数InterruptInit如下:

voidInterruptInit(void)

{

    //初始化 DSP中断控制器

    IntDSPINTCInit();

 

    //使能 DSP全局中断

    IntGlobalEnable();

}

函数细节参考这里

C6748_SPI_FLASH

  1. PWM中断初始化

    PWM中断初始化函数PWMInterruptInit如下:

voidPWMInterruptInit(void)

{

    //注册中断服务函数

    IntRegister(C674X_MASK_INT4, PWMEventIsr);

    IntRegister(C674X_MASK_INT5, PWMTZIsr);

 

    //映射中断到 DSP可屏蔽中断

    IntEventMap(C674X_MASK_INT4, SYS_INT_EHRPWM1);

    IntEventMap(C674X_MASK_INT5, SYS_INT_EHRPWM1TZ);

 

    //使能 DSP可屏蔽中断

    IntEnable(C674X_MASK_INT4);

    IntEnable(C674X_MASK_INT5);

}

函数将CPU可屏蔽中断C674X_MASK_INT4C674X_MASK_INT5的中断服务函数注册为PWMEventIsrPWMTZIsr。然后将中断事件SYS_INT_EHRPWM1#18PWM1中断)和SYS_INT_EHRPWM1TZ#23PWM1错误处理中断)分别映射到CPU中断INT4INT5,最后使能INT4INT5。关于IntRegisterIntEventMapIntEnable等函数可参考这里。

C6748_EDMA_GPIO_中断学习笔记

(手册P93)

6.产生波形

产生波形函数PWM1ABasic (10000,50)如下,其中第一个参数10000表示产生的PWM波的频率为10000Hz10KHz),第二个参数50表示波形占空比为50%

voidPWM1ABasic(unsignedint pwm_clk,unsignedshort duty_ratio)

{

//时间基准配置

//时钟配置

EHRPWMTimebaseClkConfig(SOC_EHRPWM_1_REGS, SOC_EHRPWM_1_MODULE_FREQ/CLOCK_DIV_VAL , SOC_EHRPWM_1_MODULE_FREQ);

 

//配置周期

EHRPWMPWMOpFreqSet(SOC_EHRPWM_1_REGS, SOC_EHRPWM_1_MODULE_FREQ/CLOCK_DIV_VAL,

         pwm_clk, EHRPWM_COUNT_UP, EHRPWM_SHADOW_WRITE_DISABLE);

 

//禁用输入同步信

EHRPWMTimebaseSyncDisable(SOC_EHRPWM_1_REGS);

 

//禁用输出同步信号

EHRPWMSyncOutModeSet(SOC_EHRPWM_1_REGS, EHRPWM_SYNCOUT_DISABLE);

 

//仿真(DEBUG)模式行为配置

EHRPWMTBEmulationModeSet(SOC_EHRPWM_1_REGS, EHRPWM_STOP_AFTER_NEXT_TB_INCREMENT);

 

//配置计数比较器子模块

//加载比较器 A

EHRPWMLoadCMPA(SOC_EHRPWM_1_REGS, (SOC_EHRPWM_1_MODULE_FREQ/CLOCK_DIV_VAL/pwm_clk)*duty_ratio/100, EHRPWM_SHADOW_WRITE_DISABLE,

         EHRPWM_COMPA_NO_LOAD, EHRPWM_CMPCTL_OVERWR_SH_FL);

 

//加载比较器 B

EHRPWMLoadCMPB(SOC_EHRPWM_1_REGS,0, EHRPWM_SHADOW_WRITE_DISABLE,

         EHRPWM_COMPB_NO_LOAD, EHRPWM_CMPCTL_OVERWR_SH_FL);

 

//功能限定配置(输出引脚触发方式设定)

//时间基准计数等于有效计数比较寄存器 A/B值时EPWM1_A翻转,波形由EPWM1_A输出

EHRPWMConfigureAQActionOnA(SOC_EHRPWM_1_REGS, EHRPWM_AQCTLA_ZRO_DONOTHING, EHRPWM_AQCTLA_PRD_DONOTHING,

        EHRPWM_AQCTLA_CAU_EPWMXATOGGLE, EHRPWM_AQCTLA_CAD_DONOTHING, EHRPWM_AQCTLA_CBU_EPWMXATOGGLE,

        EHRPWM_AQCTLA_CBD_DONOTHING, EHRPWM_AQSFRC_ACTSFA_DONOTHING);

 

//禁用(旁路,信号直接输出到斩波子模块)死区模块

EHRPWMDBOutput(SOC_EHRPWM_1_REGS, EHRPWM_DBCTL_OUT_MODE_BYPASS);

 

//禁用斩波子模块

EHRPWMChopperDisable(SOC_EHRPWM_1_REGS);

 

//禁用错误控制事件

EHRPWMTZTripEventDisable(SOC_EHRPWM_1_REGS, EHRPWM_TZ_ONESHOT);

EHRPWMTZTripEventDisable(SOC_EHRPWM_1_REGS, EHRPWM_TZ_CYCLEBYCYCLE);

 

//事件触发配置

//每三次事件发生产生中断

EHRPWMETIntPrescale(SOC_EHRPWM_1_REGS, EHRPWM_ETPS_INTPRD_THIRDEVENT);

//时间基准计数等于有效计数比较寄存器 B产生事件

EHRPWMETIntSourceSelect(SOC_EHRPWM_1_REGS, EHRPWM_ETSEL_INTSEL_TBCTREQUCMPBINC);

//使能中断

EHRPWMETIntEnable(SOC_EHRPWM_1_REGS);

 

//禁用高精度子模块

EHRPWMHRDisable(SOC_EHRPWM_1_REGS);

}

6.1 时间基准配置/时钟配置

要输出PWM波,首先要配置时间基准,EHRPWMTimebaseClkConfig函数在Drivers工程下的ehrpwm.c文件中,API如下:

voidEHRPWMTimebaseClkConfig(unsignedint baseAddr,

unsignedint tbClk,

unsignedint moduleClk)

 

{

unsignedint clkDiv= moduleClk/tbClk;

unsignedint hspClkDiv;

unsignedint lspClkDiv, lspClkDivSetting=0;

 

if(clkDiv> EHRPWM_TBCTL_HSPCLKDIV_14)

{

hspClkDiv= EHRPWM_TBCTL_HSPCLKDIV_DIVBY14;/* reg setting */

lspClkDiv= clkDiv/EHRPWM_TBCTL_HSPCLKDIV_14;/* divider */

/* reg setting */

while(lspClkDiv>1)

{

lspClkDiv= lspClkDiv >>1;

lspClkDivSetting++;

}

}

else

{

hspClkDiv= clkDiv/2;/* reg setting */

/* divide by 1 */

lspClkDivSetting= EHRPWM_TBCTL_HSPCLKDIV_DIVBY1;

}

 

HWREGH(baseAddr+ EHRPWM_TBCTL) = (HWREGH(baseAddr+ EHRPWM_TBCTL) &

(~EHRPWM_TBCTL_CLKDIV))| ((lspClkDivSetting <<

EHRPWM_TBCTL_CLKDIV_SHIFT)& EHRPWM_TBCTL_CLKDIV);

 

HWREGH(baseAddr+ EHRPWM_TBCTL) = (HWREGH(baseAddr+ EHRPWM_TBCTL) &

(~EHRPWM_TBCTL_HSPCLKDIV))| ((hspClkDiv <<

EHRPWM_TBCTL_HSPCLKDIV_SHIFT)& EHRPWM_TBCTL_HSPCLKDIV);

}

该函数配置时基模块(Time base module)的时钟分频器(clock divider),baseAddr是PWM模块寄存器组的基地址,tbClk为要产生的时基时钟,moduleClk是输入到PWM模块的时钟(sysclk2)。时基时钟TBCLK(Time-base Clock)计算公式为:TBCLK = SYSCLKOUT/(HSPCLKDIV × CLKDIV)。HSPCLKDIV和CLKDIV是TBCTL寄存器的位,则时钟分频值clkdiv=SYSCLKOUT/TBCLK=HSPCLKDIV x CLKDIV。

函数先计算时钟分频值clkdiv,如果CLKDIV大于HSPCLKDIV所能设置的最大分频值14(HSPCLKDIV=7h)时,则还需要计算TBCTL的CLKDIV部分。否则,HSPCLKDIV分频值就是clkdiv,CLKDIV分频值为1。这里设置tbclk为1MHz,eHRPWM1模块的输入时钟为228MHz(sysclk/2)。

(指南P465)

(指南P131)

6.2 配置周期

配置周期函数EHRPWMPWMOpFreqSet如下:

voidEHRPWMPWMOpFreqSet(unsignedint baseAddr,

unsignedint tbClk,

unsignedint pwmFreq,

unsignedint counterDir,

bool enableShadowWrite)

{

unsignedint tbPeriodCount= tbClk/pwmFreq;

 

HWREGH(baseAddr+ EHRPWM_TBCTL) = (HWREGH(baseAddr+ EHRPWM_TBCTL) &

(~EHRPWM_PRD_LOAD_SHADOW_MASK))| ((enableShadowWrite <<

EHRPWM_TBCTL_PRDLD_SHIFT)& EHRPWM_PRD_LOAD_SHADOW_MASK);

 

HWREGH(baseAddr+ EHRPWM_TBCTL) = (HWREGH(baseAddr+ EHRPWM_TBCTL) &

(~EHRPWM_COUNTER_MODE_MASK))| ((counterDir <<

EHRPWM_TBCTL_CTRMODE_SHIFT)& EHRPWM_COUNTER_MODE_MASK);

 

if(EHRPWM_COUNT_UP_DOWN== counterDir)

{

HWREGH(baseAddr+ EHRPWM_TBPRD) = (unsignedshort)tbPeriodCount/2;

}

else

{

HWREGH(baseAddr+ EHRPWM_TBPRD) = (unsignedshort)tbPeriodCount;

}

 

}

    该函数配置输出的PWM频率/周期。周期计数器决定了最后输出波形的周期。对给定的周期值,在UP 和 DOWN模式下,所装载的周期值就是给定的周期值,在UP_DOWN模式下,所装载的周期值是给定的周期值的一半。pwmFreq是PWM输出波形的频率,如果计数器的方向是up-down,该值必须为输出频率的一半,这样最终输出的信号频率才能等于输出频率。CounterDir是计数器的计数方向(up,down,up-down),enableShadowWrite指明是否使能写往周期寄存器的影子寄存器。

(指南P338)

    函数先是计算周期计数值tbPeriodCount,然后设置TBCTL的PRDLD位确定周期寄存器TBPRD的值是否从Shadow寄存器中加载;设置TBCTL的CTRMODE位,确定计数器模式,是向上计数还是向下计数还是上下计数。最后根据计数方向,确定存入周期寄存器TBPRD的值tbPeriodCount是否要减半(这里设置up和down计数模式的tbPeriodCount好像少减了1?)。这里程序设置TBCTL[CTRMODE]位为0h,即time-base计数器计数模式为Up-count mode。设置TBCTL[PRDLD]位为1,即直接加载TBPRD而不使用影子寄存器。设置TBPRD为100(1MHz/10KHz=tbclkFREQ/pwmclkFREQ),即PWM波频率为10KHz。

(指南P388)

6.3 禁用输入同步信号

    EHRPWMTimebaseSyncDisable函数设置TBCTL的PHSEN位(counter Register Load From Phase Register Enable)为0,禁用EHRPWM1的输入同步信号,即使EPWM1SYNCI引脚有同步信号输入,EPWM1也不会把相位寄存器TBPHS(TB phase register)的值装入到计数器TBCNT(time-base counter)中。

(指南P389)

(指南P390)

(指南P466)

该API如下:

voidEHRPWMTimebaseSyncDisable(unsignedint baseAddr)

{

HWREGH(baseAddr+ EHRPWM_TBCTL) &= (~EHRPWM_SYNC_ENABLE);

}

6.4 禁用输出同步信号

EHRPWMSyncOutModeSet函数设置TBCTL的SYNCOSEL位为3h,禁用EPWM1的输出同步信号EPWM1SYNCO,输出同步信号产生的条件可以是EPWM1SYNCIN、CTR=0、CTR=CMPB三个。

(指南P386)

(指南P387)

(指南P465)

该API如下:

voidEHRPWMSyncOutModeSet(unsignedint baseAddr, unsignedint syncOutMode)

{

HWREGH(baseAddr+ EHRPWM_TBCTL) = (HWREGH(baseAddr+ EHRPWM_TBCTL) &

(~EHRPWM_SYNCOUT_MASK))| syncOutMode;

}

6.5 仿真模式行为配置

EHRPWMTBEmulationModeSet函数设置TBCTL的FREE、SOFT位,配置EPWM的仿真模式行为(即在调试时timebase的行为),这里将FREE、SOFT位设为0,则在仿真事件(emulation event)发生后,ePWM的时基计数器(time-base counter)将在下一次增量(increment)或减量(decrement)发生后停止。

(指南P465)

该API如下:

voidEHRPWMTBEmulationModeSet(unsignedint baseAddr, unsignedint mode)

{

HWREGH(baseAddr+ EHRPWM_TBCTL) = (HWREGH(baseAddr+ EHRPWM_TBCTL) &

(~EHRPWM_TBCTL_FREE_SOFT))| (mode & EHRPWM_TBCTL_FREE_SOFT);

}

6.6 配置计数比较器子模块

6.6.1 加载比较器A值

计数器比较子模块(counter-compare submodule)接收时基计数器(time-base counter)的值作为输入,这个值不断地同比较计数器(counter-compare)A和比较计数器B寄存器相比较。当时基计数器的值等于其中一个比较寄存器时,这个计数器比较单元就会产生相应的事件,将事件信号输出到AQ模块中(Action Qualifier)。

(指南P394)

加载比较器A值函数EHRPWMLoadCMPA如下:

boolEHRPWMLoadCMPA(unsignedint baseAddr,

unsignedint CMPAVal,

bool enableShadowWrite,

unsignedint ShadowToActiveLoadTrigger,

bool OverwriteShadowFull)

{

bool status=FALSE;

 

if((OverwriteShadowFull)||

((HWREGH(baseAddr+EHRPWM_CMPCTL)& EHRPWM_CMPCTL_SHDWAFULL)==

EHRPWM_SHADOW_A_EMPTY))

{

HWREGH(baseAddr+ EHRPWM_CMPCTL) = (HWREGH(baseAddr+ EHRPWM_CMPCTL) &

(~EHRPWM_CMPCTL_SHDWAMODE))| ((enableShadowWrite <<

EHRPWM_CMPCTL_SHDWAMODE_SHIFT)& EHRPWM_CMPCTL_SHDWAMODE);

 

HWREGH(baseAddr+ EHRPWM_CMPCTL) = (HWREGH(baseAddr+ EHRPWM_CMPCTL) &

(~EHRPWM_COMPA_LOAD_MASK))|((ShadowToActiveLoadTrigger<<

EHRPWM_CMPCTL_LOADAMODE_SHIFT)& EHRPWM_COMPA_LOAD_MASK);

 

HWREGH(baseAddr+ EHRPWM_CMPA) = CMPAVal & EHRPWM_CMPA_CMPA;

 

status=TRUE;

}

 

return status;

}

函数先判断OverwriteShadowFull标志是否为1(真),如果为真,则不管Counter-compare A(CMPA)影子寄存器(shadow register)是否为满(SHDWAFULL=1),都往里overwrite,又或者CMPA影子寄存器为空(SHDWAFULL),也往CMPA Shadow register所在地址写数据。

(指南P469)

CMPA shadow register与CMPA active register共享同一地址,往该地址写数据时,到底往哪一个寄存器写是通过CMPCTL寄存器的SHDWAMODE位(CMPA寄存器操作模式)来决定的。这里程序把该位设为了1,即选择immediate模式,往该地址写数据直接往active register写。然后程序又设置CMPCTL的LOADAMODE位(active counter-compare A load from shadow select mode)为3h,则freeze加载行为,CMPA的active register将不从shadow register加载。

(指南P469)

    最后将要写往CMPA active register的值CMPAVal写入到CMPA active register中。这里

(指南P470)

6.6.2 加载比较器B值

加载比较器B值函数EHRPWMLoadCMPB如下:

boolEHRPWMLoadCMPB(unsignedint baseAddr,

unsignedint CMPBVal,

bool enableShadowWrite,

unsignedint ShadowToActiveLoadTrigger,

bool OverwriteShadowFull)

{

bool status=FALSE;

 

if((OverwriteShadowFull)||

((HWREGH(baseAddr+EHRPWM_CMPCTL)& EHRPWM_CMPCTL_SHDWBFULL)==

EHRPWM_SHADOW_B_EMPTY))

{

HWREGH(baseAddr+ EHRPWM_CMPCTL) = (HWREGH(baseAddr+ EHRPWM_CMPCTL)

& (~EHRPWM_CMPCTL_SHDWBMODE))| ((enableShadowWrite <<

EHRPWM_CMPCTL_SHDWBMODE_SHIFT)& EHRPWM_CMPCTL_SHDWBMODE);

 

HWREGH(baseAddr+ EHRPWM_CMPCTL) = (HWREGH(baseAddr+ EHRPWM_CMPCTL) &

(~EHRPWM_COMPB_LOAD_MASK))| ((ShadowToActiveLoadTrigger<<

EHRPWM_CMPCTL_LOADBMODE_SHIFT)& EHRPWM_COMPB_LOAD_MASK);

 

HWREGH(baseAddr+ EHRPWM_CMPB) = CMPBVal & EHRPWM_CMPB_CMPB;

 

status=TRUE;

}

return status;

}

函数与加载比较器A值函数基本一致,不同的只是判断的条件变成了CMPB shadow register是否满。设置的位变成了CMPCTL的SHDWBMODE和LOADBMODE位,比较器数据写往了CMPB。这里不再细述。

6.7 功能限定配置(输出引脚触发方式设定)

    函数EHRPWMConfigureAQActionOnA设定输出引脚触发方式,这里设置时间基准计数等于有效计数比较寄存器A/B值时EPWM1_A翻转,波形由EPWM1_A输出。该API如下:

voidEHRPWMConfigureAQActionOnA(unsignedint baseAddr,

unsignedint zero,

unsignedint period,

unsignedint CAUp,

unsignedint CADown,

unsignedint CBUp,

unsignedint CBDown,

unsignedint SWForced)

{

HWREGH(baseAddr+ EHRPWM_AQCTLA) =

((CBDown<< EHRPWM_AQCTLA_CBD_SHIFT)& EHRPWM_AQCTLA_CBD) |

((CBUp<< EHRPWM_AQCTLA_CBU_SHIFT)& EHRPWM_AQCTLA_CBU) |

((CADown<< EHRPWM_AQCTLA_CAD_SHIFT)& EHRPWM_AQCTLA_CAD) |

((CAUp<< EHRPWM_AQCTLA_CAU_SHIFT)& EHRPWM_AQCTLA_CAU) |

((period<< EHRPWM_AQCTLA_PRD_SHIFT)& EHRPWM_AQCTLA_PRD) |

((zero<< EHRPWM_AQCTLA_ZRO_SHIFT)& EHRPWM_AQCTLA_ZRO);

 

HWREGH(baseAddr+ EHRPWM_AQSFRC) = (HWREGH(baseAddr+ EHRPWM_AQSFRC) &

(~EHRPWM_AQSFRC_ACTSFA))| ((SWForced <<

EHRPWM_AQSFRC_ACTSFA_SHIFT)& EHRPWM_AQSFRC_ACTSFA);

}

该函数设置AQCTLA寄存器的CBD、CBU、CAD、CAU、PRD、ZRO位,配置EPWM模块的A通道在相应事件发生时的动作。然后设置AQSFRC寄存器的ACTSFA位,配置EPWM1_A在One-time Force A被invoke时的动作(action)。

(指南P472)

(指南P474)

    这里程序设置在TBCNT向上计数等于CMPA和CMPB时EPWM1_A输出翻转,其它时候不动作。

6.8 禁用死区模块

EHRPWMDBOutput函数选择死区模块的输出模式,这里禁用死区模块,由AQ模块(action qualifier)输出的信号在通过死区模块(dead band)时,被旁路,不做任何处理,信号被直接输出到斩波(PC,PWM chopper)子模块,注意图中DB的虚线,虚线表示旁路处理。

(指南P417)

通过设置DBCTL[OUT_MODE]位可以控制信号是否旁路,如图:

(指南P418)

该API如下:

voidEHRPWMDBOutput(unsignedint baseAddr, unsignedint DBgenOpMode)

{

HWREGH(baseAddr+ EHRPWM_DBCTL) =

(HWREGH(baseAddr+ EHRPWM_DBCTL) & (~EHRPWM_DBCTL_OUT_MODE))|

((DBgenOpMode<< EHRPWM_DBCTL_OUT_MODE_SHIFT)& EHRPWM_DBCTL_OUT_MODE);

}

函数通过设置DBCTL[OUT_MODE]位可以设置4种不同的输出模式,分别确定A通道和B通道信号是否要旁路。

(指南P476)

6.9 禁用斩波子模块

EHRPWMChopperDisable函数设置PCCTL的CHPEN位为0,禁用PWM斩波子模块的PWM斩波功能,信号经过斩波子模块时,直接被bypass,不作任何处理。该API如下:

voidEHRPWMChopperDisable(unsignedint baseAddr)

{

HWREGH(baseAddr+ EHRPWM_PCCTL) &= (~EHRPWM_PCCTL_CHPEN);

}

 

(指南P422)

(指南P478)

6.10 禁用错误控制事件

EHRPWMTZTripEventDisable函数禁用错误控制事件(trip event),当TZ引脚输入了错误信号时,错误处理模块(Trip Zone)将不会作任何处理。这里,程序设置TZSEL[OSHT1]位和TZSEL[CBC1]位为0,禁用了EPWM1模块的Trip Zone子模块产生CBC事件(Cycle-by-Cycle)和OSHT事件(One-Shot)。该API如下:

voidEHRPWMTZTripEventDisable(unsignedint baseAddr, bool osht_CBC)

{

if(EHRPWM_TZ_ONESHOT== osht_CBC)

{

HWREGH(baseAddr+ EHRPWM_TZSEL) &= (~EHRPWM_TZSEL_OSHT1);

}

if(EHRPWM_TZ_CYCLEBYCYCLE== osht_CBC)

{

HWREGH(baseAddr+ EHRPWM_TZSEL) &= (~EHRPWM_TZSEL_CBC1);

}

}

(指南P428)

(指南P479)

6.11 事件触发配置

6.11.1 每三次事件发生产生中断

    EHRPWMETIntPrescale函数设置事件触发(event trigger,ET)子模块的ETPS寄存器(event prescale),设置ETPS[INTPRD]位对要产生中断的事件进行预分频处理(即发生多少次事件才产生一次中断),这里程序设置为3次,即每3次事件发生,产生1次中断。ET子模块接收由时基子模块(time-base)和计数器比较子模块(counter-compare)所产生的事件信号输入,并产生中断信号给CPU。要产生中断的事件由ETSEL[INTSEL]位选择。EHRPWMETIntPrescale函数如下:

voidEHRPWMETIntPrescale(unsignedint baseAddr, unsignedint prescale)

{

HWREGH(baseAddr+ EHRPWM_ETPS) =

(HWREGH(baseAddr+ EHRPWM_ETPS) & (~EHRPWM_ETPS_INTPRD))|

((prescale<< EHRPWM_ETPS_INTPRD_SHIFT)& EHRPWM_ETPS_INTPRD);

}

(指南P484)

6.11.2 时间基准等于有效计数比较寄存器B值产生事件

EHRPWMETIntSourceSelect函数设置产生EPWM中断的源(source),函数设置ETSEL[INTSEL]位,确定什么事件发生时,ETPS[INTCNT]会加1。这里程序设置源为CTRU=CMPB,即TBCTR向上计数到等于CMPB时产生一次事件。该API如下:

voidEHRPWMETIntSourceSelect(unsignedint baseAddr, unsignedint selectInt)

{

HWREGH(baseAddr+ EHRPWM_ETSEL) =

(HWREGH(baseAddr+ EHRPWM_ETSEL) & (~EHRPWM_ETSEL_INTSEL))|

((selectInt<< EHRPWM_ETSEL_INTSEL_SHIFT)& EHRPWM_ETSEL_INTSEL);

}

(指南P432)

(指南P483)

6.12 使能中断

EHRPWMETIntEnable函数设置ETSEL[INTEN]位为1,使能EPWMx_INT中断信号的产生。该API如下:

voidEHRPWMETIntEnable(unsignedint baseAddr)

{

HWREGH(baseAddr+ EHRPWM_ETSEL) |= EHRPWM_ETSEL_INTEN;

}

6.13 禁用高精度子模块

EHRPWMHRDisable函数设置HRCNFG寄存器(HRPWM configuration register)的EDGEMODE位,禁用HRPWM功能。该API如下:

voidEHRPWMHRDisable(unsignedint baseAddr)

{

HWREGH(baseAddr+ EHRPWM_HRCNFG) &= (~EHRPWM_HR_EDGEMODE);

}

(指南P488)

7.斩波(可选)

    斩波函数如下:

voidChopperWaveform(void)

{

// 50%占空比

EHRPWMConfigureChopperDuty(SOC_EHRPWM_1_REGS, EHRPWM_CHP_DUTY_50_PER);

// 4分频

EHRPWMConfigureChopperFreq(SOC_EHRPWM_1_REGS, EHRPWM_PCCTL_CHPFREQ_DIVBY4);

//单个脉冲宽度

EHRPWMConfigureChopperOSPW(SOC_EHRPWM_1_REGS,0xF);

//使能斩波子模块

EHRPWMChopperEnable(SOC_EHRPWM_1_REGS);

}

7.1 设置斩波占空比

EHRPWMConfigureChopperDuty函数设置PCCTL[CHPDUTY]位,设置斩波PSCLK的占空比,这里设为3h,即50%,该API如下:

voidEHRPWMConfigureChopperDuty(unsignedint baseAddr, unsignedint dutyCycle)

{

HWREGH(baseAddr+ EHRPWM_PCCTL) =

(HWREGH(baseAddr+ EHRPWM_PCCTL) & (~EHRPWM_PCCTL_CHPDUTY))|

((dutyCycle<< EHRPWM_PCCTL_CHPDUTY_SHIFT)& EHRPWM_PCCTL_CHPDUTY);

}

(指南P424)

7.2 设置斩波频率

EHRPWMConfigureChopperFreq函数设置PCCTL[CHPFREQ],通过设置分频细述,设置斩波频率,斩波频率是从SYSCLKOUT(即CPU时钟频率)分频得来的。该API如下:

voidEHRPWMConfigureChopperFreq(unsignedint baseAddr, unsignedint freqDiv)

{

 

if(freqDiv> EHRPWM_PCCTL_CHPFREQ_DIVBY8)

{

freqDiv= EHRPWM_PCCTL_CHPFREQ_DIVBY8;

}

 

HWREGH(baseAddr+ EHRPWM_PCCTL) =

(HWREGH(baseAddr+ EHRPWM_PCCTL) & (~EHRPWM_PCCTL_CHPFREQ))|

((freqDiv<< EHRPWM_PCCTL_CHPFREQ_SHIFT)& EHRPWM_PCCTL_CHPFREQ);

}

 

(指南P422)

(指南P478)

7.3 设置单个脉冲宽度

    EHRPWMConfigureChopperOSPW函数设置PCCTL[OSHTWTH]位,设置one-shot pulse width,这里设为0x0F,即one-shot脉冲宽度为16 x SYSCLKOUT/8。

(指南P423)

(指南P478)

7.4 使能斩波子模块

EHRPWMChopperEnable函数设置PCCTL[CHPEN]位为1,使能斩波子模块,该API如下:

voidEHRPWMChopperEnable(unsignedint baseAddr)

{

HWREGH(baseAddr+ EHRPWM_PCCTL) |= EHRPWM_PCCTL_CHPEN;

}

(指南P478)

8.中断服务函数

8.1 PWM事件中断服务函数

    PWM事件中断服务函数PWMEventIsr如下:

voidPWMEventIsr(void)

{

    IntEventClear(SYS_INT_EHRPWM1);

 

EHRPWMETIntClear(SOC_EHRPWM_1_REGS);

}

函数先是清除EVTFLAGn被置位的中断标志(SYS_INT_EHRPWM1位),IntEventClear函数在\demo\StarterWare\Source\StarterWare\SystemConfig 路径system_config工程下的interrupt.c文件中,函数如下:

voidIntEventClear(unsignedint sysINT)

{

unsignedint dspintcREG;

 

/* Check the system event number */

ASSERT((sysINT<=127));

 

/* Get the address of the correct event register */

dspintcREG= SOC_INTC_0_REGS +DSPINTC_EVTCLR((sysINT>>5));

 

/* Clear the corresponding bit within the event clear register */

HWREG(dspintcREG)=DSPINTC_EVTCLR_EC(sysINT);

}

细节可参考这篇博文。

C6748_EDMA_GPIO_中断学习笔记

然后EHRPWMETIntClear函数往ETCLR寄存器的INT位写1,清除ETFLG[INT]位,清除ePWM中断标志。该API如下:

voidEHRPWMETIntClear(unsignedint baseAddr)

{

HWREGH(baseAddr+ EHRPWM_ETCLR) |= EHRPWM_ETCLR_INT;

}

(指南P485)

(指南P485)

8.2 PWM错误事件中断服务函数

    PWM错误事件中断服务函数PWMTZIsr如下:

voidPWMTZIsr(void)

{

    IntEventClear(SYS_INT_EHRPWM1TZ);

 

EHRPWMTZFlagClear(SOC_EHRPWM_1_REGS, EHRPWM_TZ_CYCLEBYCYCLE_CLEAR);

}

首先在EVTFLAGn寄存器中清除SYS_INT_EHRPWM1TZ(#23)对应的中断标志位,然后EHRPWMTZFlagClear函数设置TZCLR的相应位,清除相应错误标志,这里设置TZCLR[CBC]和TZCLR[INT]位,清除CBC trip latch标志和ePWM模块trip-interrupt中断标志TZFLG[INT]。EHRPWMTZFlagClear函数如下:

voidEHRPWMTZFlagClear(unsignedint baseAddr, unsignedint flagToClear)

{

HWREGH(baseAddr+ EHRPWM_TZCLR) = flagToClear &

(EHRPWM_TZCLR_OST| EHRPWM_TZCLR_CBC | EHRPWM_TZCLR_INT);

}6748_PWMT]weTZ,Q/pwmclkFREQ

(指南P482)

(指南P428)

9.参考文献

[1] TMS320F28027 之PWM 模块

[2] PWM死区(Dead Zone)的作用和意义