2012-04-24 122 views
1

我有两个PIC32MX微控制器,它们通过带有芯片选择的1.53MHz的SPI bus连接。我无法使我的从属端中断服务程序正确传输数据。作为一个测试案例,我让主设备每10 ms发送两个字节(0x01,0x00)。从机应接收0x01命令ID,并在主机发送第二个字节(虚拟0x00)时以0x02响应。在PIC32上实现SPI从器件ISR?

理想情况下,每个传输应该看起来像这样。
主从
0×01 0×00
0×00 0×02

我真的不知道从哪里开始从中断虽然。我使用名为airsysTx的fifo缓冲区来保存下次主服务器发出请求时需要移出的数据。从设备从主设备接收到0x01就好了,当它从设备上写入0x02到FIFO缓冲区。我不知道如何对中断进行编码,以确保正确传输。我在下面的代码是一个好的开始,但它是错误的。建议?

/******************************************************************************* 
* Interrupt service routine for SPI3 interrupts from Air MCU. 
* The user's code at this vector should perform any application specific 
* operations and MUST clear the SPI3 interrupt flags before exiting. 
******************************************************************************/ 
void __ISR(_SPI_3_VECTOR, ipl7) _SPI3Interrupt() 
{ 
    BYTE MasterCMD; 

    SET_D1();//Set debug LED 


    // RX INTERRUPT 
    if(IFS0bits.SPI3RXIF) // receive data available in SPI3BUF Rx buffer 
    { 
     MasterCMD = SPI3BUF; 
     if(AirCMD == 0x01) 
     { 
      airsysTxFlush(); 
      airsysTxWrite(0x02); 
     } 
    } 

    //Transmit data if needed. 
    if(SPI3STATbits.SPITBE) 
    { 
     if(!airsysTxIsEmpty()) 
     { 
      SPI3BUF = airsysTxRead(); 
     } 
     else 
     { 
      //Else write 0 to the tx buffer to clear the spi shift reg 
      SPI3BUF = 0x00; 
     } 
    } 


    IFS0bits.SPI3RXIF = 0; 
    IFS0bits.SPI3TXIF = 0; 
    IFS0bits.SPI3EIF = 0; 
    SPI3STATbits.SPIROV = 0;// clear the Overflow 
    CLEAR_D1();//CLEAR Debug LED 

} // end ISR 

这段代码实际上是传递是这样的:

理想的每次传输应该是这样的。
主从
0×01 0×02
0×00 0×01

回答

1

一般来说,你可以不写从SPI驱动程序在你的描述,因为你无法精确控制时间为从站的方式进行交互。什么产生你的ISR,它是来自主机的第一个字节的接收还是断言芯片选择?

作为从站,您需要在主站启动事务之前设置要传输的数据字节。您通常没有时间对第一个字节做出反应。有几种方法可以做到这一点:

1)您可以使用一种协议,其中主机执行一个1字节或2字节的只写事务,告知从服务器它想读取什么。然后,主站等待几毫秒以允许从站准备响应。然后master执行一个只读事务来获得从机响应。 2)如果使用DMA或FIFO,从器件在主器件启动事务之前将第一个填充字节预加载到fifo中。然后,当你获得ISR时,你将剩余的响应数据放入FIFO中(不需要刷新)。您需要有足够的填充字节来容纳形成响应时的从属ISR延迟。例如,您可以定义您的协议,其中主服务器知道前N个字节的响应是填充字节,其后是响应数据。填充要求取决于您的主时钟速度和从CPU速度/中断延迟。

+0

确实。当你得到RX标志或从机选择时,开始铲除数据已经太迟了,除非你所做的只是在数据寄存器发生单次写入时。当主控制器决定取数据时,数据应该已经在SPI数据寄存器中可用。 – Lundin 2012-04-25 13:20:47