目录
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模块初探