TMS320F28335之外部接口与CPLD通信问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hmf1235789/article/details/54408541
  • 系统原理

我用CPLD采集AD数据,利用XINTF接口将数据传输到DSP,CCS观察DSP地址数据。系统框图如下所示。
这里写图片描述
其中28335的XINTF采用16位数据总线连接。
这里写图片描述
GPIO端口设置如下

void InitGpio(void) //初始化GPIO
{
   EALLOW;
//-----------------------------------------------------------------------------------

    GpioCtrlRegs.GPBMUX1.all = 0xFFFFFFF0;     // 配置 GPIO32-33为I/O口
                                               // 配置 GPIO34 for XREADY 就绪
                                               // 配置 GPIO35 for XR/W     读
                                               // 配置 GPIO36 for XZCS0 片选
                                               // 配置 GPIO37 for XZCS7 片选
                                               // 配置 GPIO38 for XWE0  写
                                               // 配置 GPIO39 for XA16 地址
                                               // 配置 GPIO40 for XA0 
                                               // 配置 GPIO41 for XA1 
                                               // 配置 GPIO42 for XA2 
                                               // 配置 GPIO43 for XA3 
                                               // 配置 GPIO44 for XA4 
                                               // 配置 GPIO45 for XA5 
                                               // 配置 GPIO46 for XA6 
                                               // 配置 GPIO47 for XA7 

    GpioCtrlRegs.GPCMUX1.all = 0xFFFFFFFF;     // 配置 GPIO64-GPIO79 for XD15-XD0 数据

    GpioCtrlRegs.GPCMUX2.all = 0xFFFFFFFF;     // 配置 GPIO80-GPIO87 for XA8-XA15 地址


//  GpioCtrlRegs.GPBDIR.all = 0xE0000000;     // GPIO32-GPIO60 为输入

    GpioCtrlRegs.GPCDIR.all = 0x00000000;     // GPI064-GPIO95 为输入

//----------------------------------------------------------------------------------------
     GpioCtrlRegs.GPAPUD.all = 0x0100;              // 内部上拉 GPIO0-GPIO31
     GpioCtrlRegs.GPBPUD.all = 0x0000;              // 内部上拉 GPIO32-GPIO63
     GpioCtrlRegs.GPCPUD.all = 0x0000;              // 内部上拉 GPIO64-GPIO79

    EDIS;

}   

XINTF访问区域0地址

void InitXintf(void)
{
    // 这显示了如何写XINTF寄存器。
    // 这里使用了重置后的默认状态值。
    // 不同的硬件需要不同的配置。

    // 为INTF配置一个例子,在如下目录
    // F28335 eZdsp, refer to the examples/run_from_xintf project.

    // 任何更改XINTF配置只能从XINTF扩展之外的区域运行代码。


    // 所有区域---------------------------------
    // 所有区域的基准时间时钟为 XTIMCLK = 1/2 SYSCLKOUT
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1;         //开启XINTF时钟信号
    XintfRegs.XINTCNF2.bit.XTIMCLK = 1;             //基准时钟XTIMCLK = 1/2 SYSCLKOUT
    XintfRegs.XINTCNF2.bit.WRBUFF = 0;              //无写缓冲寄存器
    XintfRegs.XINTCNF2.bit.CLKOFF = 1;              //禁止XCLKOUT
    XintfRegs.XINTCNF2.bit.CLKMODE = 1;             //XCLKOUT=XTIMCLK/2

    XintfRegs.XTIMING0.bit.XWRLEAD = 2;             //区域0写建立时间为11b,周期数为6
    XintfRegs.XTIMING0.bit.XWRACTIVE = 5;           //有效时间为111b,周期数为14
    XintfRegs.XTIMING0.bit.XWRTRAIL = 2;            //跟踪时间为11b,周期数为6
    // Zone read timing
    XintfRegs.XTIMING0.bit.XRDLEAD = 2;             //区域0读建立时间为11b,周期数为6
    XintfRegs.XTIMING0.bit.XRDACTIVE = 5;           //有效时间为111b,周期数为14
    XintfRegs.XTIMING0.bit.XRDTRAIL = 2;            //跟踪时间为11b,周期数为6

    // double all Zone read/write lead/active/trail timing
    XintfRegs.XTIMING0.bit.X2TIMING = 1;            //比值2:1

    // Zone will sample XREADY signal
    XintfRegs.XTIMING0.bit.USEREADY = 0;            //XREADY信号采样
    XintfRegs.XTIMING0.bit.READYMODE = 1;           //异步采样

    XintfRegs.XTIMING0.bit.XSIZE = 3;               //数据总线宽度,16位
    EDIS;

}

