C6748_ECAP_APWM

1.主函数流程

C6748_ECAP_APWM

此程序的作用是实现eCAP(增强型捕获模块)的APWM(辅助脉冲宽度调制器)输出功能。主函数如下:

intmain(void)

{

    // 外设使能配置

    PSCInit();

     

    // GPIO 管脚复用配置

    GPIOBankPinMuxSet();

 

    // DSP 中断初始化

    InterruptInit();

 

    // PWM 中断初始化

    APWMInterruptInit();

 

    // 产生波形

    APWMInit();

 

    // 主循环

    for(;;)

    {

 

    }

}

2.外设使能配置

    函数首先在PSC模块中使能外设,这里是eCAP0/1/2。外设使能配置函数PSCInit如下:

voidPSCInit(void)

{

    // 使能 ECAP 模块

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

PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_ECAP0_1_2, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

}

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

C6748_UART_EDMA

C6748_ECAP_APWM

(指南P163)

3.GPIO管脚复用配置

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

voidGPIOBankPinMuxSet(void)

{

    // OMAPL138 / DSP C6748 有三个增强捕获模块(ECAP

    // 作为捕获功能时管脚方向为输入

    // 作为辅助脉宽调制时管脚方向为输出

// ECAP0 / APWM0

    ECAPPinMuxSetup(0);

// ECAP1 / APWM1

    ECAPPinMuxSetup(1);

// ECAP2 / APWM2

    ECAPPinMuxSetup(2);

}

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

voidECAPPinMuxSetup(unsignedchar n)

{

unsignedint savePinmux =0;

 

if(n==0)

{

        savePinmux = (HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(2)) &

                     ~(SYSCFG_PINMUX2_PINMUX2_31_28));

 

        HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(2)) =

             (PINMUX2_ECAP0_ENABLE | savePinmux);

}

elseif(n==1)

{

        savePinmux = (HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(1)) &

                     ~(SYSCFG_PINMUX1_PINMUX1_31_28));

 

        HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(1)) =

             (PINMUX1_ECAP1_ENABLE | savePinmux);

}

elseif(n==2)

{

        savePinmux = (HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(1)) &

                     ~(SYSCFG_PINMUX1_PINMUX1_3_0));

 

        HWREG(SOC_SYSCFG_0_REGS +SYSCFG0_PINMUX(1)) =

             (PINMUX1_ECAP2_ENABLE | savePinmux);

}

}

该函数将ECAP模块相关引脚配置为ECAPx_APWMx功能引脚,这里依次设置ECAP0、ECAP1、ECAP2的相关引脚功能设为ECAP0_APWM0、ECAP1_APWM1、ECAP2_APWM2。

C6748_ECAP_APWM

(指南P221)

C6748_ECAP_APWM

(指南P219)

C6748_ECAP_APWM

(指南P220)

 

4.DSP中断初始化

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

voidInterruptInit(void)

{

    // 初始化 DSP 中断控制器

    IntDSPINTCInit();

 

    // 使能 DSP 全局中断

    IntGlobalEnable();

}

函数细节参考这里

C6748_SPI_FLASH

5.PWM中断初始化

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

voidAPWMInterruptInit(void)

{

    // 注册中断服务函数

    IntRegister(C674X_MASK_INT4, APWMIsr);

 

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

    IntEventMap(C674X_MASK_INT4, SYS_INT_ECAP_SELECT);

 

    // 使能 DSP 可屏蔽中断

    IntEnable(C674X_MASK_INT4);

 

    // 计数值与比较器值相等时产生中断

    ECAPIntEnable(SOC_ECAP_REGS_SELECT, ECAP_CMPEQ_INT);

 

    // 使能 ECAP 全局中断

    ECAPGlobalIntEnable(SOC_ECAP_REGS_SELECT);

}

函数将CPU可屏蔽中断C674X_MASK_INT4的中断服务函数注册为APWMIsr。然后将中断事件SYS_INT_ECAP_SELECT#51ECAP2中断)映射到CPU中断INT4,最后使能INT4

C6748_ECAP_APWM

