你好!
1、我使用F23379D伺服代码(路径:C:\ti\controlSUITE\development_kits\TMDSIDDK_v2.0\IDDK_PM_Servo_F2837x_v2_00_00_00),PWM输出是高电平输出(配置:(*ePWM[chanel]).DBCTL.bit.POLSEL = DB_ACTV_HIC;),使用SD_CURRENT_SENSE才电流模式,电机可以正常运行,电流采样是正确的;当电机不接电机时,电流采样是0;
2、由于换成新板子,需要将输出PWM逻辑改成低电平有效(配置:(*ePWM[chanel]).DBCTL.bit.POLSEL = DB_ACTV_LOC;;),使用SD_CURRENT_SENSE采电流模式,当电机不接电机时,能采到电流,但是电流采样不是0,采集到的电流有较大跳变现象,所以怀疑SDFM才电流与PWM输出没有同步,该如何改动?
3、以下代码是原来PWM高电平输出,正确代码,标记处是修改位置,请问还有哪里需要改动?
代码如下:
(注:原来是DB_ACTV_HIC高电平输出有效,现在改成DB_ACTV_LOC电平输出有效)
void HOS_PWM_Int()
{
volatile int16 temp;
// Initialize PWM module 初始化PWM模块
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; //时钟同步清零
HOS_PWMChanelUpDwnCntCnf(1,INV_PWM_TICKS,200);
HOS_PWMChanelUpDwnCntCnf(2,INV_PWM_TICKS,200);
HOS_PWMChanelUpDwnCntCnf(3,INV_PWM_TICKS,200);
HOS_PWMChanelUpCntCnf(4,SDFM_TICKS); //Sigma接口
EPwm4Regs.CMPA.bit.CMPA=EPwm4Regs.TBPRD>>1;//周期
// ********************************************************************
//PWM 11 for syncing up the SD filter windows with motor control PWMs
// ********************************************************************
//==================SD时钟设置=======================================
HOS_PWMChanelUpCntCnf(11,INV_PWM_TICKS); //同步SD滤波
// configure 2 and 3 as slaves
/*==================估计是电流采样同步使用=======================================*/
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; //同步输出选择
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; //相加载使能
EPwm2Regs.TBPHS.bit.TBPHS = 2; //相位偏移寄存器
EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP; //相位方向
EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; //相加载使能
EPwm3Regs.TBPHS.bit.TBPHS = 2; //相位偏移寄存器
EPwm3Regs.TBCTL.bit.PHSDIR = TB_UP; //相位方向
//==================Sigma同步=======================================
EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; //Sigma接口
//==================EPWM11 SD同步=======================================
EPwm11Regs.TBCTL.bit.PHSEN = TB_ENABLE; //SD
EPwm11Regs.TBPHS.bit.TBPHS = 2;
EPwm11Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm11Regs.CMPC = EPwm11Regs.TBPRD – SDFM_TICKS*(OSR_RATE+1)*3/2;//周期
EPwm11Regs.CMPA.bit.CMPA = (SDFM_TICKS*(OSR_RATE+1)*3/2) + 500; // 500 is arbitrary
EPwm11Regs.CMPD = 0;
// ***********************************
// Set up GPIOs for PWM functions
// **************************************
InitEPwm1Gpio();/
InitEPwm2Gpio();//
InitEPwm3Gpio();//C相PWM管
InitEPwm4Gpio();//clk for Sigma Delta
EDIS;
EALLOW;
EPwm11Regs.ETSEL.bit.INTSEL= ET_CTRU_CMPA ;
EPwm11Regs.ETSEL.bit.INTEN = 1;// Enable INT EPWMxINTn 使能
EPwm11Regs.ETPS.bit.INTPRD = ET_1ST;
EDIS;
PhaseCurrentHwInit(); /
BusVoltageDetectInit();/
Init_Val();
//TODO 编码器
AbsEncoderInit();
// TODO Feedbacks OFFSET Calibration Routine
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
offset_SDFM1 = 0;
offset_SDFM2 = 0;
for (OffsetCalCounter=0; OffsetCalCounter<20000; )
{
if(EPwm11Regs.ETFLG.bit.INT==1)//中断状态标志位
{
if(OffsetCalCounter>1000)
{
offset_SDFM1 = K1*offset_SDFM1 + K2*(temp=SDFM1_READ_FILTER1_DATA_16BIT)*SD_PU_SCALE_FACTOR;
offset_SDFM2 = K1*offset_SDFM2 + K2*(temp=SDFM1_READ_FILTER2_DATA_16BIT)*SD_PU_SCALE_FACTOR;
}
EPwm11Regs.ETCLR.bit.INT=1;//清除中断标志位
OffsetCalCounter++;
}
}
//TODO ISR Mapping
// ****************************************************************************
// ****************************************************************************
EALLOW;
//PWM11 INT is used to trigger Motor Control ISR
EPwm11Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPA;
EPwm11Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm11Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on every event
PieVectTable.EPWM11_INT = &MotorControlISR;
PieCtrlRegs.PIEIER3.bit.INTx11 = 1; // Enable PWM11INT in PIE group 3
EPwm11Regs.ETCLR.bit.INT=1;
IER = 0x185;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
EDIS;
}
//========================================================================
//TODO
void HOS_PWMChanelUpDwnCntCnf(uint16 chanel, uint16 period, uint16 dead_band)
{
EALLOW;
// Time Base SubModule Registers
(*ePWM[chanel]).TBCTL.bit.PRDLD = TB_IMMEDIATE; // set Immediate load
(*ePWM[chanel]).TBPRD = period / 2; // PWM frequency = 1 / period
(*ePWM[chanel]).TBPHS.bit.TBPHS = 0; //set time base phase high
(*ePWM[chanel]).TBCTR = 0; //Time Base Counter
(*ePWM[chanel]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
(*ePWM[chanel]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[chanel]).TBCTL.bit.CLKDIV = TB_DIV1;
(*ePWM[chanel]).TBCTL.bit.PHSEN = TB_DISABLE;
(*ePWM[chanel]).TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //sync "down-stream"
// Counter Compare Submodule Registers
(*ePWM[chanel]).CMPA.bit.CMPA = 0; // set duty 0% initially
(*ePWM[chanel]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*ePWM[chanel]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
// Action Qualifier SubModule Registers
(*ePWM[chanel]).AQCTLA.bit.CAU = AQ_CLEAR; //向上比较
(*ePWM[chanel]).AQCTLA.bit.CAD = AQ_SET; //向下比较
// Active high complementary PWMs – Set up the deadband 设置死区
(*ePWM[chanel]).DBCTL.bit.IN_MODE = DBA_ALL; //死区输入选择模式控制
(*ePWM[chanel]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; //死区输出模式控制
(*ePWM[chanel]).DBCTL.bit.POLSEL = DB_ACTV_LOC;//DB_ACTV_HIC;(注:原来是DB_ACTV_HIC高电平输出有效,现在改成DB_ACTV_LOC电平输出有效)
(*ePWM[chanel]).DBRED.all = dead_band; //死区发生器上升沿延时计数寄存器 设置上升沿死区
(*ePWM[chanel]).DBFED.all = dead_band; //死区发生器下降沿延时计数寄存器 设置下降沿死区
EDIS;
}
//TODO
void HOS_PWMChanelUpCntCnf(uint16 chanel, uint16 period)
{
EALLOW;
// Time Base SubModule Registers
(*ePWM[chanel]).TBCTL.bit.PRDLD = TB_IMMEDIATE; // set Immediate load
(*ePWM[chanel]).TBPRD = period-1; // PWM frequency = 1 / period 周期
(*ePWM[chanel]).TBPHS.bit.TBPHS = 0;
(*ePWM[chanel]).TBCTR = 0;
(*ePWM[chanel]).TBCTL.bit.CTRMODE = TB_COUNT_UP;
(*ePWM[chanel]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[chanel]).TBCTL.bit.CLKDIV = TB_DIV1;
(*ePWM[chanel]).TBCTL.bit.PHSEN = TB_DISABLE; //相负载使
(*ePWM[chanel]).TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // sync "down-stream" 同步输出选择
// Counter Compare Submodule Registers 比较寄存器计数器模块
(*ePWM[chanel]).CMPA.bit.CMPA = 0; // set duty 0% initially 设置初始化占空比0
(*ePWM[chanel]).CMPCTL.bit.SHDWAMODE = CC_SHADOW; //比较寄存器块操作模式
(*ePWM[chanel]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
// Action Qualifier SubModule Registers
(*ePWM[chanel]).AQCTLA.bit.CAU = AQ_CLEAR; //比较器A寄存器向上计数
(*ePWM[chanel]).AQCTLA.bit.ZRO = AQ_SET; //动作计数器为零
// Active high complementary PWMs – Set up the deadband 设置死区
(*ePWM[chanel]).DBCTL.bit.IN_MODE = DBA_ALL;
(*ePWM[chanel]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
(*ePWM[chanel]).DBCTL.bit.POLSEL = DB_ACTV_LOC;//DB_ACTV_HIC; (注:原来是DB_ACTV_HIC高电平输出有效,现在改成DB_ACTV_LOC电平输出有效)
(*ePWM[chanel]).DBRED.all = 0; //死区发生器上升沿
(*ePWM[chanel]).DBFED.all = 0; //死区发生器下降沿
EDIS;
}
//TODO Motor Control ISR
interrupt void MotorControlISR(void)
{
GPIO_WritePin(59 , 0);
EINT;
MotorControl_ISR();
//dx DLOG_4CH_F_FUNC(&dlog_4ch1);
EPwm11Regs.ETCLR.bit.INT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
GPIO_WritePin(59 , 1);
}// MainISR Ends Here
以上是配置PWM和Sigmadelt 同步采样电流;由于原来输出PWM都是高有效;现在改成低有效后,sigma delta filter module 采样电流就与PWM不同步了,不知道如何改,才可以同步采电流?多谢
Yonglu Hu:
您好!
我也遇到了这个问题,请问您解决这个问题了吗?实现电流同步采样了吗?
你好!
1、我使用F23379D伺服代码(路径:C:\ti\controlSUITE\development_kits\TMDSIDDK_v2.0\IDDK_PM_Servo_F2837x_v2_00_00_00),PWM输出是高电平输出(配置:(*ePWM[chanel]).DBCTL.bit.POLSEL = DB_ACTV_HIC;),使用SD_CURRENT_SENSE才电流模式,电机可以正常运行,电流采样是正确的;当电机不接电机时,电流采样是0;
2、由于换成新板子,需要将输出PWM逻辑改成低电平有效(配置:(*ePWM[chanel]).DBCTL.bit.POLSEL = DB_ACTV_LOC;;),使用SD_CURRENT_SENSE采电流模式,当电机不接电机时,能采到电流,但是电流采样不是0,采集到的电流有较大跳变现象,所以怀疑SDFM才电流与PWM输出没有同步,该如何改动?
3、以下代码是原来PWM高电平输出,正确代码,标记处是修改位置,请问还有哪里需要改动?
代码如下:
(注:原来是DB_ACTV_HIC高电平输出有效,现在改成DB_ACTV_LOC电平输出有效)
void HOS_PWM_Int()
{
volatile int16 temp;
// Initialize PWM module 初始化PWM模块
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; //时钟同步清零
HOS_PWMChanelUpDwnCntCnf(1,INV_PWM_TICKS,200);
HOS_PWMChanelUpDwnCntCnf(2,INV_PWM_TICKS,200);
HOS_PWMChanelUpDwnCntCnf(3,INV_PWM_TICKS,200);
HOS_PWMChanelUpCntCnf(4,SDFM_TICKS); //Sigma接口
EPwm4Regs.CMPA.bit.CMPA=EPwm4Regs.TBPRD>>1;//周期
// ********************************************************************
//PWM 11 for syncing up the SD filter windows with motor control PWMs
// ********************************************************************
//==================SD时钟设置=======================================
HOS_PWMChanelUpCntCnf(11,INV_PWM_TICKS); //同步SD滤波
// configure 2 and 3 as slaves
/*==================估计是电流采样同步使用=======================================*/
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; //同步输出选择
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; //相加载使能
EPwm2Regs.TBPHS.bit.TBPHS = 2; //相位偏移寄存器
EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP; //相位方向
EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; //相加载使能
EPwm3Regs.TBPHS.bit.TBPHS = 2; //相位偏移寄存器
EPwm3Regs.TBCTL.bit.PHSDIR = TB_UP; //相位方向
//==================Sigma同步=======================================
EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; //Sigma接口
//==================EPWM11 SD同步=======================================
EPwm11Regs.TBCTL.bit.PHSEN = TB_ENABLE; //SD
EPwm11Regs.TBPHS.bit.TBPHS = 2;
EPwm11Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm11Regs.CMPC = EPwm11Regs.TBPRD – SDFM_TICKS*(OSR_RATE+1)*3/2;//周期
EPwm11Regs.CMPA.bit.CMPA = (SDFM_TICKS*(OSR_RATE+1)*3/2) + 500; // 500 is arbitrary
EPwm11Regs.CMPD = 0;
// ***********************************
// Set up GPIOs for PWM functions
// **************************************
InitEPwm1Gpio();/
InitEPwm2Gpio();//
InitEPwm3Gpio();//C相PWM管
InitEPwm4Gpio();//clk for Sigma Delta
EDIS;
EALLOW;
EPwm11Regs.ETSEL.bit.INTSEL= ET_CTRU_CMPA ;
EPwm11Regs.ETSEL.bit.INTEN = 1;// Enable INT EPWMxINTn 使能
EPwm11Regs.ETPS.bit.INTPRD = ET_1ST;
EDIS;
PhaseCurrentHwInit(); /
BusVoltageDetectInit();/
Init_Val();
//TODO 编码器
AbsEncoderInit();
// TODO Feedbacks OFFSET Calibration Routine
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
offset_SDFM1 = 0;
offset_SDFM2 = 0;
for (OffsetCalCounter=0; OffsetCalCounter<20000; )
{
if(EPwm11Regs.ETFLG.bit.INT==1)//中断状态标志位
{
if(OffsetCalCounter>1000)
{
offset_SDFM1 = K1*offset_SDFM1 + K2*(temp=SDFM1_READ_FILTER1_DATA_16BIT)*SD_PU_SCALE_FACTOR;
offset_SDFM2 = K1*offset_SDFM2 + K2*(temp=SDFM1_READ_FILTER2_DATA_16BIT)*SD_PU_SCALE_FACTOR;
}
EPwm11Regs.ETCLR.bit.INT=1;//清除中断标志位
OffsetCalCounter++;
}
}
//TODO ISR Mapping
// ****************************************************************************
// ****************************************************************************
EALLOW;
//PWM11 INT is used to trigger Motor Control ISR
EPwm11Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPA;
EPwm11Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm11Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on every event
PieVectTable.EPWM11_INT = &MotorControlISR;
PieCtrlRegs.PIEIER3.bit.INTx11 = 1; // Enable PWM11INT in PIE group 3
EPwm11Regs.ETCLR.bit.INT=1;
IER = 0x185;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
EDIS;
}
//========================================================================
//TODO
void HOS_PWMChanelUpDwnCntCnf(uint16 chanel, uint16 period, uint16 dead_band)
{
EALLOW;
// Time Base SubModule Registers
(*ePWM[chanel]).TBCTL.bit.PRDLD = TB_IMMEDIATE; // set Immediate load
(*ePWM[chanel]).TBPRD = period / 2; // PWM frequency = 1 / period
(*ePWM[chanel]).TBPHS.bit.TBPHS = 0; //set time base phase high
(*ePWM[chanel]).TBCTR = 0; //Time Base Counter
(*ePWM[chanel]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
(*ePWM[chanel]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[chanel]).TBCTL.bit.CLKDIV = TB_DIV1;
(*ePWM[chanel]).TBCTL.bit.PHSEN = TB_DISABLE;
(*ePWM[chanel]).TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //sync "down-stream"
// Counter Compare Submodule Registers
(*ePWM[chanel]).CMPA.bit.CMPA = 0; // set duty 0% initially
(*ePWM[chanel]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*ePWM[chanel]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
// Action Qualifier SubModule Registers
(*ePWM[chanel]).AQCTLA.bit.CAU = AQ_CLEAR; //向上比较
(*ePWM[chanel]).AQCTLA.bit.CAD = AQ_SET; //向下比较
// Active high complementary PWMs – Set up the deadband 设置死区
(*ePWM[chanel]).DBCTL.bit.IN_MODE = DBA_ALL; //死区输入选择模式控制
(*ePWM[chanel]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; //死区输出模式控制
(*ePWM[chanel]).DBCTL.bit.POLSEL = DB_ACTV_LOC;//DB_ACTV_HIC;(注:原来是DB_ACTV_HIC高电平输出有效,现在改成DB_ACTV_LOC电平输出有效)
(*ePWM[chanel]).DBRED.all = dead_band; //死区发生器上升沿延时计数寄存器 设置上升沿死区
(*ePWM[chanel]).DBFED.all = dead_band; //死区发生器下降沿延时计数寄存器 设置下降沿死区
EDIS;
}
//TODO
void HOS_PWMChanelUpCntCnf(uint16 chanel, uint16 period)
{
EALLOW;
// Time Base SubModule Registers
(*ePWM[chanel]).TBCTL.bit.PRDLD = TB_IMMEDIATE; // set Immediate load
(*ePWM[chanel]).TBPRD = period-1; // PWM frequency = 1 / period 周期
(*ePWM[chanel]).TBPHS.bit.TBPHS = 0;
(*ePWM[chanel]).TBCTR = 0;
(*ePWM[chanel]).TBCTL.bit.CTRMODE = TB_COUNT_UP;
(*ePWM[chanel]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[chanel]).TBCTL.bit.CLKDIV = TB_DIV1;
(*ePWM[chanel]).TBCTL.bit.PHSEN = TB_DISABLE; //相负载使
(*ePWM[chanel]).TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // sync "down-stream" 同步输出选择
// Counter Compare Submodule Registers 比较寄存器计数器模块
(*ePWM[chanel]).CMPA.bit.CMPA = 0; // set duty 0% initially 设置初始化占空比0
(*ePWM[chanel]).CMPCTL.bit.SHDWAMODE = CC_SHADOW; //比较寄存器块操作模式
(*ePWM[chanel]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
// Action Qualifier SubModule Registers
(*ePWM[chanel]).AQCTLA.bit.CAU = AQ_CLEAR; //比较器A寄存器向上计数
(*ePWM[chanel]).AQCTLA.bit.ZRO = AQ_SET; //动作计数器为零
// Active high complementary PWMs – Set up the deadband 设置死区
(*ePWM[chanel]).DBCTL.bit.IN_MODE = DBA_ALL;
(*ePWM[chanel]).DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
(*ePWM[chanel]).DBCTL.bit.POLSEL = DB_ACTV_LOC;//DB_ACTV_HIC; (注:原来是DB_ACTV_HIC高电平输出有效,现在改成DB_ACTV_LOC电平输出有效)
(*ePWM[chanel]).DBRED.all = 0; //死区发生器上升沿
(*ePWM[chanel]).DBFED.all = 0; //死区发生器下降沿
EDIS;
}
//TODO Motor Control ISR
interrupt void MotorControlISR(void)
{
GPIO_WritePin(59 , 0);
EINT;
MotorControl_ISR();
//dx DLOG_4CH_F_FUNC(&dlog_4ch1);
EPwm11Regs.ETCLR.bit.INT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
GPIO_WritePin(59 , 1);
}// MainISR Ends Here
以上是配置PWM和Sigmadelt 同步采样电流;由于原来输出PWM都是高有效;现在改成低有效后,sigma delta filter module 采样电流就与PWM不同步了,不知道如何改,才可以同步采电流?多谢
Jordan Zhou:感觉除了修改高低电平输出外,是否也修改了其他内容?
SDFM相关的内容比较多,按照你描述的现象,有可能你修改了CMPC或者CMPD相关的EVENT,导致filter出问题了。
可以尝试将OSR降低来试一试,看看没有电流的情况下,是否真的采集到了数据,并且数据是什么。