TMS320C6748_ECAP_APWM

目录

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函数在\demo\StarterWare\Source\StarterWare\SystemConfig 路径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模块初探

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值