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.

为何28027能在ram中正确运行但是换成在flash中就为什么不能运行呢



为何28027能在ram中正确运行但是换成在flash中就为什么不能运行呢

/*
// 系统时钟采用外部晶体振荡器 24MHZ 使能锁相环 60MHZ = (24*5)/2 WDTCLK = 24MHZ
//SYSCLKOUT = CLKIN =60MHZ
//
*/
#include "DSP28x_Project.h"
//#include "f2802x_common/include/SFO_V6.h"
#include "pid.h"
#include"board_CONFIG.h"

#pragma CODE_SECTION(Timer0_isr, "ramfuncs");
#pragma CODE_SECTION(SCIA_RxFifoIsr, "ramfuncs");

Uint16 Rdata[4] ;
Uint16 SendData[4] ={0};
extern Uint16 FhaseError;
extern Uint16 period ;
void InitTimer0(void);
void Process(void);
// 这里已经制定的参数都是我们默认相对不能设置的 我们需要用户去设置
PID pid;
volatile FLAG flag ;

void PID_Set(void )
{
//PID pid;
pid.outMax = 3333 ; //设定最低频率18K
pid.outMin = 1500 ; //设定最高频率
pid.InAuto= 1 ;//自动模式
pid.SampleTime = 4; //默认采样时间4ms
pid.ControllerDirection = 1;//设定控制器的方向
PID_SetTunings(&pid,2, 1, 1);//PID参数
//lastTime = millis()-SampleTime;//上一次采样时间
}


void main(void)
{
Uint16 T_counter ;
InitSysCtrl();
InitGpio();
DINT;//全局中断关闭 INTM
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();


EALLOW;
//GPIO19为演示用
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0; //选择GPIO1 为普通IO 口模式
GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; //方向输出
GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; //关闭上拉
EDIS;

/**/
//使能EPWM1 使能TZ3
InitEPwm();
InitECap();
InitSci();//通过测试
InitAdc();
InitTimer0();

extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadSize;
extern Uint16 RamfuncsRunStart;
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
InitFlash();

EnableInterrupts();
PID_Set();

for (;;)
{
//pid->Setpoint = 30 ;
//pid->Input = 20;
// PID_Compute(&pid);

if( flag.Rec_Ok )
{
Process();
flag.Rec_Ok = 0 ;
}
if(flag.Cycle)//
{
flag.Cycle = 0;
if(++T_counter>124){ GpioDataRegs.GPATOGGLE.bit.GPIO19 = 1 ;//翻转
T_counter = 0;
}
}
DELAY_US(2000);
flag.Cycle = 1;

}

}


interrupt void Timer0_isr(void)
{
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;//清除中断响应位避免阻止其他中断受影响
flag.Cycle =1;

}
void InitTimer0(void)
{
/****************设置定时器,用以触发ADC*****************/
CpuTimer0Regs.TPR.bit.TDDR = 59;
CpuTimer0Regs.TPRH.bit.TDDRH = 0; //对输入时钟60分频,60M/60=1M
CpuTimer0Regs.PRD.all = 4000;//定时4ms定时时间长度4ms
CpuTimer0Regs.TCR.bit.TRB = 1; //reload
CpuTimer0Regs.TCR.bit.TIE = 1; //使能中断
CpuTimer0Regs.TCR.bit.TSS = 0; //开始计数
EALLOW;
PieVectTable.TINT0 = &Timer0_isr;
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; //使能PIE
PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //使能int1.7
IER |=M_INT1;//使能GROUP1
EDIS;
}

