通过PIC32上的DMA接收SPI数据
我知道这个话题(DMA和SPI)已经在微芯片论坛的众多线程中被讨论过了,实际上我已经阅读了搜索结果的所有15个页面,关键字为“dma”,并阅读了有关dma的所有主题&安培; SPI。
我仍然坚持我的问题,我希望有人可以帮助我:)
这是问题所在。
我的芯片是PIC32MX775F512H。
我试图通过DMA使用SPI接收(仅接收)数据。
因为你不能“只是”接收SPI,并且只有当你写入SPIBUF(我的SPI1ABUF)时SPI内核才开始切换SPI时钟,我试图使用2个DMA通道接收数据。
DMA_CHANNEL1用于发送部分。
DMA_CHANNEL2用于接收部分。
我复制粘贴代码来自http://www.microchip.com/forums/tm.aspx?tree=true&high=&m=562453&mpage=1#
并试图让它运作没有任何运气。它只接收几个字节(5或6)。
我为两个dma通道设置了事件启用标志为DMA_EV_BLOCK_DONE,没有发生中断。
你有什么主意吗 ?
这是我正在使用的代码:
int Spi_recv_via_DMA(SPI_simple_master_class* SPI_Port, int8u *in_bytes, int16u num_bytes2)
{
DmaChannel dmaTxChn=DMA_CHANNEL1;
DmaChannel dmaRxChn=DMA_CHANNEL2;
SpiChannel spiTxChn=SPI_Port->channel;
int8u dummy_input;
DmaChnOpen(dmaTxChn, DMA_CHN_PRI3, DMA_OPEN_DEFAULT);
DmaChnOpen(dmaRxChn, DMA_CHN_PRI3, DMA_OPEN_DEFAULT);
DmaChnSetEventControl(dmaTxChn, DMA_EV_START_IRQ_EN | DMA_EV_START_IRQ(_SPI1A_RX_IRQ));
DmaChnSetEventControl(dmaRxChn, DMA_EV_START_IRQ_EN | DMA_EV_START_IRQ(_SPI1A_RX_IRQ));
DmaChnClrEvFlags(dmaTxChn, DMA_EV_ALL_EVNTS);
DmaChnClrEvFlags(dmaRxChn, DMA_EV_ALL_EVNTS);
DmaChnSetEvEnableFlags(dmaRxChn, DMA_EV_BLOCK_DONE);
DmaChnSetEvEnableFlags(dmaTxChn, DMA_EV_BLOCK_DONE);
//SpiChnClrTxIntFlag(spiTxChn);
//SpiChnClrRxIntFlag(spiTxChn);
DmaChnSetTxfer(dmaTxChn, tx_dummy_buffer, (void *)&SPI1ABUF, num_bytes2, 1, 1);
DmaChnSetTxfer(dmaRxChn, (void *)&SPI1ABUF, in_bytes, 1, num_bytes2, 1);
while ( (SPI1ASTAT & SPIRBE) == 0)
dummy_input = SPI1ABUF;
SPI1ASTAT &= ~SPIROV;
DmaRxIntFlag = 0;
DmaChnEnable(dmaRxChn);
DmaChnStartTxfer(dmaTxChn, DMA_WAIT_NOT, 0);
while(!DmaRxIntFlag);
return 1;
}
使用这两个中断处理程序:
// handler for the DMA channel 1 interrupt
void __ISR(_DMA1_VECTOR, ipl5) DmaHandler1(void)
{
int evFlags; // event flags when getting the interrupt
//LED_On(LED_CFG);
INTClearFlag(INT_SOURCE_DMA(DMA_CHANNEL1)); // acknowledge the INT controller, we're servicing int
evFlags=DmaChnGetEvFlags(DMA_CHANNEL1); // get the event flags
if(evFlags&DMA_EV_BLOCK_DONE)
{ // just a sanity check. we enabled just the DMA_EV_BLOCK_DONE transfer done interrupt
DmaTxIntFlag = 1;
DmaChnClrEvFlags(DMA_CHANNEL1, DMA_EV_BLOCK_DONE);
}
// LED_Off(LED_CFG);
}
void __ISR(_DMA2_VECTOR, ipl5) DmaHandler2(void)
{
int evFlags; // event flags when getting the interrupt
INTClearFlag(INT_SOURCE_DMA(DMA_CHANNEL2)); // acknowledge the INT controller, we're servicing int
evFlags=DmaChnGetEvFlags(DMA_CHANNEL2); // get the event flags
if(evFlags&DMA_EV_BLOCK_DONE)
{ // just a sanity check. we enabled just the DMA_EV_BLOCK_DONE transfer done interrupt
DmaRxIntFlag = 1;
DmaChnClrEvFlags(DMA_CHANNEL2, DMA_EV_BLOCK_DONE);
}
}
所以我最终在这条线上永远等待:while(!DmaRxIntFlag);
我在中断向量中放置了断点,它们从未被调用过。
在持续等待期间,这是几个寄存器的状态:
DMACON 0x0000C800
DMASTAT 0x00000001
我使用SPI1A端口,所以SPI1ABUF和_SPI1A_RX_IRQ
DCH1SPTR 0x5
DCH1SSIZ 0x2B
DCH2DPTR 0x6
DCH2DSIZ 0x2B
DCH2CON 0x00008083
DCH2ECON 0x1B10
DCH2INT 0x00800C4
DCH2SSA 0x1F805820
DCH2DSA 0x00000620
通道1用于传输
通道2用于接收
没有找到相关结果
已邀请:
2 个回复
翁茄口霉氖
以前的安全
祝好运!
悸翠疮武昏