你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

HAL库SPI DMA循环调用问题求教

[复制链接]
onev 提问时间:2017-4-9 20:53 /
使用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 。。。。。。但发现 读取总有些问题,尤其不能被中断打断,这是为什么呢?
收藏 2 评论16 发布时间:2017-4-9 20:53

举报

16个回答
chayishuang 回答时间:2017-11-23 19:09:05
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
watershade 回答时间:2017-5-11 10:33:31
这是不是和在UART中断里面启用DMA中断发送或接受UART命令一样呀。就是在循环里面继续循环(尽管支持循环嵌套)

进中断处理函数之后SPI的DMA应该先关掉吧,使用HAL_SPI_DMAPause()/ HAL_SPI_DMAStop()。这样就没有问题了。你也可以试一试在callback里面只设置准备开启的DMA设备,比如用变量存储任务号。然后在SPIx_IRQHandler的末尾根据任务号来开启。这样程序执行完就推出循环了。但是没有试过。
楼主如果要试一下的话,讲结果告诉我,谢谢。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

衔胆栖冰 回答时间:2017-5-11 11:05:52
疑问1:你的器件1,2,3....通过什么来选择?同一路SPI不同片选还是多路SPI接从器件?
疑问2:HAL_SPI_TxRxCpltCallback中调用HAL_SPI_TransmitReceive_DMA开始读取器件2这用法是否正确?
疑问3:DMA从外设到内存过程不需要CPU干预,为什么中断能打断SPI的通信数据?
如果描述不清楚的,就请上代码吧。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

onev 回答时间:2017-4-12 21:03:35
没人做过或碰到过么 这个问题
无薪税绵 回答时间:2017-5-11 08:39:00
楼主是不是配置为全双工了,
建议配置为半双工。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

yygkqzh 回答时间:2017-5-11 12:57:14
我觉得提问题就得粘贴代码,这样问大家也不知道是什么原因导致的
cldym 回答时间:2017-5-11 15:28:41
建议配置为半双工。
onev 回答时间:2017-5-26 20:25:25
衔胆栖冰 发表于 2017-5-11 11:05
疑问1:你的器件1,2,3....通过什么来选择?同一路SPI不同片选还是多路SPI接从器件?
疑问2:HAL_SPI_TxRxCp ...

1.同一路SPI接若干器件。
2.如果已经知道正确与否我还来问什么呢?
3.实测是这样的
代码太长不好贴
onev 回答时间:2017-5-26 20:26:28
无薪税绵 发表于 2017-5-11 08:39
楼主是不是配置为全双工了,
建议配置为半双工。

为什么,能不能说说原因?
onev 回答时间:2017-5-27 10:35:36
watershade 发表于 2017-5-11 10:33
这是不是和在UART中断里面启用DMA中断发送或接受UART命令一样呀。就是在循环里面继续循环(尽管支持循环嵌套 ...

多谢!如你所言,加上HAL_SPI_DMAStop()可以,不过加HAL_SPI_DMAPause()不行。
watershade 回答时间:2017-6-1 09:51:48
onev 发表于 2017-5-27 10:35
多谢!如你所言,加上HAL_SPI_DMAStop()可以,不过加HAL_SPI_DMAPause()不行。

解决了就好
chayishuang 回答时间:2017-11-20 16:29:23
我在SPI回调函数中,添加HAL_SPI_DMAStop(),和HAL_SPI_Receive_DMA(),实际使能中断一次,请问楼主有碰到这个问题吗?
onev 回答时间:2017-11-21 20:39:33
chayishuang 发表于 2017-11-20 16:29
我在SPI回调函数中,添加HAL_SPI_DMAStop(),和HAL_SPI_Receive_DMA(),实际使能中断一次,请问楼主有碰到这 ...

没太听懂你的意思
onev 回答时间:2017-11-24 09:39:02
chayishuang 发表于 2017-11-23 19:09
SPI接收回调代码:
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{

你这岂不是一个无限循环不出来了?! 话说你的片选一直拉低的吗?
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版