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.

[参考译文] TMS320F28379D:SPI 时序问题

Guru**** 2465890 points
Other Parts Discussed in Thread: C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1135838/tms320f28379d-spi-timing-issues

器件型号:TMS320F28379D
主题中讨论的其他器件:C2000WARE

大家好、

以下是客户可能需要您帮助的一些问题:

我使用示波器测试 SPI 通信时序。 SPIA 自接收和自发送、SPIA 主器件和 SPIB 从器件分别经过测试。

CCS 调试接口在 SPIA 自接收和自检期间正常显示。 示波器测量 SCLK、如下图所示、8个脉冲在一组中、单个脉冲的宽度为12.4us (高电平和低电平时间均为6.2us)、但每组脉冲之间将有31.4us 的时间间隔。 这是正常的吗?

测量了 SIMO 引脚、发现它将继续发送相同的数据。 测量时间约为32.3ms、数据重复约243次。 如何解决此问题?

以下是 SPIA 自接收和自发送的程序:

/*
 * SPI self-receive and self-transmit
 *
 */

#include "F28x_Project.h"

typedef unsigned char Uint8;


//statement
void gpio_init();   //Configure all GPIO ports connected to the PCB board (including 3-wire SPI)
void spia_init();
void spia_xmit(Uint8 a);


//global variable
char sdata;
char rdata;

void main()
{
    //initialization
    InitSysCtrl();  
    InitGpio();
    DINT;//disable interrupt
    InitPieCtrl();
    IER = 0x0000; 
    IFR = 0x0000;
    InitPieVectTable();


    gpio_init();


    spia_init();

    sdata = 0x0045;

    for(;;)
    {
        spia_xmit(sdata);
        while(SpiaRegs.SPISTS.bit.INT_FLAG != 1){}
        rdata = SpiaRegs.SPIRXBUF;
        sdata++;
    }


}

void gpio_init()
{
    /* 
     * 60   SPICLKA_DA     SPIA CLK
     * 59   SPISOMIA_DA    SPIA SOMI
     * 58   SPISIMOA_DA    SPIA SIMO
     */

    EALLOW;

    //SPI
    //DA(enable、asynchronous、SPI)
    GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;
    GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3;
    GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3;
    GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3;//SPICLKA

    GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;
    GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3;
    GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3;
    GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3;//SPISOMIA

    GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;
    GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3;
    GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3;
    GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3;//SPISIMOA

    EDIS;

}

void spia_init()
{
    //DAC1282 clock polarity(CPOL)is 0,clock phase(CPHA)is 0
    //Configuration Control Register(8 bits reserved,0000 0000 0000 0111 = 0x0007)
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;//SPI reset
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;//clock polarity is 0(SCK idle is low)
    SpiaRegs.SPICCR.bit.HS_MODE = 0;//Turn off high speed mode
    SpiaRegs.SPICCR.bit.SPILBK = 1;//Turn off loopback mode
    SpiaRegs.SPICCR.bit.SPICHAR = (8-1);//Word length 8 bits

    //运行控制寄存器(11位保留,0000 0000 0000 0110 = 0x0006)
    SpiaRegs.SPICTL.bit.OVERRUNINTENA = 1;//Disable receive overflow interrupt
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0;//clock phase is 0(Sampled on the first transition edge)
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;//MCU master
    SpiaRegs.SPICTL.bit.TALK = 1;//enable master transmit
    SpiaRegs.SPICTL.bit.SPIINTENA = 0;//disable SPI interrupt

    //SpiaRegs.SPISTS.all = 0;

    //baud rate register(9 bits reserved,0000 0000 0000 007C)
    /*
     * LSPCLKfreq=CPUfreq/n //(n=1,2,4,6,8,10,12,14)
     * SPI Baud Rate=LSPCLKfreq/(SPIBRR+1)
     * without adding an external auxiliary clock
     * The CPU frequency of F28379D is 10MHz, the corresponding minimum low-speed peripheral clock is 715KHz, and the minimum baud rate is 5586SPS
     * This minimum baud rate is greater than the maximum baud rate 4000SPS when FIR filter mode is selected
     * Therefore, the Sinc filter mode is selected, the baud rate is set to 8000SPS, and the frequency is divided by 10,SPIBRR=124=0x007C
     */

    EALLOW;
    ClkCfgRegs.LOSPCP.all = 0x0005;//101(divide by 10)
    EDIS;

    SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 0x007C;

    //Priority Control Register
    SpiaRegs.SPIPRI.bit.FREE = 1;//Free run during simulation, pause on breakpoint does not stop SPI

    //Stop SPI software reset ready to receive or transmit
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}

void spia_xmit(Uint8 a)
{
    SpiaRegs.SPITXBUF = a;//Pass 8-bit data to serial transmit buffer

}

