我用两块28035做SPI通信,一个是主机一个是从机,主机发送的数据没什么问题,但从机在接收一段时间后开始出现数据错位
下面是主从机初始化的函数
if(DeviceType == MasterDevice)
{
SpibRegs.SPIFFTX.all = 0xe000; // 不产生中断,主循环中轮询
SpibRegs.SPIFFRX.all = 0x0024;
SpibRegs.SPIFFCT.all = 0x0000;
SpibRegs.SPICCR.all = 0x000f;
SpibRegs.SPICTL.all = 0x000e;
SpibRegs.SPIBRR = 59; //15m/30
SpibRegs.SPICCR.all =0x008f;
SpibRegs.SPIFFTX.bit.TXFIFO = 1;
SpibRegs.SPIFFRX.bit.RXFIFORESET=1;
GpioDataRegs.GPACLEAR.bit.GPIO15 = 1;
}
else
{
SpibRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
SpibRegs.SPICCR.all=0x000F; //16-bit character
SpibRegs.SPIBRR = 59; //15m/15
SpibRegs.SPIFFTX.all = 0xc001; // SpibRegs.SPIFFRX.all = 0x0024;
SpibRegs.SPIFFCT.all = 0x0000;
SpibRegs.SPICTL.all = 0x000a;
SpibRegs.SPICCR.bit.SPISWRESET=1; // Enable SPI
SpibRegs.SPIFFTX.bit.TXFIFO=1;
SpibRegs.SPIFFRX.bit.RXFIFORESET=1; }
这里我有几个疑问
首先,在时序模式的四种配置中,我选择了CLK_POLARITY = 0;CLK_PHASE = 1;这时候SPI在SPICLK信号第一个上升沿之前的半个周期开始输出数据,在SPICLK信号的上升沿将输入的数据锁存。 这里我有个疑问,我的片选信号一直是拉低的,从机怎么在SPICLK信号第一个上升沿之前半个周期就开始输出数据呢?换句话说,从机只有检测到第一个SPICLK上升沿才知道主机在传输数据,那它怎么会提前半个周期输出数据到SPISOMI呢,未卜先知?。。
第二个问题,在传输数据出现错位后如何清除接收缓冲寄存器和发送缓冲寄存器?我这里用了FIFO缓冲寄存器,对于这个先进先出的寄存器,我总感觉这里的数据没有完全清掉导致的数据错位?
正常的数据
错位的数据
XangYu Zhi:
贴出抓到的信号,一张是正常情况下一张是数据错位的情况
这张是错位的
从上到下的信号分别是CLK ;SIMO; SOMI ;STE
我用两块28035做SPI通信,一个是主机一个是从机,主机发送的数据没什么问题,但从机在接收一段时间后开始出现数据错位
下面是主从机初始化的函数
if(DeviceType == MasterDevice)
{
SpibRegs.SPIFFTX.all = 0xe000; // 不产生中断,主循环中轮询
SpibRegs.SPIFFRX.all = 0x0024;
SpibRegs.SPIFFCT.all = 0x0000;
SpibRegs.SPICCR.all = 0x000f;
SpibRegs.SPICTL.all = 0x000e;
SpibRegs.SPIBRR = 59; //15m/30
SpibRegs.SPICCR.all =0x008f;
SpibRegs.SPIFFTX.bit.TXFIFO = 1;
SpibRegs.SPIFFRX.bit.RXFIFORESET=1;
GpioDataRegs.GPACLEAR.bit.GPIO15 = 1;
}
else
{
SpibRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
SpibRegs.SPICCR.all=0x000F; //16-bit character
SpibRegs.SPIBRR = 59; //15m/15
SpibRegs.SPIFFTX.all = 0xc001; // SpibRegs.SPIFFRX.all = 0x0024;
SpibRegs.SPIFFCT.all = 0x0000;
SpibRegs.SPICTL.all = 0x000a;
SpibRegs.SPICCR.bit.SPISWRESET=1; // Enable SPI
SpibRegs.SPIFFTX.bit.TXFIFO=1;
SpibRegs.SPIFFRX.bit.RXFIFORESET=1; }
这里我有几个疑问
首先,在时序模式的四种配置中,我选择了CLK_POLARITY = 0;CLK_PHASE = 1;这时候SPI在SPICLK信号第一个上升沿之前的半个周期开始输出数据,在SPICLK信号的上升沿将输入的数据锁存。 这里我有个疑问,我的片选信号一直是拉低的,从机怎么在SPICLK信号第一个上升沿之前半个周期就开始输出数据呢?换句话说,从机只有检测到第一个SPICLK上升沿才知道主机在传输数据,那它怎么会提前半个周期输出数据到SPISOMI呢,未卜先知?。。
第二个问题,在传输数据出现错位后如何清除接收缓冲寄存器和发送缓冲寄存器?我这里用了FIFO缓冲寄存器,对于这个先进先出的寄存器,我总感觉这里的数据没有完全清掉导致的数据错位?
正常的数据
错位的数据
Jingang Yang:
回复 XangYu Zhi:
帅哥,你这个问题解决了么?我现在用F28030也遇到同样的问题。
030作为slave,配置为clock_pol=0, phase=0,4级RX fifo中断,在RxFifoIsr()跟controlSUITE的spi loopback interrupt例程一样,把RX FIFO reset 0->1一下。
但实际上还是有错位的情况发生。原因应该跟你猜测的差不多,因为SPIDAT这个移位寄存器是TX/RX公用的,如果前一次移出bit结束后不是预期的位置就会一直影响后续的收和发。
要被搞死了,这么简单一个SPI竟然折腾出这么大的bug
我用两块28035做SPI通信,一个是主机一个是从机,主机发送的数据没什么问题,但从机在接收一段时间后开始出现数据错位
下面是主从机初始化的函数
if(DeviceType == MasterDevice)
{
SpibRegs.SPIFFTX.all = 0xe000; // 不产生中断,主循环中轮询
SpibRegs.SPIFFRX.all = 0x0024;
SpibRegs.SPIFFCT.all = 0x0000;
SpibRegs.SPICCR.all = 0x000f;
SpibRegs.SPICTL.all = 0x000e;
SpibRegs.SPIBRR = 59; //15m/30
SpibRegs.SPICCR.all =0x008f;
SpibRegs.SPIFFTX.bit.TXFIFO = 1;
SpibRegs.SPIFFRX.bit.RXFIFORESET=1;
GpioDataRegs.GPACLEAR.bit.GPIO15 = 1;
}
else
{
SpibRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
SpibRegs.SPICCR.all=0x000F; //16-bit character
SpibRegs.SPIBRR = 59; //15m/15
SpibRegs.SPIFFTX.all = 0xc001; // SpibRegs.SPIFFRX.all = 0x0024;
SpibRegs.SPIFFCT.all = 0x0000;
SpibRegs.SPICTL.all = 0x000a;
SpibRegs.SPICCR.bit.SPISWRESET=1; // Enable SPI
SpibRegs.SPIFFTX.bit.TXFIFO=1;
SpibRegs.SPIFFRX.bit.RXFIFORESET=1; }
这里我有几个疑问
首先,在时序模式的四种配置中,我选择了CLK_POLARITY = 0;CLK_PHASE = 1;这时候SPI在SPICLK信号第一个上升沿之前的半个周期开始输出数据,在SPICLK信号的上升沿将输入的数据锁存。 这里我有个疑问,我的片选信号一直是拉低的,从机怎么在SPICLK信号第一个上升沿之前半个周期就开始输出数据呢?换句话说,从机只有检测到第一个SPICLK上升沿才知道主机在传输数据,那它怎么会提前半个周期输出数据到SPISOMI呢,未卜先知?。。
第二个问题,在传输数据出现错位后如何清除接收缓冲寄存器和发送缓冲寄存器?我这里用了FIFO缓冲寄存器,对于这个先进先出的寄存器,我总感觉这里的数据没有完全清掉导致的数据错位?
正常的数据
错位的数据
Yuchao Zhang:
您好,可否发一下主程序中轮询的程序?是用哪个标志位检测的?
我用两块28035做SPI通信,一个是主机一个是从机,主机发送的数据没什么问题,但从机在接收一段时间后开始出现数据错位
下面是主从机初始化的函数
if(DeviceType == MasterDevice)
{
SpibRegs.SPIFFTX.all = 0xe000; // 不产生中断,主循环中轮询
SpibRegs.SPIFFRX.all = 0x0024;
SpibRegs.SPIFFCT.all = 0x0000;
SpibRegs.SPICCR.all = 0x000f;
SpibRegs.SPICTL.all = 0x000e;
SpibRegs.SPIBRR = 59; //15m/30
SpibRegs.SPICCR.all =0x008f;
SpibRegs.SPIFFTX.bit.TXFIFO = 1;
SpibRegs.SPIFFRX.bit.RXFIFORESET=1;
GpioDataRegs.GPACLEAR.bit.GPIO15 = 1;
}
else
{
SpibRegs.SPICCR.bit.SPISWRESET=0; // Reset SPI
SpibRegs.SPICCR.all=0x000F; //16-bit character
SpibRegs.SPIBRR = 59; //15m/15
SpibRegs.SPIFFTX.all = 0xc001; // SpibRegs.SPIFFRX.all = 0x0024;
SpibRegs.SPIFFCT.all = 0x0000;
SpibRegs.SPICTL.all = 0x000a;
SpibRegs.SPICCR.bit.SPISWRESET=1; // Enable SPI
SpibRegs.SPIFFTX.bit.TXFIFO=1;
SpibRegs.SPIFFRX.bit.RXFIFORESET=1; }
这里我有几个疑问
首先,在时序模式的四种配置中,我选择了CLK_POLARITY = 0;CLK_PHASE = 1;这时候SPI在SPICLK信号第一个上升沿之前的半个周期开始输出数据,在SPICLK信号的上升沿将输入的数据锁存。 这里我有个疑问,我的片选信号一直是拉低的,从机怎么在SPICLK信号第一个上升沿之前半个周期就开始输出数据呢?换句话说,从机只有检测到第一个SPICLK上升沿才知道主机在传输数据,那它怎么会提前半个周期输出数据到SPISOMI呢,未卜先知?。。
第二个问题,在传输数据出现错位后如何清除接收缓冲寄存器和发送缓冲寄存器?我这里用了FIFO缓冲寄存器,对于这个先进先出的寄存器,我总感觉这里的数据没有完全清掉导致的数据错位?
正常的数据
错位的数据
user5247965:
回复 XangYu Zhi:
我也遇到相同的问题,有人回答吗?这个错位,而且没有判读标志让人猝不及防