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.

28335的spi,配置成从模式后,没法发送数据

我使用的是spia,配置为从模式,使用的是这几个引脚。

GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 1;  
GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 1;  
GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 1; 
GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 1; 

从主机往f28335发送数据,从机这边能够正确的收到数据。

但是从机在中断里面使用如下语句,往主机回数据会出现问题:

__interrupt void
spiRxFifoIsr(void)
{
rdata[idx]=SpiaRegs.SPIRXBUF&0xff;
idx++;
SpiaRegs.SPITXBUF='R';
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flag
SpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flag
PieCtrlRegs.PIEACK.all|=0x20; // Issue PIE ack
}

理论上miso信号线上会有波形。但是实测却没有。导致主机收不到任何数据。

FIFO初始化代码如下:


//
// spi_fifo_init -
//
void
spi_fifo_init()
{
//
// Initialize SPI FIFO registers
//
SpiaRegs.***.bit.SPISWRESET=0; // Reset SPI

SpiaRegs.***.bit.***=7; //数据宽度
SpiaRegs.***.bit.CLKPOLARITY=0; //时钟极性

SpiaRegs.***.bit.SPIINTENA=1;
SpiaRegs.***.bit.MASTER_SLAVE=0;
SpiaRegs.***.bit.TALK=1;
SpiaRegs.***.bit.CLK_PHASE=1; //时钟相位
SpiaRegs.***.bit.OVERRUNINTENA=1;

SpiaRegs.SPISTS.all=0x0000;

SpiaRegs.SPIFFTX.bit.SPIRST=1;
SpiaRegs.SPIFFTX.bit.TXFFIL=8;
SpiaRegs.SPIFFTX.bit.TXFFIENA=0;
SpiaRegs.SPIFFTX.bit.SPIFFENA=1;
SpiaRegs.SPIFFTX.bit.TXFIFO=1;
SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1;

SpiaRegs.SPIFFRX.bit.RXFFIL=1;
SpiaRegs.SPIFFRX.bit.RXFFIENA=1;
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1;

SpiaRegs.SPIPRI.all=0;
SpiaRegs.SPIPRI.bit.FREE = 1; // 11 mode -
SpiaRegs.SPIPRI.bit.SOFT = 1; // 11 mode -

SpiaRegs.SPIFFCT.all=0x00;
SpiaRegs.SPIPRI.all=0x0010;
SpiaRegs.***.bit.SPISWRESET=1; // Enable SPI
SpiaRegs.SPIFFTX.bit.TXFIFO=1;
SpiaRegs.SPIFFRX.bit.RXFIFORESET=1;
}

IO的初始化应该没问题的,因为我将cpu暂停,这个时候可以从miso获取到跟mosi延迟一个byte的数据。

