1

チップ セレクトを備えた 1.53MHz SPI バスで接続された2 つのPIC32MXマイクロコントローラがあります。スレーブ側の割り込みサービス ルーチンでデータを正しく送信するのに問題があります。テスト ケースとして、マスターに 10 ミリ秒ごとに 2 バイト (0x01、0x00) を送信させています。スレーブは 0x01 コマンド ID を受信し、マスターが 2 番目のバイト (ダミーの 0x00) を送信したときに 0x02 で応答することになっています。

理想的には、各転送は次のようになります。
マスター スレーブ
0x01 0x00
0x00 0x02

ただし、スレーブ割り込みをどこから始めればよいか本当にわかりません。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

このコードが実際に送信しているのは次のようなものです。

理想的には、各転送は次のようになります。
マスター スレーブ
0x01 0x02
0x00 0x01

4

1 に答える 1

1

一般に、スレーブとしてタイミングを正確に制御できないため、説明した方法で対話するスレーブ SPI ドライバーを作成することはできません。ISR を生成するものは何ですか? マスターからの最初のバイトの Rx ですか、それともチップ セレクトのアサートですか?

スレーブとして、マスターがトランザクションを開始する前に、送信するデータ バイトを設定する必要があります。通常、最初のバイトに反応する時間はありません。これを行うには、いくつかの方法があります。

1) マスターが 1 または 2 バイトの書き込み専用トランザクションを実行し、スレーブに何を読み取りたいかを伝えるプロトコルを使用できます。次に、マスターは数ミリ秒待機して、スレーブが応答を準備できるようにします。次に、マスターは読み取り専用トランザクションを実行して、スレーブの応答を取得します。

2) DMA または FIFO を使用している場合、マスターがトランザクションを開始する前に、スレーブは最初のパディング バイトを FIFO にプリロードします。次に、ISR を取得したら、残りの応答データを (フラッシュせずに) fifo に入れます。応答を形成する際に、スレーブ ISR レイテンシに対応するのに十分なパッド バイトが必要です。したがって、たとえば、応答の最初の N バイトがパッド バイトであり、その後に応答データが続くことをマスターが認識しているプロトコルを定義できます。パディング要件は、マスター クロック速度とスレーブ CPU 速度/割り込みレイテンシによって異なります。

于 2012-04-24T17:01:26.057 に答える