Other Parts Discussed in Thread: C2000WARE
求助TI支持团队,
最近在用TMS320F28069F做一个电源,CLA部分进行AD采集计算、运行3个PI控制器、输出PWM这3个操作。
调试发现奇怪现象:
1. 连接仿真器下载程序后,CLA代码能正常运行;
2. 断开仿真器重新上电后,CLA部分PI控制代码不能正常运行,输出结果不正确,只是部分代码不正常运行,因为AD采集量是正常刷新的;
3. 手动按下复位按钮进行复位后,CLA代码又能正常运行了,输出结果也是正常的;
4. 上电前就按住复位按钮,上电后再松开,CLA部分PI控制代码不能正常运行,再按下复位按钮,CLA代码又可以运行。
总结一下就是,初始上电CLA部分代码不运行,手动复位后又可以正常运行;而且不是全部CLA代码不运行,只是那一小段,因为数据采集是正常刷新的。
CLA由PWM2触发,中断触发周期是10us,测量了CLA代码执行时间约5.6us,代码是能够执行的完的。
CLA程序是仿照例程修改的,不过我的程序是下载到flash的,而例程都是下载到内存中,不知道是不是这里出现了问题。
这个问题困扰我几天了,想了各种办法也没有解决。
大家有没有遇到类似情况的,应该怎么解决?
或者我应该检查哪个部分,有什么检查思路或者参考例程吗?
以下是部分相关代码:
CLA初始化部分(没用CLA执行完中断,所以屏蔽掉了PIE部分)
void ClaInit(void)
{
#ifdef FLASH
//Copy over the CLA code(if running in standalone mode from FLASH)
memcpy(&Cla1funcsRunStart, &Cla1funcsLoadStart, (Uint32)&Cla1funcsLoadSize);
//Copy over the CLA math tables(if running in standalone mode from FLASH and using the CLAMath Library)
memcpy(&Cla1mathTablesRunStart, &Cla1mathTablesLoadStart, (Uint32)&Cla1mathTablesLoadSize);
#endif //FLASH
EALLOW;
// Assign user defined ISR to the PIE vector table
PieVectTable.CLA1_INT1 = &cla1_task1_isr;
PieVectTable.CLA1_INT2 = &cla1_task2_isr;
PieVectTable.CLA1_INT3 = &cla1_task3_isr;
PieVectTable.CLA1_INT4 = &cla1_task4_isr;
PieVectTable.CLA1_INT5 = &cla1_task5_isr;
PieVectTable.CLA1_INT6 = &cla1_task6_isr;
PieVectTable.CLA1_INT7 = &cla1_task7_isr;
PieVectTable.CLA1_INT8 = &cla1_task8_isr;
// Compute all CLA task vectors
Cla1Regs.MVECT1 = (Uint16)((Uint32)&Cla1Task1 -(Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT2 = (Uint16)((Uint32)&Cla1Task2 -(Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT3 = (Uint16)((Uint32)&Cla1Task3 -(Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT4 = (Uint16)((Uint32)&Cla1Task4 -(Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT5 = (Uint16)((Uint32)&Cla1Task5 -(Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT6 = (Uint16)((Uint32)&Cla1Task6 -(Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT7 = (Uint16)((Uint32)&Cla1Task7 -(Uint32)&Cla1Prog_Start);
Cla1Regs.MVECT8 = (Uint16)((Uint32)&Cla1Task8 -(Uint32)&Cla1Prog_Start);
// Mapping CLA tasks
Cla1Regs.MPISRCSEL1.bit.PERINT1SEL = CLA_INT1_NONE;
Cla1Regs.MPISRCSEL1.bit.PERINT2SEL = CLA_INT2_EPWM2INT;//CLA_INT2_NONE;
Cla1Regs.MPISRCSEL1.bit.PERINT3SEL = CLA_INT3_NONE;
Cla1Regs.MPISRCSEL1.bit.PERINT4SEL = CLA_INT4_NONE;
Cla1Regs.MPISRCSEL1.bit.PERINT5SEL = CLA_INT5_NONE;
Cla1Regs.MPISRCSEL1.bit.PERINT6SEL = CLA_INT6_NONE;
Cla1Regs.MPISRCSEL1.bit.PERINT7SEL = CLA_INT7_NONE;
Cla1Regs.MPISRCSEL1.bit.PERINT8SEL = CLA_INT8_NONE;
Cla1Regs.MIER.bit.INT1 = CLA_INT_ENABLE;
Cla1Regs.MIER.bit.INT2 = CLA_INT_ENABLE;
Cla1Regs.MCTL.bit.IACKE = CLA_IACK_ENABLE;
// Switch the CLA program space to the CLA and enable software forcing
// Also switch over CLA data ram 0,1 and 2
// CAUTION: The RAMxCPUE bits can only be enabled by writing to the register
// and not the individual bit field. Furthermore, the status of these bitfields
// is not reflected in either the watch or register views - they always read as
// zeros. This is a known bug and the user is advised to test CPU accessibilty
// first before proceeding
Cla1Regs.MMEMCFG.all = CLA_PROG_ENABLE|CLARAM0_ENABLE|CLARAM1_ENABLE|CLARAM2_ENABLE|CLA_RAM1CPUE;
// Enable CLA interrupts at the group and subgroup levels
// PieCtrlRegs.PIEIER11.bit.INTx2 = 1;
// IER |= (M_INT11 );
EDIS;
}
shared_data.c
//Task 2 (C) Variables #pragma DATA_SECTION(xInput,"CpuToCla1MsgRAM"); long xInput; #pragma DATA_SECTION(xResult,"Cla1ToCpuMsgRAM"); long xResult; #pragma DATA_SECTION(DutyBuck_CLA,"CpuToCla1MsgRAM") volatile float32 DutyBuck_CLA; #pragma DATA_SECTION(DutyBoost_CLA,"Cla1DataRam1") volatile float32 DutyBoost_CLA; #pragma DATA_SECTION(DutyBoost_CLA2CPU,"Cla1ToCpuMsgRAM"); volatile float32 DutyBoost_CLA2CPU; #pragma DATA_SECTION(Ipv_Read_CLA,"Cla1DataRam1") #pragma DATA_SECTION(Vpv_Read_CLA,"Cla1DataRam1") #pragma DATA_SECTION(Iout_Read_CLA,"Cla1DataRam1") #pragma DATA_SECTION(Vout_Read_CLA,"Cla1DataRam1") volatile float32 Ipv_Read_CLA,Vpv_Read_CLA,Iout_Read_CLA,Vout_Read_CLA; #pragma DATA_SECTION(Vpv_Ref_CLA,"CpuToCla1MsgRAM") volatile float32 Vpv_Ref_CLA; #pragma DATA_SECTION(Vout_Ref_CLA,"CpuToCla1MsgRAM") volatile float32 Vout_Ref_CLA; #pragma DATA_SECTION(Iout_Ref_DC_CLA,"Cla1DataRam1") #pragma DATA_SECTION(Iout_Ref_CL_CLA,"Cla1DataRam1") #pragma DATA_SECTION(Iout_Ref_MPPT_CLA,"Cla1DataRam1") volatile float32 Iout_Ref_DC_CLA,Iout_Ref_CL_CLA,Iout_Ref_MPPT_CLA; #pragma DATA_SECTION(MATH_EMAVG_CLA_Ipv, "Cla1ToCpuMsgRAM") MATH_EMAVG_CLA MATH_EMAVG_CLA_Ipv; #pragma DATA_SECTION(MATH_EMAVG_CLA_Vpv, "Cla1ToCpuMsgRAM") MATH_EMAVG_CLA MATH_EMAVG_CLA_Vpv; #pragma DATA_SECTION(MATH_EMAVG_CLA_Iout, "Cla1ToCpuMsgRAM") MATH_EMAVG_CLA MATH_EMAVG_CLA_Iout; #pragma DATA_SECTION(MATH_EMAVG_CLA_Vout, "Cla1ToCpuMsgRAM") MATH_EMAVG_CLA MATH_EMAVG_CLA_Vout; #pragma DATA_SECTION(CNTL_PI_CLA_Vpv, "Cla1DataRam1") volatile CNTL_PI_CLA CNTL_PI_CLA_Vpv; #pragma DATA_SECTION(CNTL_PI_CLA_Vout, "Cla1DataRam1") volatile CNTL_PI_CLA CNTL_PI_CLA_Vout; #pragma DATA_SECTION(CNTL_PI_CLA_Iout, "Cla1DataRam1") volatile CNTL_PI_CLA CNTL_PI_CLA_Iout; #pragma DATA_SECTION(Vout_Ref_CLA2CPU,"Cla1ToCpuMsgRAM"); volatile float32 Vout_Ref_CLA2CPU; #pragma DATA_SECTION(Vout_Read_CLA2CPU,"Cla1ToCpuMsgRAM"); volatile float32 Vout_Read_CLA2CPU; #pragma DATA_SECTION(Iout_Ref_DC_CLA2CPU,"Cla1ToCpuMsgRAM"); volatile float32 Iout_Ref_DC_CLA2CPU;
shared.h
//Task 2 (C) Variables extern Uint16 G_WorkStatNow; extern long xInput; extern long xResult; extern volatile float32 DutyBuck_CLA; extern volatile float32 DutyBoost_CLA; extern volatile float32 DutyBoost_CLA2CPU; extern volatile float32 Ipv_Read_CLA,Vpv_Read_CLA,Iout_Read_CLA,Vout_Read_CLA; extern volatile float32 Vpv_Ref_CLA; extern volatile float32 Vout_Ref_CLA; extern volatile float32 Iout_Ref_DC_CLA,Iout_Ref_CL_CLA,Iout_Ref_MPPT_CLA; extern MATH_EMAVG_CLA MATH_EMAVG_CLA_Ipv; extern MATH_EMAVG_CLA MATH_EMAVG_CLA_Vpv; extern MATH_EMAVG_CLA MATH_EMAVG_CLA_Iout; extern MATH_EMAVG_CLA MATH_EMAVG_CLA_Vout; extern volatile CNTL_PI_CLA CNTL_PI_CLA_Vpv; extern volatile CNTL_PI_CLA CNTL_PI_CLA_Vout; extern volatile CNTL_PI_CLA CNTL_PI_CLA_Iout; extern volatile float32 Vout_Ref_CLA2CPU; extern volatile float32 Vout_Read_CLA2CPU; extern volatile float32 Iout_Ref_DC_CLA2CPU;
cla.cla 感觉运行不正常的是CNTL_PI_CLA_MACRO()函数
__interrupt void Cla1Task2 ( void )
{
Uint32 M_PeriodBuck,M_PeriodBoost;
// xResult=xInput;
Ipv_Read_CLA = (1-0.0384615)*Ipv_Read_CLA + 0.0384615*(Ipv_FB2)*0.000244140625;
Iout_Read_CLA = (1-0.3858695)*Iout_Read_CLA + 0.3858695*(Iout_FB2)*0.000244140625;//10kHz Low Pass
Vout_Read_CLA = (1-0.3858695)*Vout_Read_CLA + 0.3858695*(Vout_FB2)*0.000244140625;//10kHz Low Pass
Vpv_Read_CLA = (1-0.0384615)*Vpv_Read_CLA + 0.0384615*(Vpv_FB2)*0.000244140625;
if(Iout_Read_CLA<0){Iout_Read_CLA=0;}
if (Iout_Read_CLA<0.025) {EPwm2Regs.DBCTL.bit.OUT_MODE = DBA_ENABLE;}//Disable PWM out of EPWM2B,EPwm2Regs.DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;
else if (Iout_Read_CLA>0.05) {EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;}//Enable PWM out of EPWM2B,EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
//输入电压环PI
CNTL_PI_CLA_Vpv.Ref = Vpv_Ref_CLA;
CNTL_PI_CLA_Vpv.Fbk = Vpv_Read_CLA;
CNTL_PI_CLA_MACRO(CNTL_PI_CLA_Vpv);
Iout_Ref_MPPT_CLA = CNTL_PI_CLA_Vpv.Out;
//输出电压环PI
CNTL_PI_CLA_Vout.Ref = Vout_Ref_CLA;
CNTL_PI_CLA_Vout.Fbk = Vout_Read_CLA;
CNTL_PI_CLA_MACRO(CNTL_PI_CLA_Vout);
Iout_Ref_DC_CLA = CNTL_PI_CLA_Vout.Out;
Iout_Ref_CL_CLA = (Iout_Ref_MPPT_CLA<Iout_Ref_DC_CLA)?Iout_Ref_MPPT_CLA:Iout_Ref_DC_CLA;
//输出电流环PI
CNTL_PI_CLA_Iout.Ref = Iout_Ref_CL_CLA;//
CNTL_PI_CLA_Iout.Fbk = Iout_Read_CLA;
CNTL_PI_CLA_MACRO(CNTL_PI_CLA_Iout);
if((G_WorkStatNow==StartUpStat))//||)
{
DutyBoost_CLA = 0;//
}
else if((G_WorkStatNow==OnStat))
{
DutyBoost_CLA = CNTL_PI_CLA_Iout.Out;//
}
else{DutyBoost_CLA=0;}
M_PeriodBuck = EPwm1Regs.TBPRD * DutyBuck_CLA;
EPwm1Regs.CMPA.half.CMPA = M_PeriodBuck;
M_PeriodBoost = EPwm2Regs.TBPRD * DutyBoost_CLA;
EPwm2Regs.CMPA.half.CMPA = M_PeriodBoost;
xResult=G_WorkStatNow;
DutyBoost_CLA2CPU = DutyBoost_CLA;
Vout_Ref_CLA2CPU = CNTL_PI_CLA_Vout.Ref;
Vout_Read_CLA2CPU = CNTL_PI_CLA_Vout.Fbk;
Iout_Ref_DC_CLA2CPU = CNTL_PI_CLA_Vout.Out;
MATH_EMAVG_CLA_Ipv.In = (Ipv_Read_CLA);
MATH_EMAVG_CLA_MACRO(MATH_EMAVG_CLA_Ipv);
MATH_EMAVG_CLA_Vpv.In = (Vpv_Read_CLA);
MATH_EMAVG_CLA_MACRO(MATH_EMAVG_CLA_Vpv);
MATH_EMAVG_CLA_Iout.In = (Iout_Read_CLA);
MATH_EMAVG_CLA_MACRO(MATH_EMAVG_CLA_Iout);
MATH_EMAVG_CLA_Vout.In = (Vout_Read_CLA);
MATH_EMAVG_CLA_MACRO(MATH_EMAVG_CLA_Vout);
}
.cmd
_Cla1Prog_Start = _Cla1funcsRunStart;
-heap 0x400
-stack 0x400
// Define a size for the CLA scratchpad area that will be used
// by the CLA compiler for local symbols and temps
// Also force references to the special symbols that mark the
// scratchpad are.
CLA_SCRATCHPAD_SIZE = 0x100;
--undef_sym=__cla_scratchpad_end
--undef_sym=__cla_scratchpad_start
MEMORY
{
PAGE 0 : /* Program Memory */
/* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE1 for data allocation */
//RAML0 : origin = 0x008000, length = 0x000800 /* on-chip RAM block L0 */
//RAML1 : origin = 0x008800, length = 0x000400 /* on-chip RAM block L1 */
RAMM0 : origin = 0x000050, length = 0x0003B0
RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */
RAML3 : origin = 0x009000, length = 0x001000 /* on-chip RAM block L3 */
OTP : origin = 0x3D7800, length = 0x000400 /* on-chip OTP */
FLASHH : origin = 0x3D8000, length = 0x004000 /* on-chip FLASH */
FLASHG : origin = 0x3DC000, length = 0x004000 /* on-chip FLASH */
FLASHF : origin = 0x3E0000, length = 0x004000 /* on-chip FLASH */
FLASHE : origin = 0x3E4000, length = 0x004000 /* on-chip FLASH */
FLASHD : origin = 0x3E8000, length = 0x004000 /* on-chip FLASH */
FLASHC : origin = 0x3EC000, length = 0x004000 /* on-chip FLASH */
FLASHA : origin = 0x3F4000, length = 0x003F80 /* on-chip FLASH */
CSM_RSVD : origin = 0x3F7F80, length = 0x000076 /* Part of FLASHA. Program with all 0x0000 when CSM is in use. */
BEGIN : origin = 0x3F7FF6, length = 0x000002 /* Part of FLASHA. Used for "boot to Flash" bootloader mode. */
CSM_PWL_P0 : origin = 0x3F7FF8, length = 0x000008 /* Part of FLASHA. CSM password locations in FLASHA */
FPUTABLES : origin = 0x3FD860, length = 0x0006A0 /* FPU Tables in Boot ROM */
IQTABLES : origin = 0x3FDF00, length = 0x000B50 /* IQ Math Tables in Boot ROM */
IQTABLES2 : origin = 0x3FEA50, length = 0x00008C /* IQ Math Tables in Boot ROM */
IQTABLES3 : origin = 0x3FEADC, length = 0x0000AA /* IQ Math Tables in Boot ROM */
ROM : origin = 0x3FF3B0, length = 0x000C10 /* Boot ROM */
RESET : origin = 0x3FFFC0, length = 0x000002 /* part of boot ROM */
VECTORS : origin = 0x3FFFC2, length = 0x00003E /* part of boot ROM */
PAGE 1 : /* Data Memory */
/* Memory (RAM/FLASH/OTP) blocks can be moved to PAGE0 for program allocation */
/* Registers remain on PAGE1 */
BOOT_RSVD : origin = 0x000000, length = 0x000050 /* Part of M0, BOOT rom will use this for stack */
CLARAM0 : origin = 0x008800, length = 0x000400
CLARAM1 : origin = 0x008C00, length = 0x000400
CLARAM2 : origin = 0x008000, length = 0x000800
RAML4 : origin = 0x00A000, length = 0x002000 /* on-chip RAM block L4 */
RAML5_L8 : origin = 0x00C000, length = 0x008000
USB_RAM : origin = 0x040000, length = 0x000800 /* USB RAM */
FLASHB : origin = 0x3F0000, length = 0x004000 /* on-chip FLASH */
CLA_CPU_MSGRAM : origin = 0x001480, length = 0x000080 /* CLA-R/W, CPU-R message RAM */
CPU_CLA_MSGRAM : origin = 0x001500, length = 0x000080 /* CPU-R/W, CLA-R message RAM */
}
SECTIONS
{
/* Allocate program areas: */
.cinit : > FLASHA, PAGE = 0
.pinit : > FLASHA, PAGE = 0
.text : > FLASHA, PAGE = 0
codestart : > BEGIN, PAGE = 0
ramfuncs : LOAD = FLASHD,
RUN = RAMM0 | RAMM1,
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
LOAD_SIZE(_RamfuncsLoadSize),
PAGE = 0
{
--library=SFRA_F_Lib.lib<SFRA_F_INJECT.obj>
--library=SFRA_F_Lib.lib<SFRA_F_COLLECT.obj>
}
SFRA_F_Data : > RAML5_L8, ALIGN = 64, PAGE = 1//Add @190305 for SFRA support
csmpasswds : > CSM_PWL_P0, PAGE = 0
csm_rsvd : > CSM_RSVD, PAGE = 0
/* Allocate uninitalized data sections: */
.stack : > RAML4, PAGE = 1
.ebss : > RAML4, PAGE = 1
.esysmem : > RAML4, PAGE = 1
/* Initalized sections to go in Flash */
/* For SDFlash to program these, they must be allocated to page 0 */
.econst : > FLASHA, PAGE = 0
.switch : > FLASHA, PAGE = 0
.scratchpad : > CLARAM0, PAGE = 1
.bss_cla : > CLARAM0, PAGE = 1
.const_cla : > CLARAM0, PAGE = 1
/* Allocate IQ math areas: */
IQmath : > FLASHA, PAGE = 0 /* Math Code */
IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD
/* Allocate FPU math areas: */
FPUmathTables : > FPUTABLES, PAGE = 0, TYPE = NOLOAD
/*CLA specifi sections */
Cla1Prog : LOAD = FLASHD,
RUN = RAML3,
LOAD_START(_Cla1funcsLoadStart),
LOAD_SIZE(_Cla1funcsLoadSize),
LOAD_END(_Cla1funcsLoadEnd),
RUN_START(_Cla1funcsRunStart),
RUN_SIZE(_Cla1funcsRunSize),
RUN_END(_Cla1funcsRunEnd),
PAGE = 0, ALIGN(4)
Cla1ToCpuMsgRAM : > CLA_CPU_MSGRAM, PAGE = 1
CpuToCla1MsgRAM : > CPU_CLA_MSGRAM, PAGE = 1
Cla1DataRam0 : > CLARAM0, PAGE = 1
Cla1DataRam1 : > CLARAM1, PAGE = 1
Cla1DataRam2 : > CLARAM2, PAGE = 1
CLA1mathTables : > CLARAM1,
LOAD_START(_Cla1mathTablesLoadStart),
LOAD_END(_Cla1mathTablesLoadEnd),
LOAD_SIZE(_Cla1mathTablesLoadSize),
RUN_START(_Cla1mathTablesRunStart),
PAGE = 1
// Must be allocated to memory the CLA has write access to
CLAscratch :
{ *.obj(CLAscratch)
. += CLA_SCRATCHPAD_SIZE;
*.obj(CLAscratch_end) } > CLARAM0,//RAML3,//
PAGE = 1
/* .reset is a standard section used by the compiler. It contains the */
/* the address of the start of _c_int00 for C Code. /*
/* When using the boot ROM this section and the CPU vector */
/* table is not needed. Thus the default type is set here to */
/* DSECT */
.reset : > RESET, PAGE = 0, TYPE = DSECT
vectors : > VECTORS, PAGE = 0, TYPE = DSECT
DLOG : > RAML5_L8, PAGE = 1//Add @190305
SINTBL : > FLASHB, PAGE = 1//Add @190305
}