用于 SPIA 主器件 SPIB 从器件测试的连接:

SPIA CLK-SPIB CLK

SPIA SIMO-SPIB SOMI

SPIA SOMI-SPIB SIMO

SCLK 波形与 SPIA 波形相同、但在正常运行一段时间后、调试接口显示 RDATA 始终为 FFFF、SpiaRegs.spits 位.INT_flag 始终为1、而 while 环路不能跳出。 这应该如何解决?

针对 SPIA 主器件和 SPIB 从器件的程序:

/*
 *
 *
 */

#include "F28x_Project.h"

typedef unsigned char Uint8;



void gpio_init();
void spia_init();
void spia_xmit(Uint8 a);
void spib_init();
void spib_xmit(Uint8 a);



char sdata;
char rdata;

int i;

void main()
{
    
    InitSysCtrl();
    InitGpio();//GPIO
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();


    gpio_init();


    spia_init();
    spib_init();

    sdata = 0x0000;
    rdata = 0x0000;

    for(;;)
    {
        spia_xmit(sdata);
        while(SpibRegs.SPISTS.bit.INT_FLAG != 1){}
        rdata = SpibRegs.SPIRXBUF;
        sdata++;

    }


}

void gpio_init()
{
    /*
     * 60   SPICLKA_DA     SPIA CLK
     * 59   SPISOMIA_DA    SPIA SOMI
     * 58   SPISIMOA_DA    SPIA SIMO
     *
     * 65   SPICLKB_AD     SPIB CLK
     * 64   SPISOMIB_AD    SPIB SOMI
     * 63   SPISIMOB_AD    SPIB SIMO
     */

    EALLOW;

    //SPI
    //DA
    GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;
    GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3;
    GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3;
    GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3;//SPICLKA

    GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;
    GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3;
    GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3;
    GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3;//SPISOMIA

    GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;
    GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3;
    GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3;
    GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3;//SPISIMOA

    //SPI
    //DA
    GpioCtrlRegs.GPCPUD.bit.GPIO65 = 0;
    GpioCtrlRegs.GPCQSEL1.bit.GPIO65 = 3;
    GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 3;
    GpioCtrlRegs.GPCGMUX1.bit.GPIO65 = 3;//SPICLKB

    GpioCtrlRegs.GPCPUD.bit.GPIO64 = 0;
    GpioCtrlRegs.GPCQSEL1.bit.GPIO64 = 3;
    GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 3;
    GpioCtrlRegs.GPCGMUX1.bit.GPIO64 = 3;//SPISOMIB

    GpioCtrlRegs.GPBPUD.bit.GPIO63 = 0;
    GpioCtrlRegs.GPBQSEL2.bit.GPIO63 = 3;
    GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 3;
    GpioCtrlRegs.GPBGMUX2.bit.GPIO63 = 3;//SPISIMOB

    EDIS;

}

void spia_init()
{
    
    
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
    SpiaRegs.SPICCR.bit.HS_MODE = 0;
    SpiaRegs.SPICCR.bit.SPILBK = 1;
    SpiaRegs.SPICCR.bit.SPICHAR = (8-1);

    
    SpiaRegs.SPICTL.bit.OVERRUNINTENA = 1;
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;//MCU master
    SpiaRegs.SPICTL.bit.TALK = 1;
    SpiaRegs.SPICTL.bit.SPIINTENA = 0;

    //SpiaRegs.SPISTS.all = 0;

    
    /*
     * LSPCLKfreq=CPUfreq/n //(n=1,2,4,6,8,10,12,14)
     * SPI Baud Rate=LSPCLKfreq/(SPIBRR+1)
     * 
     * 
     * 
     * 
     */

    EALLOW;
    ClkCfgRegs.LOSPCP.all = 0x0005;//101
    EDIS;

    SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 0x007C;

    
    SpiaRegs.SPIPRI.bit.FREE = 1;

    
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;
}

void spib_init()
{
    
    
    SpibRegs.SPICCR.bit.SPISWRESET = 0;
    SpibRegs.SPICCR.bit.CLKPOLARITY = 0;
    SpibRegs.SPICCR.bit.HS_MODE = 0;
    SpibRegs.SPICCR.bit.SPILBK = 1;
    SpibRegs.SPICCR.bit.SPICHAR = (8-1);

    
    SpibRegs.SPICTL.bit.OVERRUNINTENA = 1;
    SpibRegs.SPICTL.bit.CLK_PHASE = 0;
    SpibRegs.SPICTL.bit.MASTER_SLAVE = 0;//MCU master
    SpibRegs.SPICTL.bit.TALK = 1;
    SpibRegs.SPICTL.bit.SPIINTENA = 0;

    //SpiaRegs.SPISTS.all = 0;

    
    /*
     * LSPCLKfreq=CPUfreq/n //(n=1,2,4,6,8,10,12,14)
     * SPI Baud Rate=LSPCLKfreq/(SPIBRR+1)
     * 
     * 
     * 
     * 
     */

    EALLOW;
    ClkCfgRegs.LOSPCP.all = 0x0005;//101
    EDIS;

    SpibRegs.SPIBRR.bit.SPI_BIT_RATE = 0x007C;

    
    SpibRegs.SPIPRI.bit.FREE = 1;

    
    SpibRegs.SPICCR.bit.SPISWRESET = 1;
}