请各位帮忙看看,我这个问题出自哪里?谢谢!

  • 您可以参考一下下面的程序,是基于28346测试的,自己的SPIA发送,SPID接收。

    Example_2834xSpi_FFDLB_int.c
    // TI File $Revision: /main/3 $
    // Checkin $Date: June 28, 2010   09:18:54 $
    //###########################################################################
    //
    // FILE:   Example_2834xSpi_FFDLB_int.c
    //
    // TITLE:  DSP2834x Device Spi Digital Loop Back with Interrupts Example.
    //
    // ASSUMPTIONS:
    //
    //    This program requires the DSP2834x header files.
    //
    //    This program uses the internal loop back test mode of the peripheral.
    //    Other then boot mode pin configuration, no other hardware configuration
    //    is required.
    //
    //    As supplied, this project is configured for "boot to SARAM"
    //    operation.  The 2834x Boot Mode table is shown below.
    //    For information on configuring the boot mode of an eZdsp,
    //    please refer to the documentation included with the eZdsp,
    //
    //       $Boot_Table:
    //
    //         GPIO87   GPIO86     GPIO85   GPIO84
    //          XA15     XA14       XA13     XA12
    //           PU       PU         PU       PU
    //        ==========================================
    //            1        1          1        1    TI Test Only
    //            1        1          1        0    SCI-A boot
    //            1        1          0        1    SPI-A boot
    //            1        1          0        0    I2C-A boot timing 1
    //            1        0          1        1    eCAN-A boot timing 1
    //            1        0          1        0    McBSP-A boot
    //            1        0          0        1    Jump to XINTF x16
    //            1        0          0        0    Jump to XINTF x32
    //            0        1          1        1    eCAN-A boot timing 2
    //            0        1          1        0    Parallel GPIO I/O boot
    //            0        1          0        1    Parallel XINTF boot
    //            0        1          0        0    Jump to SARAM	    <- "boot to SARAM"
    //            0        0          1        1    Branch to check boot mode
    //            0        0          1        0    I2C-A boot timing 2
    //            0        0          0        1    Reserved
    //            0        0          0        0    TI Test Only
    //                                              Boot_Table_End$$
    //
    // DESCRIPTION:
    //
    //    This program is a SPI-A example that uses the internal loopback of
    //    the peripheral.  Both interrupts and the SPI FIFOs are used.
    //
    //    A stream of data is sent and then compared to the recieved stream.
    //
    //    The sent data looks like this:
    //    0000 0001 0002 0003 0004 0005 0006 0007
    //    0001 0002 0003 0004 0005 0006 0007 0008
    //    0002 0003 0004 0005 0006 0007 0008 0009
    //    ....
    //    FFFE FFFF 0000 0001 0002 0003 0004 0005
    //    FFFF 0000 0001 0002 0003 0004 0005 0006
    //     etc..
    //
    //    This pattern is repeated forever.
    //
    //
    // Watch Variables:
    //     sdata[8]    - Data to send
    //     rdata[8]    - Received data
    //     rdata_point - Used to keep track of the last position in
    //                   the receive stream for error checking
    //###########################################################################
    //
    // Original Source by S.D.
    //
    // $TI Release: 2834x Header Files V1.12 $
    // $Release Date: March 2011 $
    //###########################################################################
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    // Prototype statements for functions found within this file.
    // interrupt void ISRTimer2(void);
    interrupt void spiTxFifoIsr(void);
    interrupt void spiRxFifoIsr(void);
    interrupt void spidTxFifoIsr(void);
    interrupt void spidRxFifoIsr(void);
    void delay_loop(void);
    void spi_fifo_init(void);
    void error();
    
    
    Uint16 sdata_spia[8];     // Send data buffer
    Uint16 rdata_spia[8];     // Receive data buffer
    
    Uint16 sdata_spid[8];     // Send data buffer
    Uint16 rdata_spid[8];     // Receive data buffer
    
    Uint16 rdata_point;  // Keep track of where we are
                         // in the data stream to check received data
    
    void main(void)
    {
       Uint16 i;
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2834x_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initalize GPIO:
    // This example function is found in the DSP2834x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    // Setup only the GP I/O only for SPI-A functionality
       InitSpiGpio();
    
    // Step 3. Initialize PIE vector table:
    // Disable and clear all CPU interrupts
       DINT;
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize PIE control registers to their default state:
    // This function is found in the DSP2834x_PieCtrl.c file.
       InitPieCtrl();
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2834x_DefaultIsr.c.
    // This function is found in DSP2834x_PieVect.c.
       InitPieVectTable();
    
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
       EALLOW;	// This is needed to write to EALLOW protected registers
       PieVectTable.SPIRXINTA = &spiRxFifoIsr;
       PieVectTable.SPITXINTA = &spiTxFifoIsr;
       PieVectTable.SPIRXINTD = &spidRxFifoIsr;
       PieVectTable.SPITXINTD = &spidTxFifoIsr;
       EDIS;   // This is needed to disable write to EALLOW protected registers
    
    
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP2834x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
       spi_fifo_init();	  // Initialize the SPI only
    
    
    // Step 5. User specific code, enable interrupts:
    
    // Initalize the send data buffer
    
    
          sdata_spia[0] = 0x1100;
          sdata_spia[1] = 0x2200;
          sdata_spia[2] = 0x3300;
          sdata_spia[3] = 0x4400;
          sdata_spia[4] = 0x5500;
          sdata_spia[5] = 0x6600;
          sdata_spia[6] = 0x7700;
          sdata_spia[7] = 0x8800;
    
    
    
    
          sdata_spid[0] = 0x9900;
          sdata_spid[1] = 0xAA00;
          sdata_spid[2] = 0xBB00;
          sdata_spid[3] = 0xCC00;
          sdata_spid[4] = 0xDD00;
          sdata_spid[5] = 0xEE00;
          sdata_spid[6] = 0xFF00;
          sdata_spid[7] = 0x0000;
    
    
    
    
    
    
    
    
    
    
    
       rdata_point = 0;
    
    // Enable interrupts required for this example
       PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
       PieCtrlRegs.PIEIER6.bit.INTx1=1;     // Enable PIE Group 6, INT 1
       PieCtrlRegs.PIEIER6.bit.INTx2=1;     // Enable PIE Group 6, INT 2
       PieCtrlRegs.PIEIER6.bit.INTx7=1;     // Enable PIE Group 6, INT 1
       PieCtrlRegs.PIEIER6.bit.INTx8=1;     // Enable PIE Group 6, INT 2
       IER=0x20;                            // Enable CPU INT6
       EINT;                                // Enable Global Interrupts
    
    // Step 6. IDLE loop. Just sit and loop forever (optional):
    	for(;;);
    
    }
    
    
    // Some Useful local functions
    void delay_loop()
    {
        long      i;
        for (i = 0; i < 1000000; i++) {}
    }
    
    
    void error(void)
    {
        asm("     ESTOP0");	 //Test failed!! Stop!
        for (;;);
    }
    
    
    void spi_fifo_init()
    {
    // Initialize SPI FIFO registers
       SpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
    
       SpiaRegs.SPICCR.all=0x000F;       //16-bit character,
       SpiaRegs.SPICTL.all=0x0017;       //Interrupt enabled, Master XMIT enabled
       SpiaRegs.SPISTS.all=0x0000;
       SpiaRegs.SPIBRR=0x00F;           // Baud rate
       SpiaRegs.SPIFFTX.all=0xC028;      // Enable FIFO's, set TX FIFO level to 8
       SpiaRegs.SPIFFRX.all=0x0028;      // Set RX FIFO level to 8
       SpiaRegs.SPIFFCT.all=0x00;
       SpiaRegs.SPIPRI.all=0x0010;
    
       SpiaRegs.SPICCR.bit.SPISWRESET=1;  // Enable SPI
    
       SpiaRegs.SPIFFTX.bit.TXFIFO=1;
       SpiaRegs.SPIFFRX.bit.RXFIFORESET=1;
    
       SpidRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
    
       SpidRegs.SPICCR.all=0x000F;       //16-bit character,
       SpidRegs.SPICTL.all=0x0013;       //Interrupt enabled, Slave XMIT enabled
       SpidRegs.SPISTS.all=0x0000;
       SpidRegs.SPIBRR=0x00F;           // Baud rate
       SpidRegs.SPIFFTX.all=0xC028;      // Enable FIFO's, set TX FIFO level to 8
       SpidRegs.SPIFFRX.all=0x0028;      // Set RX FIFO level to 8
       SpidRegs.SPIFFCT.all=0x00;
       SpidRegs.SPIPRI.all=0x0010;
    
       SpidRegs.SPICCR.bit.SPISWRESET=1;  // Enable SPI
    
       SpidRegs.SPIFFTX.bit.TXFIFO=1;
       SpidRegs.SPIFFRX.bit.RXFIFORESET=1;
    }
    
    interrupt void spiTxFifoIsr(void)
    {
     	Uint16 i;
        for(i=0;i<8;i++)
        {
     	   SpiaRegs.SPITXBUF=sdata_spia[i];      // Send data
        }
    
        for(i=0;i<8;i++)                    // Increment data for next cycle
        {
        	sdata_spia[i]++;
        }
    
    
        SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1;  // Clear Interrupt flag
    	PieCtrlRegs.PIEACK.all|=0x20;  		// Issue PIE ACK
    }
    
    interrupt void spiRxFifoIsr(void)
    {
        Uint16 i;
        for(i=0;i<8;i++)
        {
    	    rdata_spia[i]=SpiaRegs.SPIRXBUF;		// Read data
    	}
    
    	rdata_point++;
    	SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1;  // Clear Overflow flag
    	SpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; 	// Clear Interrupt flag
    	PieCtrlRegs.PIEACK.all|=0x20;       // Issue PIE ack
    }
    
    interrupt void spidTxFifoIsr(void)
    {
     	Uint16 i;
        for(i=0;i<8;i++)
        {
     	   SpidRegs.SPITXBUF=sdata_spid[i];      // Send data
        }
    
        for(i=0;i<8;i++)                    // Increment data for next cycle
        {
     	   sdata_spid[i]++;
        }
    
    
        SpidRegs.SPIFFTX.bit.TXFFINTCLR=1;  // Clear Interrupt flag
    	PieCtrlRegs.PIEACK.all|=0x20;  		// Issue PIE ACK
    }
    
    interrupt void spidRxFifoIsr(void)
    {
        Uint16 i;
        for(i=0;i<8;i++)
        {
    	    rdata_spid[i]=SpidRegs.SPIRXBUF;		// Read data
    	}
    
    	rdata_point++;
    	SpidRegs.SPIFFRX.bit.RXFFOVFCLR=1;  // Clear Overflow flag
    	SpidRegs.SPIFFRX.bit.RXFFINTCLR=1; 	// Clear Interrupt flag
    	PieCtrlRegs.PIEACK.all|=0x20;       // Issue PIE ack
    }
    
    //===========================================================================
    // No more.
    //===========================================================================
    
    

    另外您也可以参考C \ ti \ controlSUITE \ device_support \ f2833x \ v142 \ DSP2833x_examples_ccsv5 \内的SPI程序,但需要将示例从主模式更改为从模式。 附上SPI参考指南

    6114.3000.TI_SPI_2833x_sprueu3a.pdf

  • 你最好看一下波形 从机发送也即是使用的主机的clk进行数据传输的
    看看时钟 使能等时序对不