0

dsPIC33FJ128GP802 マイクロコントローラ用の SD カード (FatFS を使用) に書き込むプロジェクトを再作成しようとしています。

現在、SPI から日付を収集するために、512 回ループして SPI バッファーにダミー値を書き込む do/while を使用し、SPI フラグを待ってから、次のように SPI 値を読み取ります。

int c = 512;

do {
    SPI1BUF = 0xFF;
    while (!_SPIRBF);
    *p++ = SPI1BUF;
} while (--c);

DMA 割り込みを使用してこれを再現しようとしていますが、期待どおりに動作しません。私は 1 つの DMA チャネルを使用しています。SPI は当面 8 ビット モードであるため、DMA はバイト モードであり、「ヌル書き込み」モードでもあり、ピンポンなしで連続します。私のバッファーは 1 つのメンバー配列のみであり、DMA は一致しています。

DMA2CONbits.CHEN = 0; //Disable DMA
DMA2CONbits.SIZE = 1; //Receive bytes (8 bits)
DMA2CONbits.DIR = 0; //Receive from SPI to DMA
DMA2CONbits.HALF = 0; //Receive full blocks
DMA2CONbits.NULLW = 1; //null write mode on
DMA2CONbits.AMODE = 0; //Register indirect with post-increment
DMA2CONbits.MODE = 0; //continuous mode without ping-pong

DMA2REQbits.IRQSEL = 10; //Transfer done (SPI)

DMA2STA = __builtin_dmaoffset(SPIBuffA); //receive buffer
DMA2PAD = (volatile unsigned int) &SPI1BUF;

DMA2CNT = 0; //transfer count = 1

IFS1bits.DMA2IF = 0; //Clear DMA interrupt
IEC1bits.DMA2IE = 1; //Enable DMA interrupt

null書き込みモードから私が理解していることから、DMAは読み取りが実行されるたびにnull値を書き込みます。ただし、CPU による最初の書き込みが実行されるまで DMA は開始されないため、手動/強制の方法で DMA を開始しました。

DMA1CONbits.CHEN = 1; //Enable DMA
DMA1REQbits.FORCE = 1; //Manual write

割り込みが開始され、エラーなしで実行されます。ただし、コードは後でコレクションが正しくないことを示しています。

私の割り込みは、収集したデータ (上記で割り当てられた DMA バッファーに配置されていると想定) を、プログラム全体で使用されるポインターに配置するだけであるという点で単純です。

void __attribute__((interrupt, no_auto_psv)) _DMA2Interrupt(void) {

if (RxDmaBuffer == 513) {
    DMA2CONbits.CHEN = 0;
    rxFlag = 1;
} else {

    buffer[RxDmaBuffer] = SPI1BUF;
    RxDmaBuffer++;
}

IFS1bits.DMA2IF = 0; // Clear the DMA0 Interrupt Flag

}

割り込みが 512 回実行されたら、DMA を停止してフラグをスローします。

私は何が欠けていますか?これは非 DMA 方式とどのように同じではないのですか? SPIの送信完了を待つwhileループ(while(!_SPIRBF);)が無いのが原因でしょうか。残念ながら、null 書き込みモードでは SPI データを自動的に送受信するため、手動で待機することはできません。

また、2 つの DMA チャネル (1 つは書き込み用、もう 1 つは読み取り用) を使用してみましたが、これも機能しませんでした (さらに、後で SD カードに適切に書き込むときに、そのチャネルが必要になります)。

どんな助けでも素晴らしいでしょう!

4

0 に答える 0