CPLD与AD芯片之间采样时序如下
这里写图片描述

  • 问题
    从DSP外部中断1的中断函数内,读取CPLD地址数据,发现8路ADC数据错乱,给AD通道1电平变化,其他相邻地址位也出现数据变化,相互串扰。其中测试确保程序进入了外部中断函数中。
#define FPGA_BASE_ADDR          0X4000  //区域0起始地址

#define HSAD_OUT_CUR_A1         (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0004))  //HSAD采样        
#define HSAD_OUT_CUR_B1         (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0005))  //HSAD采样电流  
#define HSAD_OUT_CUR_A2         (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0006))  //HSAD采样电流  
#define HSAD_OUT_CUR_B2         (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0007))  //HSAD采样电流  
#define HSAD_OUT_CUR_A3         (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0008))  //HSAD采样电流  
#define HSAD_OUT_CUR_B3         (*(volatile int16 *)(FPGA_BASE_ADDR + 0x0009))  //HSAD采样电流  

#define HSAD_OUT_CUR_A4         (*(volatile int16 *)(FPGA_BASE_ADDR + 0x000A))  //HSAD采样电流  
#define HSAD_OUT_CUR_A5         (*(volatile int16 *)(FPGA_BASE_ADDR + 0x000B))  //HSAD采样电流  


interrupt void  XINT1_ISR(void)
{
  // ISR代码插入这里  

    outCurADeal_pSt[0].in_I16 = HSAD_OUT_CUR_A1;                //1_A相电流
    outCurBDeal_pSt[0].in_I16 = HSAD_OUT_CUR_B1;                //1_B相电流
    outCurADeal_pSt[1].in_I16 = HSAD_OUT_CUR_A2;                //2_A相电流
    outCurBDeal_pSt[1].in_I16 = HSAD_OUT_CUR_B2;                //2_B相电流    
    outCurADeal_pSt[2].in_I16 = HSAD_OUT_CUR_A3;                //3_A相电流
    outCurBDeal_pSt[2].in_I16 = HSAD_OUT_CUR_B3;                //3_B相电流

    outCurADeal_pSt[3].in_I16 = HSAD_OUT_CUR_A4;                //1_A相电流
    outCurADeal_pSt[4].in_I16 = HSAD_OUT_CUR_A5;                //2_A相电流

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}

