DSP

C6748_ECAP_APWM

2019-07-13 12:48发布

目录 1.主函数流程 2.外设使能配置 3.GPIO管脚复用配置 4.DSP中断初始化 5.PWM中断初始化 6.产生波形 6.1 配置ECAP2为APWM模式 6.2 配置周期及占空比(比较计数器值) 6.3 输出相位配置 6.4 启动比较计数器 7.中断服务函数 7.1 禁用中断 7.2 清除中断标志 7.3 使能中断 8.参考文献

1.主函数流程

  此程序的作用是实现eCAP(增强型捕获模块)的APWM(辅助脉冲宽度调制器)输出功能。主函数如下: int main(void) { // 外设使能配置 PSCInit(); // GPIO 管脚复用配置 GPIOBankPinMuxSet(); // DSP 中断初始化 InterruptInit(); // PWM 中断初始化 APWMInterruptInit(); // 产生波形 APWMInit(); // 主循环 for(;;) { } }

2.外设使能配置

      函数首先在PSC模块中使能外设,这里是eCAP0/1/2。外设使能配置函数PSCInit如下: void PSCInit(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                                                                                  (指南P163)

3.GPIO管脚复用配置

将ECAP模块所在的引脚的功能(function)配置为ECAP功能,GPIO管脚复用配置函数GPIOBankPinMuxSet如下: void GPIOBankPinMuxSet(void) { // OMAPL138 / DSP C6748 有三个增强捕获模块(ECAP) // 作为捕获功能时管脚方向为输入 // 作为辅助脉宽调制时管脚方向为输出 // ECAP0 / APWM0 ECAPPinMuxSetup(0); // ECAP1 / APWM1 ECAPPinMuxSetup(1); // ECAP2 / APWM2 ECAPPinMuxSetup(2); } ECAPPinMuxSetup函数在demo的Platform工程下的ECAP.c文件中,函数如下: void ECAPPinMuxSetup(unsigned char n) { unsigned int 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); } else if(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); } else if(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。                                                                         (指南P221)                                                                          (指南P219)                                                                         (指南P220)

4.DSP中断初始化

    DSP中断初始化函数InterruptInit如下: void InterruptInit(void) { // 初始化 DSP 中断控制器 IntDSPINTCInit(); // 使能 DSP 全局中断 IntGlobalEnable(); } 函数细节参考这里 C6748_SPI_FLASH

5.PWM中断初始化

PWM中断初始化函数APWMInterruptInit如下: void APWMInterruptInit(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(#51,ECAP2中断)映射到CPU中断INT4,最后使能INT4。                                                                               (手册P94) ECAPIntEnable函数指明什么事件发生时,产生ECAP中断。ECAP模块可以在捕获事件(capture event)(CEVT1-CEVT4,CTROVF)或者是APWM事件(CTR=PRD,CTR=CMP)发生时,产生ECAP中断。这里程序设置ECEINT[7]位(CTR=CMP)为1,使能计数器与比较值相等时产生中断。该API如下: void ECAPIntEnable(unsigned int baseAdd, unsigned int flag) { HWREGH(baseAdd + ECAP_ECEINT) |= flag; }                                                                             (指南P345)                                                                             (指南P370) 最后,在产生ECAP中断前,还需要先清除ECAP模块全局中断标志,ECAPGlobalIntEnable函数ECCLR[INT]位为1,清除ECFLG,从而使能ECAP中断。该API如下: void ECAPGlobalIntEnable(unsigned int baseAdd) { HWREGH(baseAdd + ECAP_ECCLR) |= ECAP_ECCLR_INT; }

6.产生波形

产生波形函数APWMInit如下: void APWMInit(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模式。                                                                                                                         (指南P339)                                                                              (指南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如下: void ECAPAPWMCaptureConfig(unsigned int baseAdd, unsigned int compareVal, unsigned int periodVal) { HWREG(baseAdd + ECAP_CAP1) = periodVal; HWREG(baseAdd + ECAP_CAP2) = compareVal; }                                                                           (指南P364)                                                                           (指南P365)                                                                          (指南P346)

6.3 输出相位配置

    ECAPAPWMPolarityConfig函数设置ECCTL2[APWMPOL]位,配置eCAP模块APWM输出的极性,这里程序设置该位为1,即输出为低电平有效(active low),即比较值(Compare value)定义了一个周期中的低电平时间。该API如下: void ECAPAPWMPolarityConfig(unsigned int baseAdd, unsigned int flag) { if(flag) { HWREGH(baseAdd + ECAP_ECCTL2) |= ECAP_ECCTL2_APWMPOL; } else { HWREGH(baseAdd + ECAP_ECCTL2) &= ~ECAP_ECCTL2_APWMPOL; } }                                                                                 (指南P368)

6.4 启动比较计数器

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

7.中断服务函数

    中断服务函数如下: void APWMIsr(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如下: void ECAPIntDisable(unsigned int baseAdd, unsigned int flag) { HWREGH(baseAdd + ECAP_ECEINT) = HWREG(baseAdd + ECAP_ECEINT) & ~flag; }                                                                              (指南P370)

7.2 清除中断标志

    接着,程序清除中断标志,IntEventClear函数清除EVTFLAGn被置位的中断标志(这里是SYS_INT_ECAP_SELECT,#51),IntEventClear函数在demoStarterWareSourceStarterWareSystemConfig 路径system_config工程下的interrupt.c文件中,函数如下: void IntEventClear(unsigned int sysINT) { unsigned int 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如下: void ECAPIntStatusClear(unsigned int baseAdd, unsigned int flag) { HWREGH(baseAdd + ECAP_ECCLR) = flag;//HWREGH(baseAdd + ECAP_ECCLR) & flag; }

7.3 使能中断

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

8.参考文献

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