OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3701|回复: 6

HAL库如何实现DMA双缓冲模式?

[复制链接]

3

主题

11

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2019-5-27
在线时间
12 小时
发表于 2019-11-25 19:02:26 | 显示全部楼层 |阅读模式
15金钱
现在在做高速采集,普通DMA模式会导致丢数(乒乓RAM方式,进入中断,SPI那边就停止采数了),需要用DMA双缓冲模式。但我看了下HAL库里的库函数,好像只有普通DMA模式,没找到DMA双缓冲模式的函数。
看到一个2015年的帖子,说是只能仿照标准库自己写一个,已经2019年了,ST官方还是没有给出HAL库的函数解决方案?
有没有大佬搞过,真心求个解决方案,非常感谢!!!

最佳答案

查看完整内容[请看2#楼]

看下429的OV5640摄像头例程看看 里边有用到双缓冲模式
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14407
金钱
14407
注册时间
2018-8-3
在线时间
1156 小时
发表于 2019-11-25 19:02:27 | 显示全部楼层
看下429的OV5640摄像头例程看看 里边有用到双缓冲模式
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2019-11-26 00:22:23 | 显示全部楼层
参考下我们的HAL库例程,比如429的HAL库教程
回复

使用道具 举报

17

主题

142

帖子

0

精华

高级会员

Rank: 4

积分
897
金钱
897
注册时间
2016-2-16
在线时间
162 小时
发表于 2019-11-26 15:18:42 | 显示全部楼层
在寄存器里使能双缓冲模式,指定当前缓冲区地址和下次缓冲区地址,使能中断位即可。
回复

使用道具 举报

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2020-7-27
在线时间
10 小时
发表于 2020-8-23 15:29:37 | 显示全部楼层
HAL_DMAEx_MultiBufferStart_IT
回复

使用道具 举报

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2020-7-27
在线时间
10 小时
发表于 2020-8-23 15:30:19 | 显示全部楼层
HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
{
  HAL_StatusTypeDef status = HAL_OK;
  
  /* Check the parameters */
  assert_param(IS_DMA_BUFFER_SIZE(DataLength));
  
  /* Memory-to-memory transfer not supported in double buffering mode */
  if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
  {
    hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
    return HAL_ERROR;
  }
  
  /* Process locked */
  __HAL_LOCK(hdma);
  
  if(HAL_DMA_STATE_READY == hdma->State)
  {
    /* Change DMA peripheral state */
    hdma->State = HAL_DMA_STATE_BUSY;
   
    /* Initialize the error code */
    hdma->ErrorCode = HAL_DMA_ERROR_NONE;
   
    /* Enable the Double buffer mode */
    hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;
   
    /* Configure DMA Stream destination address */
    hdma->Instance->M1AR = SecondMemAddress;
   
    /* Configure the source, destination address and the data length */
    DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);
   
    /* Clear all flags */
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
   
    /* Enable Common interrupts*/
    hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
    hdma->Instance->FCR |= DMA_IT_FE;
   
    if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
    {
      hdma->Instance->CR  |= DMA_IT_HT;
    }
   
    /* Enable the peripheral */
    __HAL_DMA_ENABLE(hdma);
  }
  else
  {     
    /* Process unlocked */
    __HAL_UNLOCK(hdma);          
   
    /* Return error status */
    status = HAL_BUSY;
  }  
  return status;
}

这个是双缓冲函数吧。
回复

使用道具 举报

1

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2020-7-27
在线时间
10 小时
发表于 2020-9-26 15:18:19 | 显示全部楼层
用HAL_DMAEx_MultiBufferStart+传输完成中断标志判断就好了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-17 04:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表