3、DSP28335输出两路PWM波并设置死区

本文详细介绍了如何在嵌入式系统中使用EPWM(EnhancedPulseWidthModulation)控制占空比,包括向上计数和上下计数模式下配置时基模块、比较模块、动作限定模块以及事件触发模块,以实现不同频率的PWM波形生成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 占空比是指高电平在一个脉冲周期中所占的比例

#include "epwm.h"

//1000k == 1MHz
//1us   -->1Mhz
//10us  -->100KHz
//主频 / 周期值 = 频率

#if PWM_COUNT_UP
//向上计数模式:主频为150MHz,周期值设置为1500,即一个周期有10us,向上计数仅有一个CMP比较值,且为周期的一半
//设置计数值等于0时,输出低电平,大于CMP比较值时输出高电平,即所得占空比为50%,频率为100KHz
void EPwmInit(void)
{
	//1、使能ePWM外设时钟,及失能时基模块时钟,这里在mian函数InitSysCtrl()中完成

	//2、配置对应的GPIO
	InitEPwm6Gpio();

	//3、初始化时基模块TB
	//TB模块用来产生一个时基信号TBCLK,TBCLK通过系统时钟SYSCLKOUT传递过来,同时还需要通过两个时钟分频器进行分频(HSPCLKDIV和CLKDIV)

	//关闭时钟同步输入
	EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
	//关闭相位使能
	EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;
	//如果打开时钟同步功能和相位使能功能,那么TBPHS设置的值就会被加载到TBCTR(计数值)里
	EPwm6Regs.TBPHS.half.TBPHS = 0;
	//初始计数值
	EPwm6Regs.TBCTR = 0x0000;
	//设置计数方式
	EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;

	//最高主频 150M
	//时钟分频由两位控制,这里一分频 TBCLK = SYSCLKOUT(HSPCLKDIV * CLKDIV)
	//这里相当于不分频,TBCLK为 150MHz,计数150次,需要1us
	EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
	EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1;

	//周期设置为1500,相当于计数1500次,需要10us,周期为10us

    //PWM周期 1500/TBCLK,这里有影子寄存器和活动寄存器
    //当使用影子寄存器更新周期值时,当发生某一个特定时刻时更新
    //当使用活动寄存器时,会立马更新
    EPwm6Regs.TBPRD = 1500;

	//4、初始化比较模块CC
	//影子寄存器模式设置,可以配置为影子寄存器和活动寄存器
	//当配置为活动寄存器时,设置的CMPA值立马起作用
	//当配置为影子寄存器时,当发生某一个特定时刻时,影子寄存器的值传入到活动寄存器中
	EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
	EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

	//要配置影子寄存器工作,需要配置LOADAMODE,当CTR(计数值)为0时加载
	EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
	EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

	//设置比较值

	EPwm6Regs.CMPA.half.CMPA = 750;
    EPwm6Regs.CMPB = 750;

	//5、初始化动作限定模块AQ

    //AQ_NO_ACTION  无动作
    //AQ_CLEAR      置低
    //AQ_SET        置高
    //AQ_TOGGLE     电平翻转

    //ZRO   当计数值 == 0
    //PRD   当计数值 == 周期值
    //CAU   向上计数时,计数值 == CMPA
    //CAD   向下计数时,计数值 == CMPA
    //CBU   向上计数时,计数值 == CMPB
    //CBD   向下计数时,计数值 == CMPB

	EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR;
	EPwm6Regs.AQCTLA.bit.CAU = AQ_SET;

	EPwm6Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
	EPwm6Regs.AQCTLB.bit.CBU = AQ_SET;

	//5、死区
//    DBA_ALL         0x0   ePWMA作为双边延时输入源
//    DBB_RED_DBA_FED 0x1   ePWMB是上升延时输入源 ,epwmA是下降延时输入源
//    DBA_RED_DBB_FED 0x2   ePWMA是上升延时输入源 ,epwmB是下降延时输入源
//    DBB_ALL         0x3   ePWMB是双边沿延时输入源
	EPwm6Regs.DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;
//    DB_ACTV_HI      0x0
//    DB_ACTV_LOC     0x1   //极性选择:A不翻转,B翻转
//    DB_ACTV_HIC     0x2   //极性选择:A翻转,B不翻转
//    DB_ACTV_LO      0x3
	EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;   //极性选择:A不翻转,B翻转
//    DB_DISABLE      0x0   ePWMA 和 ePWMB 都不经过死区
//    DBA_ENABLE      0x1   禁止上升沿延时,使能下降沿延时(一个过下降沿死区,一个直接输出)
//    DBB_ENABLE      0x2   禁止下降沿延时,使能上升沿延时(一个过上升沿死区,一个直接输出)
//    DB_FULL_ENABLE  0x3	ePWMA 和 ePWMB 都经过死区
	EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;

	//一个pwm波周期有一个死区时间(一个上升沿延时 或者 一个下降沿延时),这里相当于设置死区时间为1us
	EPwm6Regs.DBFED = 150;
	EPwm6Regs.DBRED = 150;

	//6、初始化事件触发模块
	EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;   //计数值为0时
	EPwm6Regs.ETSEL.bit.INTEN = 1;              //使能中断
	EPwm6Regs.ETPS.bit.INTPRD = ET_1ST;         //设置当事件产生几次时,触发中断

	//7、使能时基计数器时钟
	EALLOW;
	SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
	EDIS;
}

