This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

FLASH调试和RAM调试的问题

Other Parts Discussed in Thread: CONTROLSUITE

   写了一个PWM周期触发ADC转换,然后进入ADC中断的程序,发现在FLASH和RAM中运行的时序差异很大,

下载到FLASH中   运行完全不能满足需求,请教一下TI的工程师,如何解决:

1、在RAM中调试的PWM波形(使用28335_RAM_lnk.cmd):

2、使用FLASH调试(F28335.cmd)

PWM频率设置的是50khz,50%占空比

不但时序发生了很大的变化,PWM波形也有很大偏差,请问这究竟如何解决?

  • 请问能否确定PWM在初始化完之后,没有在其他地方修改PWM比较寄存器的值?

    当使用FLASH的CMD的时候,要注意的一点就是要对FLASH进行初始化,即Initflash()。

    参考例程:C:\ti\controlSUITE\device_support\f2833x\v133\DSP2833x_examples_ccsv4\flash_f28335

    Eric

  • Eric Ma:

           感谢回复!

           我确定Initflash调用了。并没有在其他地方修改占空比和周期,从在RAM中调试的波形可以看出来。

    2张图片的唯一区别就是从28335_RAM_lnk.cmd更换到F28335.cmd。

           

  • zone

    麻烦把main源文件发上来看一下。以及PWM的初始化代码。

    Eric

  • 附件是Main。

    这是PWM初始化,思路是声明一个宏PWM_Set_OBJ ,直接在宏里面选择配置,最后直接根据宏的选项,在PWM配置中生效。

    void ConfigePWM(PWM_Number_e Ch,const PWM_Set_OBJ mode) {   

    //——————————————————————————————————————  

     //            TBCTR计数频率TBCLK配置   

    (*ePWM[Ch]).TBCTL.bit.HSPCLKDIV  =  mode.HspClkDiv;   

    (*ePWM[Ch]).TBCTL.bit.CLKDIV   =  mode.ClkDiv;

      //——————————————————————————————————————  

     //            TBCTL寄存器   

    (*ePWM[Ch]).TBCTL.bit.CTRMODE  =  mode.CounterMode; 

     //TBCTR的计数模式  

     (*ePWM[Ch]).TBCTL.bit.PHSEN    =  mode.PhaseLoadMode;  

     (*ePWM[Ch]).TBCTL.bit.SYNCOSEL  =  mode.SyncoSrc;  

     (*ePWM[Ch]).TBCTL.bit.PHSDIR   =  mode.PhaseDir;  

     (*ePWM[Ch]).TBCTL.bit.PRDLD    =  mode.PhaseLoadMode;  

     (*ePWM[Ch]).TBCTL.bit.FREE_SOFT  =  mode.SimulationMode;

      //——————————————————————————————————————  

     //              CC   

    (*ePWM[Ch]).CMPCTL.bit.SHDWAMODE = mode.CmpaLoadMode;  //CMPA工作(加载)模式

      (*ePWM[Ch]).CMPCTL.bit.SHDWBMODE = mode.CmpbLoadMode;  //CMPB工作(加载)模式

      (*ePWM[Ch]).CMPCTL.bit.LOADAMODE = mode.CmpaLoadPoint;  //CMPA加载策略点  

     (*ePWM[Ch]).CMPCTL.bit.LOADBMODE = mode.CmpbLoadPoint;  //CMPB加载策略点

      //——————————————————————————————————————   

    //              AQ   (*ePWM[Ch]).AQSFRC.bit.RLDCSF   =  mode.CsfrcLoadMode;

      (*ePWM[Ch]).AQCTLA.bit.ZRO    =  mode.AqZero_ePWMxA_in;  

     (*ePWM[Ch]).AQCTLA.bit.PRD    =  mode.AqTBPRD_ePWMxA_in;

      (*ePWM[Ch]).AQCTLA.bit.CAU    =  mode.AqCAU_ePWMxA_in;  

     (*ePWM[Ch]).AQCTLA.bit.CAD    =  mode.AqCAD_ePWMxA_in;  

     (*ePWM[Ch]).AQCTLA.bit.CBU    =  mode.AqCBU_ePWMxA_in;   

    (*ePWM[Ch]).AQCTLA.bit.CBD    =  mode.AqCBD_ePWMxA_in;

      (*ePWM[Ch]).AQCTLB.bit.ZRO    =  mode.AqZero_ePWMxB_in;  

     (*ePWM[Ch]).AQCTLB.bit.PRD    =  mode.AqTBPRD_ePWMxB_in;  

     (*ePWM[Ch]).AQCTLB.bit.CAU    =  mode.AqCAU_ePWMxB_in;  

     (*ePWM[Ch]).AQCTLB.bit.CAD    =  mode.AqCAD_ePWMxB_in;  

     (*ePWM[Ch]).AQCTLB.bit.CBU    =  mode.AqCBU_ePWMxB_in;  

     (*ePWM[Ch]).AQCTLB.bit.CBD    =  mode.AqCBD_ePWMxB_in;

      //——————————————————————————————————————  

     //              DB   (*ePWM[Ch]).DBCTL.bit.IN_MODE  =  mode.DbInputMode;   

    (*ePWM[Ch]).DBCTL.bit.POLSEL   =  mode.DbPolariry;   

    (*ePWM[Ch]).DBCTL.bit.OUT_MODE  =  mode.DbOutputMode;

      //——————————————————————————————————————  

     //              ET   

    (*ePWM[Ch]).ETSEL.bit.INTEN    =  mode.IntEnable;   //PWM中断使能?   

    (*ePWM[Ch]).ETSEL.bit.INTSEL    =  mode.IntTrigSrc;  //PWM中断触发源

      (*ePWM[Ch]).ETPS.bit.INTPRD    =  mode.IntPeriod;

      (*ePWM[Ch]).ETSEL.bit.SOCAEN   =  mode.SocaEnalbe;   

    (*ePWM[Ch]).ETSEL.bit.SOCASEL   =  mode.SocaTrigSrc;   

    (*ePWM[Ch]).ETPS.bit.SOCAPRD   =  mode.SocaPeriod;

      (*ePWM[Ch]).ETSEL.bit.SOCBEN   =  mode.SocbEnable;  

     (*ePWM[Ch]).ETSEL.bit.SOCBSEL   =  mode.SocbTrigSrc;  

     (*ePWM[Ch]).ETPS.bit.SOCBPRD   =  mode.SocbPeriod;

     }

     

    配置PWM的数据对象:

    typedef struct

    {  //——————————————————————————————————————————————  

    //               TBCLK设置

     PWM_HspClkDiv_e       HspClkDiv;     

      // TBCLK = SYSCLKOUT / (HSPCLKDIV × CLKDIV)  PWM_ClkDiv_e     

       ClkDiv;        // TBCLK = SYSCLKOUT / (HSPCLKDIV × CLKDIV)

     //——————————————————————————————————————————————

     //               TB子模块配置  

    PWM_CounterMode_e     CounterMode;     // TBCTR计数模式  

    PWM_PhaseLoadMode_e    PhaseLoadMode;    

    // 是否允许初始相位加载??  

    PWM_SyncoSrc__e       SyncoSrc;       // SYNCO触发源择  

    PWM_PhaseDir_e       PhaseDir;       // TBPHS计数方向  

    PWM_PeriodLoadMode_e    PeriodLodeMode;    // TBPRD加载模式  

    PWM_SimulationMode_e     SimulationMode;    // PWM在仿真模式下动作  //不发出软件强制SYNCO  //仿真模式始终正常运行  //TBPRD仅在TBCTR=0加载

     //——————————————————————————————————————————————  //    

               CC子模块配置

     PWM_CMPALoad_e      CmpaLoadMode;   //CMPA加载模式  

    PWM_CMPBLoad_e      CmpbLoadMode;   //CMPB加载模式

     PWM_CMPALoadPoint_e     CmpaLoadPoint;    //CMPA加载策略点

      PWM_CMPBLoadPoint_e     CmpbLoadPoint;   //CMPB加载策略点  

    //CMPA/CMPB更新void SetPmwPeriodAndDutyRatio(PWM_Number_e Ch,Uint16 duty,Uint16 period)

     //——————————————————————————————————————————————

     //               AQ子模块配置  

    PWM_CsfrcLoadPoint_e     CsfrcLoadMode;    // AQCSFRC加载策略点

      //ePWMxA_in限定

     PWM_AqAZeroQual_e      AqZero_ePWMxA_in;

     PWM_AqATBPRDQual_e     AqTBPRD_ePWMxA_in;

      PWM_AqACAUQual_e      AqCAU_ePWMxA_in;

     PWM_AqACADQual_e      AqCAD_ePWMxA_in;  

    PWM_AqACBUQual_e      AqCBU_ePWMxA_in;

     PWM_AqACBDQual_e      AqCBD_ePWMxA_in;  //ePWMxB_in限定

     PWM_AqBZeroQual_e      AqZero_ePWMxB_in;  

    PWM_AqBTBPRDQual_e     AqTBPRD_ePWMxB_in;

     PWM_AqBCAUQual_e      AqCAU_ePWMxB_in;

     PWM_AqBCADQual_e      AqCAD_ePWMxB_in;  

    PWM_AqBCBUQual_e      AqCBU_ePWMxB_in;

     PWM_AqBCBDQual_e      AqCBD_ePWMxB_in;

     //——————————————————————————————————————————————  

    //               DB子模块配置  

    PWM_DeadBandInputMode_e   DbInputMode;  

    PWM_DeadBandPolarity_e    DbPolariry;  

    PWM_DeadBandOutputMode_e  DbOutputMode;

     //死区设置函数void SetPwmDBDelay(PWM_Number_e Ch,Uint16 risingdelay,Uint16 fallingdelay)

     //——————————————————————————————————————————————  

    //               PC子模块配置

     

     

     //——————————————————————————————————————————————  

    //               ET子模块配置  

    PWM_INTEnable_e       IntEnable;       //是否使能PWM中断  

    PWM_IntSrc_e        IntTrigSrc;       //中断触发源

     PWM_IntPeriod_e       IntPeriod;       //中断周期

     PWM_SocAEnable_e      SocaEnalbe;      //SOCA使能?

     PWM_SocaPulseSrc_e      SocaTrigSrc;      //SOCA触发源

     PWM_SocaPeriod_e      SocaPeriod;      //SOCA触发周期

     PWM_SocBEnable_e      SocbEnable;      //SOCB使能?  

    PWM_SocbPulseSrc_e      SocbTrigSrc;      //SOCB触发源

     PWM_SocbPeriod_e      SocbPeriod;      //SOCB触发周期

     }PWM_Set_OBJ;

     

    PWM设置的宏参数选项

    #define  EPWMSET                 \ {                         \  

    /*————时钟配置————          */\

     PWM_HspClkDiv_by_1,/*时钟配置1        */\

     PWM_ClkDiv_by_1,  /*时钟配置2        */\                      

      \  /*————TB配置————           */\  

    PWM_CounterMode_UpDown, /* 时基计数模式    */\  

    PWM_PhaseLoad_Disable,/*禁止TBPHS加载     */\

     PWM_SyncoSrc_EPWMxSYNCI,           \

     PWM_PhaseDir_CountDown,/*SYNCI,TBCTR向下计数  */\

     PWM_PeriodLoad_Shadow,             \

      PWM_SimulationMode_FreeRun,                            \           

                 \  /*————CC配置————           */\

     PWM_CmpaLoadMode_Shadow,           \  

    PWM_CmpbLoadMode_Shadow,              \

     PWM_CmpaLoad_Zero,              \  

    PWM_CmpbLoad_Zero,              \                  

          \  /*————AQ配置————           */\  

    PWM_CsfrcLoadPoint_Zero,             \  

    PWM_AqAZero_DoNothing,             \

     PWM_AqATBPRD_DoNothing,            \

     PWM_AqACAU_Set,                \  

    PWM_AqACAD_Clear,               \

     PWM_AqACBU_DoNothing,             \

     PWM_AqACBD_DoNothing,             \  

    PWM_AqBZero_DoNothing,             \

     PWM_AqBTBPRD_DoNothing,            \  

    PWM_AqBCAU_DoNothing,             \  

    PWM_AqBCAD_DoNothing,                                           \

     PWM_AqBCBU_DoNothing,                                           \  

    PWM_AqBCBD_DoNothing,                                           \                        

     /*————DB配置————               */\   

      PWM_DeadBandInputMode_EPWMxA_Rising_and_Falling,    /*输入模式*/\    

    PWM_DeadBandPolarity_EPWMxB_Inverted,            /*极性设置*/\

        PWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Falling, /*输出模式*/\   

                              \     /*————ET配置————                  */\  

    PWM_INTEnable_Disable,                 \  

    PWM_IntSrc_CounterEqualPeriod,            \

     PWM_IntPeriod_Disable,                  \                        

      \  PWM_SocAEnable_Enable, /*SOCA使能           */\

     PWM_SocaPulseSrc_CounterEqualPeriod,            \

     PWM_SocaPeriod_FirstEvent,                \                          \

     PWM_SocBEnable_Disable,                 \  

    PWM_SocbPulseSrc_CounterEqualPeriod,             \

      PWM_SocbPeriod_Disable,                 \                           }

     

     

    我认为PWM初始化配置应该没问题,应为在RAM中运行都很正常。

     

  • Zone

    看到你程序中下面的函数有问题

    F28335_DeviceInit(); // 调用Iniflash()


    MemCopy(.....)

    对Flash的配置需要放在RAM中运行,Memcopy是把这段代码放在RAM中,你应该把Iniflash函数放在memcopy函数下面。

    Eric

  • Eric Ma:

    我试试,另外还想请教一下:

    FILFO                    FOFilter                = FOFLTER_DEFAULT;

    Filter_fo_Handle   FLT_FO_Handle   = &FOFilter;

    这是我的一个关键变量,想存到RAM中运行,是存FOFilter    ?还是存FLT_FO_Handle?

    #pragma (FOFilter    ,"ramfuncs")

    还是#pragma (FLT_FO_Handle,"ramfuncs")

    还是两个都得放到RAM中?

     

     

  • 存FOFilter

    #pragma DATA_SECTION(FOFilter,"ramfuncs");

    Eric

  • Eric:

          根据你的意见,问题已经解决了,有一个疑问:

          在很多实例代码中的函数拷贝,都是直接声明一个#pragma  CODE_SECTION(……) ,然后也没有要放在Memorycopy下面运行啊?

         比如:Example_2833xFlash.c中:epwm1_timer_isr和epwm2_timer_isr要拷贝到RAM中运行,有如下声明:

     #pragma CODE_SECTION(epwm1_timer_isr, "ramfuncs");

     #pragma CODE_SECTION(epwm2_timer_isr, "ramfuncs");

    interrupt void epwm1_timer_isr(void);

     interrupt void epwm2_timer_isr(void);

    在主函数中也就调用了Memorycopy就可以了,也没有要求要在Memorycopu()下面运行的啊?

     

  • 我的意思是,只有先调用memcopy后,才能运行这些函数,因为芯片会去对应的RAM去寻找函数入口代码,如果代码没有复制过去,那么跑过去的话就程序就会跑飞。

    所以memcopy函数一般都是在函数初始化最开始的地方,后面其他函数的调用时,如epwm2_timer_isr,RAM中已经有这些代码了。

    Eric