void spia_xmit(Uint8 a)
{
    SpiaRegs.SPITXBUF = a;

}

谢谢、此致

耶鲁李

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yale、

    [引用 userid="514648" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1135838/tms320f28379d-spi-timing-issues ]SPIA 自接收和自检期间 CCS 调试接口正常显示。 示波器测量 SCLK、如下图所示、8个脉冲在一组中、单个脉冲的宽度为12.4us (高电平和低电平时间均为6.2us)、但每组脉冲之间将有31.4us 的时间间隔。 这是否正常?

    时间对我来说似乎是正确的。 您的 SPICLK 看起来以80.6kHz 的频率运行。 由于 LSPCLK 设置为/10并且 BRR 设置为124、这意味着您的 MCU SYSCLK 以80.6kHz *(124+1)*(10)= 100MHz 的频率运行。 根据您的期望、这听起来是否正确?

    "分组"也是正常的、因为您在 SPI 配置中未使用 FIFO 模式。  如果需要连续数据、则必须启用 FIFO 模式。 C2000ware 中提供了几个示例、可为您展示如何执行该操作。

    [引用 userid="514648" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1135838/tms320f28379d-spi-timing-issues ]*测量了 SIMO 引脚、发现它将继续发送相同的数据。 测量时间约为32.3ms、数据重复约243次。 如何解决此问题?[/quot]

    在 SPIA_xmit 代码中、您要向 uint16寄存器写入 uint8值。 我认为编译器应该已经标记了有关这一点的警告。 由于 SPI 配置为8位、并且 SPITXBUF 的 MSB 始终首先移出、因此您还需要将数据移动<< 8 (有关更多信息、请参阅 TRM)。 下面是我认为您的代码应该是什么样的:

    void spia_xmit(Uint8 a)
    {
    SpiaRegs.SPITXBUF = (Uint16)(a<<8);//Pass 8-bit data to serial transmit buffer
    
    }

    [引用 userid="514648" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1135838/tms320f28379d-spi-timing-issues ]SCLK 波形与 SPIA 波形相同、但在正常运行一段时间后、调试接口会显示 RDATA 始终为 FFFF、SpiaRegs.spit.bit.INT_flag 始终为1、并且无法跳出 while 环路。 如何解决此问题?[/报价]

    我没有看到您的 spib_xmit()代码,因此不太确定问题可能是什么。 但假设您使用的代码与 SPIA_xmit()类似,则需要进行与上述相同的更改。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Gus、

    感谢您的回复。

    我的客户如您所说修改了 SPIA_xmit ()和 spib_xmit ()、并在 main 函数中添加了将数据从 spib 发送到 SPIA 的代码。  但是、调试接口显示 SPIA 可以正常接收 spib 的数据、而 spib 的 RXBUF 仍然始终为 FF。

    以下是修改后的程序:

    /*
     * 
     *
     */
    
    #include "F28x_Project.h"
    
    typedef unsigned char Uint8;
    
    
    
    void gpio_init();
    void spia_init();
    void spia_xmit(Uint8 a);
    void spib_init();
    void spib_xmit(Uint8 a);
    
    
    
    char sdata;
    char rdata;
    
    void main()
    {
        
        InitSysCtrl();
        InitGpio();
        DINT;
        InitPieCtrl();
        IER = 0x0000;
        IFR = 0x0000;
        InitPieVectTable();
    
    
        gpio_init();
    
    
        spia_init();
        spib_init();
    
        sdata = 0x0000;
        rdata = 0x0000;
    
        for(;;)
        {
            spia_xmit(sdata);
            while(SpibRegs.SPISTS.bit.INT_FLAG != 1){}
            rdata = SpibRegs.SPIRXBUF;
            spib_xmit(sdata);
            while(SpiaRegs.SPISTS.bit.INT_FLAG != 1){}
            char rdataa = SpiaRegs.SPIRXBUF;
            sdata++;
    
        }
    
    
    }
    
    void gpio_init()
    {
        /* 
         * 60   SPICLKA_DA     SPIA CLK
         * 59   SPISOMIA_DA    SPIA SOMI
         * 58   SPISIMOA_DA    SPIA SIMO
         *
         * 65   SPICLKB_AD     SPIB CLK
         * 64   SPISOMIB_AD    SPIB SOMI
         * 63   SPISIMOB_AD    SPIB SIMO
         */
    
        EALLOW;
    
        //SPI
        //DA
        GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;
        GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3;
        GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3;
        GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3;//SPICLKA
    
        GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;
        GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3;
        GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3;
        GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3;//SPISOMIA
    
        GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;
        GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3;
        GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3;
        GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3;//SPISIMOA
    
        //SPI
        //DA
        GpioCtrlRegs.GPCPUD.bit.GPIO65 = 0;
        GpioCtrlRegs.GPCQSEL1.bit.GPIO65 = 3;
        GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 3;
        GpioCtrlRegs.GPCGMUX1.bit.GPIO65 = 3;//SPICLKB
    
        GpioCtrlRegs.GPCPUD.bit.GPIO64 = 0;
        GpioCtrlRegs.GPCQSEL1.bit.GPIO64 = 3;
        GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 3;
        GpioCtrlRegs.GPCGMUX1.bit.GPIO64 = 3;//SPISOMIB
    
        GpioCtrlRegs.GPBPUD.bit.GPIO63 = 0;
        GpioCtrlRegs.GPBQSEL2.bit.GPIO63 = 3;
        GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 3;
        GpioCtrlRegs.GPBGMUX2.bit.GPIO63 = 3;//SPISIMOB
    
        EDIS;
    
    }
    
    void spia_init()
    {
        
        
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpiaRegs.SPICCR.bit.HS_MODE = 0;
        SpiaRegs.SPICCR.bit.SPILBK = 1;
        SpiaRegs.SPICCR.bit.SPICHAR = (8-1);
    
        
        SpiaRegs.SPICTL.bit.OVERRUNINTENA = 1;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.TALK = 1;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
    
        //SpiaRegs.SPISTS.all = 0;
    
        
        /*
         * LSPCLKfreq=CPUfreq/n //(n=1,2,4,6,8,10,12,14)
         * SPI Baud Rate=LSPCLKfreq/(SPIBRR+1)
         * 
         * 
         * 
         * 
         */
    
        EALLOW;
        ClkCfgRegs.LOSPCP.all = 0x0005;//101(10分频)
        EDIS;
    
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 0x007C;
    
        
        SpiaRegs.SPIPRI.bit.FREE = 1;
    
        
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;
    }
    
    void spib_init()
    {
        
        
        SpibRegs.SPICCR.bit.SPISWRESET = 0;
        SpibRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpibRegs.SPICCR.bit.HS_MODE = 0;
        SpibRegs.SPICCR.bit.SPILBK = 1;
        SpibRegs.SPICCR.bit.SPICHAR = (8-1);
    
        
        SpibRegs.SPICTL.bit.OVERRUNINTENA = 1;
        SpibRegs.SPICTL.bit.CLK_PHASE = 0;
        SpibRegs.SPICTL.bit.MASTER_SLAVE = 0;
        SpibRegs.SPICTL.bit.TALK = 1;
        SpibRegs.SPICTL.bit.SPIINTENA = 0;
    
        //SpiaRegs.SPISTS.all = 0;
    
        
        /*
         * LSPCLKfreq=CPUfreq/n //(n=1,2,4,6,8,10,12,14)
         * SPI Baud Rate=LSPCLKfreq/(SPIBRR+1)
         * 
         * 
         * 
         * 
         */
    
        EALLOW;
        ClkCfgRegs.LOSPCP.all = 0x0005;
        EDIS;
    
        SpibRegs.SPIBRR.bit.SPI_BIT_RATE = 0x007C;
    
        
        SpibRegs.SPIPRI.bit.FREE = 1;
    
        
        SpibRegs.SPICCR.bit.SPISWRESET = 1;
    }
    
    void spia_xmit(Uint8 a)
    {
        SpiaRegs.SPITXBUF = (Uint16)(a<<8);
    
    }
    
    void spib_xmit(Uint8 b)
    {
        SpibRegs.SPITXBUF = (Uint16)(b<<8);
    
    }

    这种情况的原因是什么?

    谢谢、此致

    耶鲁李

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    耶鲁大学

    客户在 SPIA 和 spib 中都启用了环回模式。 应为两个接口禁用 Looback 模式。

    SpibRegs.SPICCR.bit.SPILBK = 1;

    SpiaRegs.SPICCR.bit.SPILBK = 1;

    来自 TRM:

    环回模式允许在器件测试期间进行模块验证。 此模式仅在 SPI 的主模式下有效。

    • 复位类型:SYSRSn
    • 0h (R/W)=禁用 SPI 环回模式。 这是复位后的默认值。
    • 1h (R/W)=启用 SPI 回路模式、SIMO/SOMI 线路在内部连接。 用于模块自检。