#else
//上下计数模式:主频为150MHz,周期值设置为1500,即理论一个周期有10us,这里上下计数仅仅设置一个CMP比较值,向上计数到最大值时为1500,再由1500向下计数到0,这里才算计数完一次
//设置等于CMP比较值且向上计数时输出高电平,等于CMP比较值且向下计数时输出低电平,即所得占空比为50%,周期为 20us,频率为50KHz
void EPwmInit(void)
{
    //1、使能ePWM外设时钟,及失能时基模块时钟,这里在mian函数InitSysCtrl()中完成

    //2、配置对应的GPIO
    InitEPwm6Gpio();

    //3、初始化时基模块TB
    //TB模块用来产生一个时基信号TBCLK,TBCLK通过系统时钟SYSCLKOUT传递过来,同时还需要通过两个时钟分频器进行分频(HSPCLKDIV和CLKDIV)

    //关闭时钟同步输入
    EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
    //关闭相位使能
    EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;
    //如果打开时钟同步功能和相位使能功能,那么TBPHS设置的值就会被加载到TBCTR(计数值)里
    EPwm6Regs.TBPHS.half.TBPHS = 0;

    //初始计数值
    EPwm6Regs.TBCTR = 0x0000;

    //设置计数方式:上下计数模式
    EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;

    //最高主频 150M
    //时钟分频由两位控制,这里一分频 TBCLK = SYSCLKOUT(HSPCLKDIV * CLKDIV)
    //这里相当于不分频,TBCLK为 150MHz,计数150次,需要1us
    EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
    EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1;

    //周期设置为1500,相当于计数1500次,需要10us,周期为10us

    //PWM周期 1500/TBCLK,这里有影子寄存器和活动寄存器
    //当使用影子寄存器更新周期值时,当发生某一个特定时刻时更新
    //当使用活动寄存器时,会立马更新
    EPwm6Regs.TBPRD = 1500;

    //4、初始化比较模块CC
    //影子寄存器模式设置,可以配置为影子寄存器和活动寄存器
    //当配置为活动寄存器时,设置的CMPA值立马起作用
    //当配置为影子寄存器时,当发生某一个特定时刻时,影子寄存器的值传入到活动寄存器中
    EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

    //要配置影子寄存器工作,需要配置LOADAMODE,当CTR为0时加载
    EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    //设置比较值

    EPwm6Regs.CMPA.half.CMPA = 750;
    EPwm6Regs.CMPB = 750;

    //5、初始化动作限定模块AQ

    //AQ_NO_ACTION  无动作
    //AQ_CLEAR      置低
    //AQ_SET        置高
    //AQ_TOGGLE     电平翻转

    //ZRO   当计数值 == 0
    //PRD   当计数值 == 周期值
    //CAU   向上计数时,计数值 == CMPA
    //CAD   向下计数时,计数值 == CMPA
    //CBU   向上计数时,计数值 == CMPB
    //CBD   向下计数时,计数值 == CMPB

    EPwm6Regs.AQCTLA.bit.CAU = AQ_SET;
    EPwm6Regs.AQCTLA.bit.CAD = AQ_CLEAR;

    EPwm6Regs.AQCTLB.bit.CBU = AQ_SET;
    EPwm6Regs.AQCTLB.bit.CBD = AQ_CLEAR;

    //5、死区
//    DBA_ALL         0x0   ePWMA作为双边延时输入源
//    DBB_RED_DBA_FED 0x1   ePWMB是上升延时输入源 ,epwmA是下降延时输入源
//    DBA_RED_DBB_FED 0x2   ePWMA是上升延时输入源 ,epwmB是下降延时输入源
//    DBB_ALL         0x3   ePWMB是双边沿延时输入源
    EPwm6Regs.DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;
//    DB_ACTV_HI      0x0
//    DB_ACTV_LOC     0x1   //极性选择:A不翻转,B翻转
//    DB_ACTV_HIC     0x2   //极性选择:A翻转,B不翻转
//    DB_ACTV_LO      0x3
    EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;   //极性选择:A不翻转,B翻转
//    DB_DISABLE      0x0   ePWMA 和 ePWMB 都不经过死区
//    DBA_ENABLE      0x1   禁止上升沿延时,使能下降沿延时(一个过下降沿死区,一个直接输出)
//    DBB_ENABLE      0x2   禁止下降沿延时,使能上升沿延时(一个过上升沿死区,一个直接输出)
//    DB_FULL_ENABLE  0x3   ePWMA 和 ePWMB 都经过死区
    EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;

    // 向上模式计数 和 向下模式计数 的周期是 上下计数的2倍
    //类似于,上下计数模式实际是有 两个周期,死区设置中,是将死区时间分给了这两个周期,
    //一个pwm波周期有一个死区时间,这里相当于设置死区时间为1us
    EPwm6Regs.DBFED = 150;
    EPwm6Regs.DBRED = 150;

    //6、初始化事件触发模块
    EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;   //计数值为0时
    EPwm6Regs.ETSEL.bit.INTEN = 1;              //使能中断
    EPwm6Regs.ETPS.bit.INTPRD = ET_1ST;         //设置当事件产生几次时,触发中断

    //7、使能时基计数器时钟
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;
}
#endif


//设置占空比
void EPwm6A_SetCompare(Uint16 Val)
{
	EPwm6Regs.CMPA.half.CMPA = Val;
}

//设置占空比
void EPwm6B_SetCompare(Uint16 Val)
{
	EPwm6Regs.CMPB = Val;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值