//Rdata[4] 数据包含 命令+数据(2 byte)
// 'S'+频率数值
extern void SCIA_RxFifoSend(Uint16 * Src) ;
void Process(void)
{
if(Rdata[0]=='S') {
period = ((Rdata[1]<<8)|Rdata[2]);
EPwm1Regs.TBPRD = period-1; // PWM frequency = 1 / period
EPwm1Regs.CMPA.half.CMPA = period/2; // Set duty as 50%
SendData[0] = 'S';
SendData[1] = Rdata[1];
SendData[2] = Rdata[2];
}
else if(Rdata[0]=='R')
{
SendData[0] = 'R';
SendData[2] = FhaseError%255;
SendData[1] = FhaseError>>8;

}
else if(Rdata[0]=='C')
{
if(Rdata[1]==0) EPwm4Regs.AQCSFRC.bit.CSFA = 1;//软件强制0输出
else if(Rdata[1]==0xff) EPwm4Regs.AQCSFRC.bit.CSFA = 3;//软件强制无效
SendData[0] = 'C';
SendData[1] = Rdata[1];
SendData[2] = Rdata[2];
}


SCIA_RxFifoSend(SendData);

}
interrupt void SCIA_RxFifoIsr(void)
{
uint16_t i;

for(i=0;i<3;i++)
{
// Read data
Rdata[i] = SciaRegs.SCIRXBUF.bit.RXDT ;
}
SciaRegs.SCIFFRX.bit.RXFFINTCLR = 1;//// Clear Interrupt flag
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;//避免影响其他中断的发生
//rest

flag.Rec_Ok = 1 ;//设定 接收完成标志
}

  • 你通过代码搬移的方法试试吧     就是将FLASH中的代码搬移到RAM中运行

  • 你好 TI技术人员  我的程序是可以在RAM中运行的 可是却不能在flash中运行

  • 初步查明是 InitAdc();//影响中断执行 影响了整个程序的运行 去掉次函数后 整个程序在flash中运行良好

    #define ADC_usDELAY  1000L
    Uint16 Result[8] = {0};

    #pragma CODE_SECTION(ADC_convered1, "ramfuncs");
    #pragma CODE_SECTION(ADC_convered2, "ramfuncs");
    #pragma CODE_SECTION(ADC_convered3, "ramfuncs");
    #pragma CODE_SECTION(ADC_convered4, "ramfuncs");
    #pragma CODE_SECTION(ADC_convered5, "ramfuncs");
    #pragma CODE_SECTION(ADC_convered6, "ramfuncs");
    #pragma CODE_SECTION(ADC_convered7, "ramfuncs");
    #pragma CODE_SECTION(ADC_convered8, "ramfuncs");

    interrupt void ADC_convered1(void);
    interrupt void ADC_convered2(void);
    interrupt void ADC_convered3(void);
    interrupt void ADC_convered4(void);
    interrupt void ADC_convered5(void);
    interrupt void ADC_convered6(void);
    interrupt void ADC_convered7(void);
    interrupt void ADC_convered8(void);

    void InitAdc(void)
    {
        extern void DSP28x_usDelay(Uint32 Count);

        // IMPORTANT
        // The Device_cal function, which copies the ADC calibration values from TI reserved
        // OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
        // Boot ROM. If the boot ROM code is bypassed during the debug process, the
        // following function MUST be called for the ADC to function according
        // to specification. The clocks to the ADC MUST be enabled before calling this
        // function.
        // See the device data manual and/or the ADC Reference
        // Manual for more information.

            EALLOW;
            SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
            (*Device_cal)();
            EDIS;

        // To powerup the ADC the ADCENCLK bit should be set first to enable
        // clocks, followed by powering up the bandgap, reference circuitry, and ADC core.
        // Before the first conversion is performed a 5ms delay must be observed
        // after power up to give all analog circuits time to power up and settle

        // Please note that for the delay function below to operate correctly the
        // CPU_RATE define statement in the DSP2802x_Examples.h file must
        // contain the correct CPU clock period in nanoseconds.
        EALLOW;
        AdcRegs.ADCCTL1.bit.ADCBGPWD  = 1;      // Power ADC BG
        AdcRegs.ADCCTL1.bit.ADCREFPWD = 1;      // Power reference
        AdcRegs.ADCCTL1.bit.ADCPWDN   = 1;      // Power ADC
        AdcRegs.ADCCTL1.bit.ADCENABLE = 1;      // Enable ADC
        AdcRegs.ADCCTL1.bit.ADCREFSEL = 0;      // Select interal BG
        EDIS;

        DELAY_US(ADC_usDELAY);         // Delay before converting ADC channels

        InitAdcAio();//初始化ADC IO 口
        ///////////////////////////
        EALLOW;
        ///
        //AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0 = 0; //顺序采样默认顺序采样
        //选择需要转换的通道
        //过采样 高频电流
        AdcRegs.ADCSOC0CTL.bit.CHSEL = 6;       //
        AdcRegs.ADCSOC1CTL.bit.CHSEL = 6;       //
        AdcRegs.ADCSOC2CTL.bit.CHSEL = 6;       //

        AdcRegs.ADCSOC3CTL.bit.CHSEL = 6;       //
        //
        AdcRegs.ADCSOC4CTL.bit.CHSEL = 0;       //
        AdcRegs.ADCSOC5CTL.bit.CHSEL = 1;       //
        AdcRegs.ADCSOC6CTL.bit.CHSEL = 3;       //
        AdcRegs.ADCSOC7CTL.bit.CHSEL = 7;       //

        //ADC选择采样窗口大小
        AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;
        AdcRegs.ADCSOC1CTL.bit.ACQPS = 6;
        AdcRegs.ADCSOC2CTL.bit.ACQPS = 6;
        AdcRegs.ADCSOC3CTL.bit.ACQPS = 6;

        AdcRegs.ADCSOC4CTL.bit.ACQPS = 6;
        AdcRegs.ADCSOC5CTL.bit.ACQPS = 6;
        AdcRegs.ADCSOC6CTL.bit.ACQPS = 6;
        AdcRegs.ADCSOC7CTL.bit.ACQPS = 6;
        // soc触发选择,TIM0
        AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 1;
        AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 1;
        AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 1;
        AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 1;
        //software ctrl
        AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 0;
        AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 0;
        AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 0;
        AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 0;
    ////////////////////////////////////////////////////////////////////
        AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 4 ;//ADC0-ADC3 high priority

        AdcRegs.ADCCTL1.bit.INTPULSEPOS  = 1;  //结果存入寄存器才产生中断

        PieVectTable.ADCINT1 = &ADC_convered1;
        PieVectTable.ADCINT2 = &ADC_convered2;
        PieVectTable.ADCINT3 = &ADC_convered3;
        PieVectTable.ADCINT4 = &ADC_convered4;
        PieVectTable.ADCINT5 = &ADC_convered5;
        PieVectTable.ADCINT6 = &ADC_convered6;
        PieVectTable.ADCINT7 = &ADC_convered7;
        PieVectTable.ADCINT8 = &ADC_convered8;

        AdcRegs.INTSEL1N2.bit.INT1SEL = 1;    //中断线1选择soc1
        AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;  //不连续转换
        AdcRegs.INTSEL1N2.bit.INT1E  = 1;    //中断使能
        AdcRegs.INTSEL1N2.bit.INT2SEL = 2;    //中断线1选择soc2
        AdcRegs.INTSEL1N2.bit.INT2CONT  = 0;  //不连续转换
        AdcRegs.INTSEL1N2.bit.INT2E  = 1;    //中断使能

        AdcRegs.INTSEL3N4.bit.INT3SEL = 3;    //中断线1选择soc3
        AdcRegs.INTSEL3N4.bit.INT3CONT  = 0;  //不连续转换
        AdcRegs.INTSEL3N4.bit.INT3E  = 1;    //中断使能
        AdcRegs.INTSEL3N4.bit.INT4SEL = 4;    //中断线1选择soc4
        AdcRegs.INTSEL3N4.bit.INT4CONT  = 0;  //不连续转换
        AdcRegs.INTSEL3N4.bit.INT4E  = 1;    //中断使能

        AdcRegs.INTSEL5N6.bit.INT5SEL = 5;    //中断线1选择soc5
        AdcRegs.INTSEL5N6.bit.INT5CONT  = 0;  //不连续转换
        AdcRegs.INTSEL5N6.bit.INT5E  = 1;    //中断使能
        AdcRegs.INTSEL5N6.bit.INT6SEL = 6;    //中断线1选择soc6
        AdcRegs.INTSEL5N6.bit.INT6CONT  = 0;  //不连续转换
        AdcRegs.INTSEL5N6.bit.INT6E  = 1;

        AdcRegs.INTSEL7N8.bit.INT7SEL = 7;    //中断线1选择soc7
        AdcRegs.INTSEL7N8.bit.INT7CONT  = 0;  //不连续转换
        AdcRegs.INTSEL7N8.bit.INT7E  = 1;    //中断使能
        AdcRegs.INTSEL7N8.bit.INT8SEL = 8;    //中断线1选择soc8
        AdcRegs.INTSEL7N8.bit.INT8CONT  = 0;  //不连续转换
        AdcRegs.INTSEL7N8.bit.INT8E  = 1;

        PieCtrlRegs.PIEIER1.bit.INTx1 =0 ;
        PieCtrlRegs.PIEIER10.all= 0xff;   //使能int10
        IER |= M_INT10;
        EDIS;

    }

     


    interrupt void ADC_convered1(void)
    {

        Result[0] = AdcResult.ADCRESULT0;
        AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//硬件清零
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;
    }

    interrupt void ADC_convered2(void)
    {

        Result[1] = AdcResult.ADCRESULT1;
        AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;//硬件清零
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;
    }
    interrupt void ADC_convered3(void)
    {

        Result[2] = AdcResult.ADCRESULT2;
        AdcRegs.ADCINTFLGCLR.bit.ADCINT3 = 1;//硬件清零
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;
    }
    interrupt void ADC_convered4(void)
    {

        Result[3] = AdcResult.ADCRESULT3;
        AdcRegs.ADCINTFLGCLR.bit.ADCINT4 = 1;//硬件清零
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;
    }
    interrupt void ADC_convered5(void)
    {

        Result[4] = AdcResult.ADCRESULT4;
        AdcRegs.ADCINTFLGCLR.bit.ADCINT5 = 1;//硬件清零
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;
    }

    interrupt void ADC_convered6(void)
    {

        Result[5] = AdcResult.ADCRESULT5;
        AdcRegs.ADCINTFLGCLR.bit.ADCINT6 = 1;//硬件清零
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;
    }
    interrupt void ADC_convered7(void)
    {

        Result[6] = AdcResult.ADCRESULT6;
        AdcRegs.ADCINTFLGCLR.bit.ADCINT7 = 1;//硬件清零
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;
    }
    interrupt void ADC_convered8(void)
    {

        Result[7] = AdcResult.ADCRESULT7;
        AdcRegs.ADCINTFLGCLR.bit.ADCINT8 = 1;//硬件清零
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP10;
    }
    void InitAdcAio()
    {

       EALLOW;

    /* Configure ADC pins using AIO regs*/
    // This specifies which of the possible AIO pins will be Analog input pins.
    // NOTE: AIO1,3,5,7-9,11,13,15 are analog inputs in all AIOMUX1 configurations.
    // Comment out other unwanted lines.

        //GpioCtrlRegs.AIOMUX1.bit.AIO2 = 2;    // Configure AIO2 for A2 (analog input) operation
        //GpioCtrlRegs.AIOMUX1.bit.AIO4 = 2;    // Configure AIO4 for A4 (analog input) operation
        GpioCtrlRegs.AIOMUX1.bit.AIO6 = 2;    // Configure AIO6 for A6 (analog input) operation
        GpioCtrlRegs.AIOMUX1.bit.AIO10 = 2;   // Configure AIO10 for B2 (analog input) operation
        GpioCtrlRegs.AIOMUX1.bit.AIO12 = 2;   // Configure AIO12 for B4 (analog input) operation
        GpioCtrlRegs.AIOMUX1.bit.AIO14 = 2;   // Configure AIO14 for B6 (analog input) operation

        EDIS;
    }

  • 不能运行能说具体一点吗?是程序没有跑起来,还是某部分(例如中断)不能正常运行。

    如果是没有运行起来,请确认一下Boot mode的引脚是否配置成Flash模式。

  • 就是中断不能响应,for循环好像也不能运行,因该是跳到了某个中断函数里面去了 去掉init_ADC函数后程序就正常了

  • 应该是DELAY_US()函数的问题,你单独屏蔽这个函数试一下

    解决的方法是你烧写到Flash中运行时,使用Memcopy,将程序从Flash Copy到Ram中运行

  • 你好,我刚才将 

    PIE VECT.C和.h中的ADCINT1/2 涉及到的INT1与INT10 改写呼唤了一下

    // Group 1 PIE Vectors
    rsvd_ISR, // 1.1 ADC // ADCINT1_ISRif this is , then INT10.1 should be defined as ADCINT1_ISR
    rsvd_ISR, // 1.2 ADC //ADCINT2_ISR if this is rsvd_ISR, then INT10.2 should be defined as ADCINT1_ISR

    // Group 10 PIE Vectors
    ADCINT1_ISR, // 10.1 If this is ADCINT1_ISR, then INT1.1 should be defined as rsvd_ISR
    ADCINT2_ISR, // 10.2 If this is ADCINT1_ISR, then INT1.2 should be defined as rsvd_ISR

     用XDS100V3仿真器全速运行可以正常运行,但是拿掉仿真器 后 再断电重新上电后程序定时中断0大概运行250次后 整个程序好像卡在某处不运行

  • 屏蔽此函数DELAY_US()函数对整个程序不运行或卡在某处起不到任何作用

  • 你连接仿真器用CCS全速运行正常,重新上电后程序会有问题,这两次测试都是烧写Flash的,程序没有改动过是吗?是重新上电后运行了一段时间后才出问题的?

  • 是的,因为我程序中的gpio19来指示程序的运行与否,山了三下说明中断进入了至少125*3下后来就不闪了 我怀疑跟我的EACP中的计数器溢出或者ECAP有关有关所以我再找找看

  • interrupt void ECAP1_Isr(void)
    {

    ECap1Regs.ECCLR.bit.INT = 1;//清除中断
    ECap1Regs.ECCLR.bit.CEVT1= 1;//ECAP1 FLAG未清楚影响整个程序的执行
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
    ECap1Regs.ECCTL2.bit.REARM = 1;//Reset MOD4 counter
    FhaseError = ECap1Regs.CAP1 ;
    Fhase2 = ECap1Regs.CAP2;
    }