(手册P94

ECAPIntEnable函数指明什么事件发生时,产生ECAP中断。ECAP模块可以在捕获事件(capture event)(CEVT1-CEVT4,CTROVF)或者是APWM事件(CTR=PRD,CTR=CMP)发生时,产生ECAP中断。这里程序设置ECEINT[7]位(CTR=CMP)为1,使能计数器与比较值相等时产生中断。该API如下:

voidECAPIntEnable(unsignedint baseAdd, unsignedint flag)

{

HWREGH(baseAdd + ECAP_ECEINT) |= flag;

}

C6748_ECAP_APWM

(指南P345

C6748_ECAP_APWM

(指南P370

最后,在产生ECAP中断前,还需要先清除ECAP模块全局中断标志,ECAPGlobalIntEnable函数ECCLR[INT]位为1,清除ECFLG,从而使能ECAP中断。该API如下:

voidECAPGlobalIntEnable(unsignedint baseAdd)

{

HWREGH(baseAdd + ECAP_ECCLR) |= ECAP_ECCLR_INT;

}

6.产生波形

产生波形函数APWMInit如下:

voidAPWMInit(void)

{

    // 配置 ECAP 2 APWM 模式

    ECAPOperatingModeSelect(SOC_ECAP_REGS_SELECT, ECAP_APWM_MODE);

    // 配置周期及占空比(比较计数器值)

    ECAPAPWMCaptureConfig(SOC_ECAP_REGS_SELECT, Period*DutyCycle, Period);

    // 输出相位配置

    ECAPAPWMPolarityConfig(SOC_ECAP_REGS_SELECT, ECAP_APWM_ACTIVE_LOW);

    // 启动比较计数器

    ECAPCounterControl(SOC_ECAP_REGS_SELECT, ECAP_COUNTER_FREE_RUNNING);

}

6.1 配置ECAP2为APWM模式

ECAPOperatingModeSelect函数配置eCAP模块是运行在捕获模式还是APWM模式。ECAP模块有2种操作模式(modes of operation),一种是捕获模式(capture mode),另一种是APWM模式(auxiliary pulse-width modulator mode)。这里程序设置ECCTL[9]位(CAP/APWM)为1,将ECAP模块运行模式设为APWM模式。

C6748_ECAP_APWM

(指南P339)

C6748_ECAP_APWM

(指南P368)

6.2 配置周期及占空比(比较计数器值)

    ECAPAPWMCaptureConfig函数配置APWM模式下eCAP模块输出PWM波形的周期和占空比,在APWM模式下,capture1和capture2寄存器被用作周期寄存器和比较寄存器。该函数设置capture1和capture2寄存器,从而设置PWM波的周期和占空比。ECAPs模块的输入时钟频率为228MHz(PLL1_SYSCLK1/2=456MHz/2=228MHz),这里函数设置周期寄存器Period reg("CAP1")的值为22800,则输出PWM波频率为10KHz(228MHz/22800=10000Hz=10KHz),设置比较寄存器Compare reg("CAP2")的值为11400(22800*0.5=11400),则输出PWM波的占空比为50%。该API如下:

voidECAPAPWMCaptureConfig(unsignedint baseAdd, unsignedint compareVal,

unsignedint periodVal)

{

HWREG(baseAdd + ECAP_CAP1) = periodVal;

HWREG(baseAdd + ECAP_CAP2) = compareVal;

}

C6748_ECAP_APWM

(指南P364)

C6748_ECAP_APWM

(指南P365)

C6748_ECAP_APWM

(指南P346)

6.3 输出相位配置

    ECAPAPWMPolarityConfig函数设置ECCTL2[APWMPOL]位,配置eCAP模块APWM输出的极性,这里程序设置该位为1,即输出为低电平有效(active low),即比较值(Compare value)定义了一个周期中的低电平时间。该API如下:

voidECAPAPWMPolarityConfig(unsignedint baseAdd, unsignedint flag)

{

if(flag)

{

HWREGH(baseAdd + ECAP_ECCTL2) |= ECAP_ECCTL2_APWMPOL;

}

else

{

HWREGH(baseAdd + ECAP_ECCTL2) &=~ECAP_ECCTL2_APWMPOL;

}

}

C6748_ECAP_APWM

(指南P368)

6.4 启动比较计数器

    ECAPCounterControl函数设置ECCTL2[TSCTRSTOP]位,配置计数器是停止还是运行(free running),这里程序将该位设为1,启动计数器。

C6748_ECAP_APWM

(指南P368)

7.中断服务函数

    中断服务函数如下:

voidAPWMIsr(void)

{

//  SW_BREAKPOINT

 

// 禁用中断

    ECAPIntDisable(SYS_INT_ECAP_SELECT, ECAP_CMPEQ_INT);

    // 清除中断标志

    IntEventClear(SYS_INT_ECAP_SELECT);

    ECAPIntStatusClear(SOC_ECAP_REGS_SELECT, ECAP_CMPEQ_INT);;

    // 使能中断

    ECAPIntEnable(SOC_ECAP_REGS_SELECT, ECAP_CMPEQ_INT);

}

7.1 禁用中断

    程序先是禁用了ECAP中断,ECAPIntDisable函数设置ECEINT的相关位,禁用指定的ECAP事件中断。这里程序设置了ECEINT[7](CTR=CMP)为0,禁止比较相等(Compare Equal)事件作为中断源。该API如下:

voidECAPIntDisable(unsignedint baseAdd, unsignedint flag)

{

HWREGH(baseAdd + ECAP_ECEINT) =HWREG(baseAdd + ECAP_ECEINT) &~flag;

}

C6748_ECAP_APWM

(指南P370)

7.2 清除中断标志

    接着,程序清除中断标志,IntEventClear函数清除EVTFLAGn被置位的中断标志(这里是SYS_INT_ECAP_SELECT,#51),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_中断学习笔记

然后,ECAPIntStatusClear设置ECCLR的相关位,清除相应的事件标志,这里是设置ECCLR[7](CTR=CMP)为1,从而清除CTR=CMP标志状态。该API如下:

voidECAPIntStatusClear(unsignedint baseAdd, unsignedint flag)

{

HWREGH(baseAdd + ECAP_ECCLR) = flag;//HWREGH(baseAdd + ECAP_ECCLR) & flag;

}

7.3 使能中断

    最后,程序再使能CMPEQ中断。

8.参考文献

[1] DSP28335的eCAP模块

[2]【创龙TMS320C6748开发板试用】+ECAP模块初探