SPI的DMA中断

时间:2013-07-12 00:15:09

标签: c interrupt dma spi mplab

我正在尝试为dsPIC33FJ128GP802微控制器重新创建一个写SD卡(使用FatFS)的项目。

目前要从SPI收集日期我有一个do / while循环512次并将伪值写入SPI缓冲区,等待SPI标志,然后读取SPI值,如下所示:

int c = 512;

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

我正在尝试使用DMA intterupts重新创建它,但它不像我希望的那样工作。我正在使用一个DMA通道,SPI暂时处于8位模式,因此DMA处于字节模式,它也处于'空写'模式,并且连续没有乒乓。我的缓冲区只有一个成员数组,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

根据我从空写模式的理解,DMA将在每次执行读操作时写入空值。但是,DMA在CPU执行初始写入之前不会启动,所以我使用了manual / force方法来启动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);)。不幸的是,当空写入模式自动发送和接收SPI数据时,我无法手动进行任何类型的等待。

我也尝试过使用两个DMA通道,一个用于写入,一个用于读取,但这也不起作用(此外,当我正确写入SD卡时,我需要该通道。)

任何帮助都会很棒!

0 个答案:

没有答案