起初以为是CPLD与AD之间采样时序错误,造成CPLD本身地址上数据错乱,经XINTF传送后,DSP也接收到错乱数据,CPLD程序如下。

 always@(posedge SYS_10M_CLK)
        begin

            cs_r[2]  =(XA ==  BASE_AD_ZONE0 +   16'H0004) &(!rd_filter)&(!XZCS0_N);     //0x04 AD1_V1 
            cs_r[3]  =(XA ==  BASE_AD_ZONE0 +   16'H0005) &(!rd_filter)&(!XZCS0_N);     //0x05 AD1_V2 
            cs_r[4]  =(XA ==  BASE_AD_ZONE0 +   16'H0006) &(!rd_filter)&(!XZCS0_N);     //0x06 AD1_V3
            cs_r[5]  =(XA ==  BASE_AD_ZONE0 +   16'H0007) &(!rd_filter)&(!XZCS0_N);     //0x07 AD1_V4
            cs_r[6]  =(XA ==  BASE_AD_ZONE0 +   16'H0008) &(!rd_filter)&(!XZCS0_N);     //0x08 AD1_V5 
            cs_r[7]  =(XA ==  BASE_AD_ZONE0 +  16'H0009) &(!rd_filter)&(!XZCS0_N);      //0x09 AD1_V6 

            cs_r[8]  =(XA ==  BASE_AD_ZONE0 +   16'H000A) &(!rd_filter)&(!XZCS0_N);     //0x0A AD2_V1 
            cs_r[9]  =(XA ==  BASE_AD_ZONE0 +   16'H000B) &(!rd_filter)&(!XZCS0_N);     //0x0B AD2_V2 

        end   


        always@(posedge SYS_10M_CLK)
        case(cs_r)

        15'b000_0000_0000_0100: begin dsp_dat_reg =  ad1_dout[15:0];  end        //30 AD1_V1  1_A相电流 
        15'b000_0000_0000_1000: begin dsp_dat_reg =  ad1_dout[31:16]; end        //40 AD1_V2  1_B相电流    
        15'b000_0000_0001_0000: begin dsp_dat_reg =  ad1_dout[47:32]; end        //50 AD1_V3  2_A相电流    
        15'b000_0000_0010_0000: begin dsp_dat_reg =  ad1_dout[63:48]; end        //60 AD1_V4  2_B相电流    
        15'b000_0000_0100_0000: begin dsp_dat_reg =  ad1_dout[79:64]; end        //70 AD1_V5  3_A相电流    
        15'b000_0000_1000_0000: begin dsp_dat_reg =  ad1_dout[95:80]; end        //80 AD1_V6  3_B相电流    

        15'b000_0001_0000_0000: begin dsp_dat_reg =  ad2_dout[15:0];  end        //110 AD2_V1  1_A相电流 
        15'b000_0010_0000_0000: begin dsp_dat_reg =  ad2_dout[31:16]; end        //120 AD2_V2  2_A相电流
                           default: begin dsp_dat_reg = dsp_dat_reg;end          //数据寄存器数据保持 
        endcase

因CPLD程序无法调试和观察变量,我将CPLD采集程序屏蔽到只剩下一路AD采样,然后再次观察DSP地址变量数据,发现数据正确,单独测试每一路均能正确接收数据,但将多路AD采样通道开启却出现错误,再次检查CPLD与AD芯片采样时序,确保AD采样时序符合最小时序要求,发现还是出现错误。最后将CPLD采样程序屏蔽,直接在地址位上赋常量,如下所示。

 always@(posedge SYS_10M_CLK)
        begin

            cs_r[2]  =(XA ==  BASE_AD_ZONE0 +   16'H0004) &(!rd_filter)&(!XZCS0_N);     //0x04 AD1_V1 
            cs_r[3]  =(XA ==  BASE_AD_ZONE0 +   16'H0005) &(!rd_filter)&(!XZCS0_N);     //0x05 AD1_V2 
            cs_r[4]  =(XA ==  BASE_AD_ZONE0 +   16'H0006) &(!rd_filter)&(!XZCS0_N);     //0x06 AD1_V3
            cs_r[5]  =(XA ==  BASE_AD_ZONE0 +   16'H0007) &(!rd_filter)&(!XZCS0_N);     //0x07 AD1_V4
            cs_r[6]  =(XA ==  BASE_AD_ZONE0 +   16'H0008) &(!rd_filter)&(!XZCS0_N);     //0x08 AD1_V5 
            cs_r[7]  =(XA ==  BASE_AD_ZONE0 +  16'H0009) &(!rd_filter)&(!XZCS0_N);      //0x09 AD1_V6 

            cs_r[8]  =(XA ==  BASE_AD_ZONE0 +   16'H000A) &(!rd_filter)&(!XZCS0_N);     //0x0A AD2_V1 
            cs_r[9]  =(XA ==  BASE_AD_ZONE0 +   16'H000B) &(!rd_filter)&(!XZCS0_N);     //0x0B AD2_V2 

        end   


        always@(posedge SYS_10M_CLK)
        case(cs_r)

        15'b000_0000_0000_0100: begin dsp_dat_reg =  30;  end        //30 AD1_V1  1_A相电流 
        15'b000_0000_0000_1000: begin dsp_dat_reg =  40; end         //40 AD1_V2  1_B相电流    
        15'b000_0000_0001_0000: begin dsp_dat_reg =  50; end         //50 AD1_V3  2_A相电流    
        15'b000_0000_0010_0000: begin dsp_dat_reg =  60; end         //60 AD1_V4  2_B相电流    
        15'b000_0000_0100_0000: begin dsp_dat_reg =  70; end         //70 AD1_V5  3_A相电流    
        15'b000_0000_1000_0000: begin dsp_dat_reg =  80; end         //80 AD1_V6  3_B相电流    

        15'b000_0001_0000_0000: begin dsp_dat_reg =  110;  end       //110 AD2_V1  1_A相电流 
        15'b000_0010_0000_0000: begin dsp_dat_reg =  120; end        //120 AD2_V2  2_A相电流
                           default: begin dsp_dat_reg = dsp_dat_reg;end          //数据寄存器数据保持 
        endcase

测试发现DSP地址数据出现跳变错乱,可以判断是CPLD与DSP的xintf通信问题,当时单路测试时正确以为xintf通信已经没有问题,导致花费很多时间测试CPLD与AD之间时序。仔细观察,发现ADC通道1数据串扰到通道2地址上,并影响通道3,怀疑DSP与CPLD通信时序不匹配,DSP速度过快,CPLD速度过慢,通过改变xintf配置寄存器,将建立、有效、跟踪时间调整至最高和最低,如下。

    XintfRegs.XTIMING0.bit.XWRLEAD = 1;             //区域0写建立时间为1b,周期数为1
    XintfRegs.XTIMING0.bit.XWRACTIVE = 1;           //有效时间为1b,周期数为1
    XintfRegs.XTIMING0.bit.XWRTRAIL = 1;            //跟踪时间为1b,周期数为1
    // Zone read timing
    XintfRegs.XTIMING0.bit.XRDLEAD = 1;             //区域0读建立时间为1b,周期数为1
    XintfRegs.XTIMING0.bit.XRDACTIVE = 1;           //有效时间为1b,周期数为1
    XintfRegs.XTIMING0.bit.XRDTRAIL = 1;            //跟踪时间为1b,周期数为1

    // double all Zone read/write lead/active/trail timing
    XintfRegs.XTIMING0.bit.X2TIMING = 0;            //比值1:1

发现差别明显,另外通过将DSP系统时钟设置进行降频,发现数据能达到一个比较稳定状态。

//#define DSP28_DIVSEL   0      // Enable /4 for SYSCLKOUT
//#define DSP28_DIVSEL   1      // Enable /4 for SYSCKOUT
#define DSP28_DIVSEL     2      // Enable /2 for SYSCLKOUT
//#define DSP28_DIVSEL   3      // Enable /1 for SYSCLKOUT

#define DSP28_PLLCR      10
//#define DSP28_PLLCR    9
//#define DSP28_PLLCR    8
//#define DSP28_PLLCR    7
//#define DSP28_PLLCR    6
//#define DSP28_PLLCR    5
//#define DSP28_PLLCR    4
//#define DSP28_PLLCR    3
//#define DSP28_PLLCR    2
//#define DSP28_PLLCR    1
//#define DSP28_PLLCR    0      // PPL旁路


void InitSysCtrl(void)                      //初始化系统控制
{
   DisableDog();                            //关闭看门狗
   InitPll(DSP28_PLLCR,DSP28_DIVSEL);       //初始化PLL控制
   InitPeripheralClocks();                  //初始化外设时钟
}

最后发现DSP晶振为30Mhz,CPLD晶振为10Mhz,导致CPLD数据线上数据变化过慢,当DSP地址改变时,CPLD数据线上的数据还是前一位数据,造成数据延迟,串扰到第一位地址。尝试将xintf接口速度减慢,CPLD芯片无PLL,采用上下沿触发,软件倍频,还是达不到匹配状态。最后只得将CPLD晶振替换为30MHz才正确匹配。

猜你喜欢

转载自blog.csdn.net/hmf1235789/article/details/54408541