HAL库SPI DMA循环调用问题

2019-07-14 15:09发布

使用HAL库的SPI DMA方式读取一个器件的数据,然后在回调函数中开启下一个器件的SPI DMA方式来读取数据,依此方式依次读取几个器件,比如器件1、2、3。。。。。。,用SPI DMA函数HAL_SPI_TransmitReceive_DMA读取器件1后在SPI的回调函数HAL_SPI_TxRxCpltCallback中调用HAL_SPI_TransmitReceive_DMA开始读取器件2,然后下一步再在HAL_SPI_TxRxCpltCallback中调用HAL_SPI_TransmitReceive_DMA读取器件3 。。。。。。但发现 读取总有些问题,尤其不能被中断打断,这是为什么呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
15条回答
xxn082349
1楼-- · 2019-07-15 12:12
xieweibin 发表于 2018-12-17 17:27
楼主是不是配置为全双工了,
建议配置为半双工。

为什么,能不能说说原因?
xxn082349
2楼-- · 2019-07-15 14:22
naiztycheng 发表于 2018-12-17 17:40
这是不是和在UART中断里面启用DMA中断发送或接受UART命令一样呀。就是在循环里面继续循环(尽管支持循环嵌套)

进中断处理函数之后SPI的DMA应该先关掉吧,使用HAL_SPI_DMAPause()/ HAL_SPI_DMAStop()。这样就没有问题了。你也可以试一试在callback里面只设置准备开启的DMA设备,比如用变量存储任务号。然后在SPIx_IRQHandler ...

多谢!如你所言,加上HAL_SPI_DMAStop()可以,不过加HAL_SPI_DMAPause()不行。
naiztycheng
3楼-- · 2019-07-15 17:55
60user89
4楼-- · 2019-07-15 18:33
我在SPI回调函数中,添加HAL_SPI_DMAStop(),和HAL_SPI_Receive_DMA(),实际使能中断一次,请问楼主有碰到这个问题吗?
xxn082349
5楼-- · 2019-07-15 22:34
 精彩回答 2  元偷偷看……
tongjingyang
6楼-- · 2019-07-16 00:52
SPI接收回调代码:
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
        HAL_SPI_DMAStop(hspi);
        if(HAL_SPI_Receive_DMA(hspi, REV_FPGA_DATA, 6)!= HAL_OK)
  {
    /* Transfer error in transmission process */
    Error_Handler();
  }
}
DMA初始化中的部分代码:
/* SPI1 DMA Init */
    /* SPI1_RX Init */
    hdma_spi1_rx.Instance = DMA2_Stream0;
    hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3;
    hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_spi1_rx.Init.Mode = DMA_NORMAL;
    hdma_spi1_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
    hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
主函数中,初始化后,执行了一次        :
if(HAL_SPI_Receive_DMA(hspi, REV_FPGA_DATA, 6)!= HAL_OK)
  {
    /* Transfer error in transmission process */
    Error_Handler();
  }
结果是:只执行了一次dma

一周热门 更多>