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.
f28035 关于SPI 通信 程序目 读取外部18位数据 ,应为SPI 最长支持 16 位,所有本人想用 FIFO 同时送2个9位的数据出去。程序如下
初始化程序
{
s->***.bit.SPISWRESET = 0; // Put SPI in reset state
s->***.bit.*** = 0x8; // 9-bit character
s->***.bit.SPILBK = 0; // loopback off
s->***.bit.CLKPOLARITY = 1; // Rising edge without delay
s->***.bit.SPIINTENA = 0; // disable SPI interrupt
s->***.bit.TALK = 1; // enable transmission
s->***.bit.MASTER_SLAVE = 1; // master
s->***.bit.CLK_PHASE = 0; // Rising edge without delay
s->***.bit.OVERRUNINTENA = 0; // disable reciever overrun interrupt
s->SPIBRR = 20; // *** = LSPCLK / 4 (max ***)
s->SPIPRI.bit.SOFT=1; //停止前完成当前的接收 、发送操作
s->SPIPRI.bit.FREE=0;
s->SPIFFTX.bit.TXFFST=2; //发送FIFO具有2个字
s->SPIFFRX.bit.RXFFST=2; //接收FIFO具有2个字
s->***.bit.SPISWRESET=1; // Enable SPI
}
下面是输出的读入程序
{
s->SPITXBUF = 1; //send out the data
s->SPITXBUF = 1; //send out the data
while(s->SPISTS.bit.INT_FLAG == 0); //wait for the packet to complete
stat_reg1 = s->SPIRXBUF; //dummy read to clear the INT_FLAG bit
stat_reg2 = s->SPIRXBUF;
}
进过测试,发现。这个程序 要求输出9*2=18位的 数据,但是在连续相 (s->SPITXBUF = 1; //send out the data
s->SPITXBUF = 1; //send out the data) 写2个9位的数据,结果 发现 输出了 9*3=27个时钟信号。
如果每次穿一个
(s->SPITXBUF = 1; //send out the data
while(s->SPISTS.bit.INT_FLAG == 0);
s->SPITXBUF = 1; //send out the data
) while(s->SPISTS.bit.INT_FLAG == 0);,能输出2* 9个脉冲
请高手给指教一下
目的是为了传输 一个18位的数据,应为 SPI 最多只支持16 位,所有就想用传 2个9 位输出 来合成一个18位的数据,上门的出现 测试以后发现,输出了27位数据。
是哪个地方出了问啊啊
我没发现错误。
不应该发送 输出了 9*3=27个时钟信号。是否是算错了?如下面这样写的话是否能只看到18个?
{
s->SPITXBUF = 1; //send out the data
s->SPITXBUF = 1; //send out the data
while(s->SPISTS.bit.INT_FLAG == 0); //wait for the packet to complete
for(i=0;i<1000;i++);
stat_reg1 = s->SPIRXBUF; //dummy read to clear the INT_FLAG bit
stat_reg2 = s->SPIRXBUF;
}
现在又遇到一个问题,
stat_reg1 = s->SPIRXBUF; //dummy read to clear the INT_FLAG bit
stat_reg2 = s->SPIRXBUF;
读出来的是一样的。
目的应该要重 从机读出 一个18 位的 数据
通过以上的修改,加入延时程序以后,可以输出准确的18个脉冲,
但是 用过上面的程序读取 输入回来的数据,发现是一样的。
stat_reg1 = s->SPIRXBUF; //dummy read to clear the INT_FLAG bit
stat_reg2 = s->SPIRXBUF
我这程序里面还有一个10KHZ 的中断程序
请教技术支持!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
通过上面一些方法的 测试,现在出现 已经可以 输出连续的18个脉冲时钟, 从设备也你能 正常回传 18位的数据,
现在的 初始化和 读程序如下。
但是还是发现了一个问题,依然没有解决,就是 通过读输入的 数据,发现 2个临时变量的 数据是一样的。
程序如下:
s->SPICCR.bit.SPISWRESET = 0; // Put SPI in reset state
s->SPICCR.bit.SPICHAR = 0x8; // 9-bit character//////////////////
s->SPICCR.bit.SPILBK = 0; // loopback off
s->SPICCR.bit.CLKPOLARITY = 1; // Rising edge without delay
s->SPICTL.bit.SPIINTENA = 0; // disable SPI interrupt
s->SPICTL.bit.TALK = 1; // enable transmission
s->SPICTL.bit.MASTER_SLAVE = 1; // master
s->SPICTL.bit.CLK_PHASE = 0; // Rising edge without delay
s->SPICTL.bit.OVERRUNINTENA = 0; // disable reciever overrun interrupt
s->SPIBRR = 20; // SPICLK = LSPCLK / 4 (max SPICLK)
s->SPIPRI.bit.SOFT=1; //停止前完成当前的接收 、发送操作
s->SPIPRI.bit.FREE=0; //
s->SPIFFTX.bit.TXFFST=2; //发送FIFO具有2个字///////////////////
//s->SPIFFTX.bit.TXFFIL=2;
s->SPIFFRX.bit.RXFFST=2; //接收FIFO具有2个字///////////////
//s->SPIFFRX.bit.RXFFIL=2;
s->SPIFFTX.bit.TXFFIENA=1; ////发送FIFO中断使能//////////////////
s->SPIFFRX.bit.RXFFIENA=1; ///接收FIFO 中断使能
s->SPICCR.bit.SPISWRESET=1; // Enable SPI
下面是 通信程序。
s->SPITXBUF = 0; //send out the data
s->SPITXBUF = 0; //send out the data
while(s->SPISTS.bit.INT_FLAG == 0); //wait for the packet to complete
for(i=0;i<10;i++);
stat_reg1 = s->SPIRXBUF;
stat_reg2 = s->SPIRXBUF;
以上数据通过示波器观察已经确定。 现在依然是 读回的2个数据一样。、
在两个读入中间加 延时倒是可以读取,
stat_reg1 = s->SPIRXBUF;
for(i=0;i<100;i++);
stat_reg2 = s->SPIRXBUF;
但是因为程序里面有 1个10Khz 的中断。要产生,还是会产生读出的 数据会有错误
因为s->SPISTS.bit.INT_FLAG 中断标志的产生会在每个数据接收9位完都会产生,
所以,要想读取 18位数据,就需要分2次读取。如果这2次读取的数据间隔时间短,就会出现2次读回一样的数据。
如个使用2个FIFIO 来保持接收的数据,不知道是否可以。现在程序也已经定了2个FIFO 但是在数据读取方面还是不行
我试了一下,能够正常读取,2个数据不一样。附件是我试的程序,是在TI的例程基础上改的,您请看一下。
//########################################################################### // //! \addtogroup f2803x_example_list //! <h1>SPI Digital Loop Back(spi_loopback)</h1> //! //! This program uses the internal loop back test mode of the peripheral. //! Other then boot mode pin configuration, no other hardware configuration //! is required. Interrupts are not used. //! //! A stream of data is sent and then compared to the received stream. //! The sent data looks like this: \n //! 0000 0001 0002 0003 0004 0005 0006 0007 .... FFFE FFFF \n //! This pattern is repeated forever. //! //! \b Watch \b Variables \n //! - \b sdata , sent data //! - \b rdata , received data // ////########################################################################### // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V126 $ // $Release Date: November 30, 2011 $ //########################################################################### #include "DSP28x_Project.h" // Device Headerfile and Examples Include File // Prototype statements for functions found within this file. void spi_xmit(Uint16 a); void spi_fifo_init(void); void spi_init(void); void error(void); void main(void) { Uint16 sdata; // send data Uint16 rdata; // received data Uint16 stat_reg1,stat_reg2; Uint16 K1=0X111; Uint16 K2=0X022; int i; // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the DSP2803x_SysCtrl.c file. InitSysCtrl(); // Step 2. Initalize GPIO: // This example function is found in the DSP2803x_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 // This function is found in DSP2803x_Spi.c InitSpiaGpio(); // Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interrupts DINT; // Initialize PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared. // This function is found in the DSP2803x_PieCtrl.c file. InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000; // 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 DSP2803x_DefaultIsr.c. // This function is found in DSP2803x_PieVect.c. InitPieVectTable(); // Step 4. Initialize all the Device Peripherals: // This function is found in DSP2803x_InitPeripherals.c // InitPeripherals(); // Not required for this example spi_fifo_init(); // Initialize the Spi FIFO spi_init(); // init SPI // Step 5. User specific code: // Interrupts are not used in this example. sdata = 0x0000; for(;;) { SpiaRegs.SPITXBUF = K1; //send out the data SpiaRegs.SPITXBUF = K2; //send out the data while(SpiaRegs.SPIFFTX.bit.TXFFST != 0){}; //wait for the packet to complete // while(SpiaRegs.SPISTS.bit.INT_FLAG==0){}; for(i=0;i<1000;i++); stat_reg1 = SpiaRegs.SPIRXBUF; //dummy read to clear the INT_FLAG bit stat_reg2 = SpiaRegs.SPIRXBUF; } } // Step 7. Insert all local Interrupt Service Routines (ISRs) and functions here: void error(void) { __asm(" ESTOP0"); // Test failed!! Stop! for (;;); } void spi_init() { /* SpiaRegs.SPICCR.all =0x000F; // Reset on, rising edge, 16-bit char bits SpiaRegs.SPICTL.all =0x0006; // Enable master mode, normal phase, // enable talk, and SPI int disabled. SpiaRegs.SPIBRR =0x007F; SpiaRegs.SPICCR.all =0x009F; // Relinquish SPI from Reset SpiaRegs.SPIPRI.bit.FREE = 1; // Set so breakpoints don't disturb xmission */ SpiaRegs.SPICCR.bit.SPISWRESET = 0; // Put SPI in reset state SpiaRegs.SPICCR.bit.SPICHAR = 0x8; // 9-bit character SpiaRegs.SPICCR.bit.SPILBK = 1; // loopback on SpiaRegs.SPICCR.bit.CLKPOLARITY = 1; // Rising edge without delay SpiaRegs.SPICTL.bit.SPIINTENA = 0; // disable SPI interrupt SpiaRegs.SPICTL.bit.TALK = 1; // enable transmission SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1; // master SpiaRegs.SPICTL.bit.CLK_PHASE = 0; // Rising edge without delay SpiaRegs.SPICTL.bit.OVERRUNINTENA = 0; // disable reciever overrun interrupt SpiaRegs.SPIBRR = 20; // SPICLK = LSPCLK / 4 (max SPICLK) SpiaRegs.SPIPRI.bit.SOFT=1; //ֹͣǰ��ɵ�ǰ�Ľ��� �����Ͳ��� SpiaRegs.SPIPRI.bit.FREE=0; SpiaRegs.SPIFFTX.bit.SPIFFENA=1; SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SPI } void spi_xmit(Uint16 a) { SpiaRegs.SPITXBUF=a; } void spi_fifo_init() { // Initialize SPI FIFO registers SpiaRegs.SPIFFTX.all=0xE040; SpiaRegs.SPIFFRX.all=0x2044; SpiaRegs.SPIFFCT.all=0x0; } //=========================================================================== // No more. //===========================================================================