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

请教下 STM32Cube_FW_F7_V1.6.0 sd dma 的使用 ?

[复制链接]
hpdell 提问时间:2017-3-27 20:01 /
本帖最后由 hpdell 于 2017-3-27 23:51 编辑

请教下 ,关于最新版本的库 STM32Cube_FW_F7_V1.6.0 版本的 sd dma 的使用 ?

目前使用sd dma 读写总是失败,如果不使用dma读写则完全没有问题

现在就是想请教下,当使用 dma 读写时,需要调用什么函数来判断这个dma 的读写是否完成 ???????????

使用dma 相关函数如下:
uint8_t     SD_RxCplt , SD_TxCplt ;

uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t NumOfBlocks)
{
  uint8_t sd_state = MSD_OK;
  if(HAL_SD_ReadBlocks_DMA(&_HSD, (uint8_t *)pData, ReadAddr, NumOfBlocks) != HAL_OK)  
  {
    sd_state = MSD_ERROR;
  }
  return sd_state;
}

uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t NumOfBlocks)
{
  uint8_t sd_state = MSD_OK;

  if(HAL_SD_WriteBlocks_DMA(&_HSD, (uint8_t *)pData, WriteAddr,  NumOfBlocks) != HAL_OK)  
  {
    sd_state = MSD_ERROR;
  }

  return sd_state;
}




DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
{
  DRESULT res = RES_OK;
  uint32_t timeout = 100000;

  if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,
                       (uint64_t) (sector ),
                       count) == MSD_OK)
  {
    while(SD_RxCplt == 0)
    {
      if (timeout-- == 0)
      {
        SD_RxCplt = 0;
        sd_state =  MSD_ERROR;
      }
    }

    SD_RxCplt = 0;
    res = RES_OK;
  }
  return res;
}


DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
  DRESULT res = RES_OK;
  uint32_t timeout = 100000;
  if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
                        (uint64_t)(sector ),
                        count) == MSD_OK)
  {
    while(SD_TxCplt == 0)
    {
      if (timeout-- == 0)
      {
        SD_TxCplt = 0;
        sd_state =  MSD_ERROR;
      }
    }

    SD_TxCplt = 0;   
    res = RES_OK;
  }
  return res;
}


回调函数/**
  * @brief Tx Transfer completed callbacks
  */
void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
{
  SD_TxCplt = 1;
  printf("SD Tx Completed \r\n");

}

/**
  * @brief Rx Transfer completed callbacks
  */
void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
{
  SD_RxCplt = 1;
  printf("SD Rx Completed \r\n");

}




现在就是想请教下,当使用 dma 读写时,需要调用什么函数来判断这个dma 的读写是否完成 ???????????
// **********************************************************************************
在以前的老版本里面有个 如下函数,但是在目前的 这个 f7 v1.6的库里面已经找不到了
  /* Wait until  Tx  Rx  complete */
    HAL_SD_CheckWriteOperation(&_HSD, (uint32_t)SD_DATATIMEOUT) ;
    HAL_SD_CheckReadOperation(&_HSD, (uint32_t)SD_DATATIMEOUT);









收藏 1 评论18 发布时间:2017-3-27 20:01

举报

18个回答
gdszyj 回答时间:2017-4-7 09:45:03
/**
  * @brief  Reads block(s) from a specified address in a card. The Data transfer
  *         is managed by DMA mode.
  * @note   This API should be followed by a check on the card state through
  *         HAL_SD_GetCardState().
  * @note   You could also check the DMA transfer process through the SD Rx
  *         interrupt event.
  * @param  hsd: Pointer SD handle                 
  * @param  pData: Pointer to the buffer that will contain the received data
  * @param  BlockAdd: Block Address from where data is to be read  
  * @param  NumberOfBlocks: Number of blocks to read.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
这个是在库文件找到的,当用HAL_SD_GetCardState().返回的结果总是4 HAL_SD_CARD_TRANSFER               = 0x00000004U,  /*!< Card is in transfer state               */
gdszyj 回答时间:2017-4-7 14:38:13
hpdell 发表于 2017-4-7 11:06
我目前使用的查询貌似,dma 模式还没有去研究,除非把他替换为 v1.6 之前的版本就可以使用 dma 模式了, ...

刚才试了下查询的方法,速度能够达到1M每秒,但是拷贝进去以后会出现乱码的现象,再次拷贝出来说是文件损坏。
        /* Write block(s) in DMA transfer mode */
        if(HAL_SD_WriteBlocks(&hsd,buf, blk_addr , blk_len,0xffff) == HAL_OK){
                ret = USBD_OK;
        }
hpdell 回答时间:2017-4-7 11:06:30
gdszyj 发表于 2017-4-7 09:45
/**
  * @brief  Reads block(s) from a specified address in a card. The Data transfer
  *         is ...

我目前使用的查询貌似,dma 模式还没有去研究,除非把他替换为 v1.6 之前的版本就可以使用 dma 模式了,
maisheng 回答时间:2017-3-28 10:00:17
楼主先试试HAL_SD_WriteBlocks_DMA和HAL_SD_ReadBlocks_DMA正常不正常再说,我在STM32L476上也遇到你说的问题,你可以看我刚发的帖子。

评分

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

查看全部评分

feiante 回答时间:2017-3-28 10:25:19
好像这块不用更改吧,你试试降低时钟频率看看

评分

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

查看全部评分

hpdell 回答时间:2017-3-28 15:07:02
maisheng 发表于 2017-3-28 10:00
楼主先试试HAL_SD_WriteBlocks_DMA和HAL_SD_ReadBlocks_DMA正常不正常再说,我在STM32L476上也遇到你说的问 ...

你好,你刚刚发布的帖子能否提供一下 网址啊 ??
hpdell 回答时间:2017-3-28 15:08:01
feiante 发表于 2017-3-28 10:25
好像这块不用更改吧,你试试降低时钟频率看看

估计跟时钟没有关系的,

因为我是从我以前的工程里面移植过来的,现在 的这个新版本的库 不老版本的 库 有很大差别
feiante 回答时间:2017-3-29 08:37:21
hpdell 发表于 2017-3-28 15:08
估计跟时钟没有关系的,

因为我是从我以前的工程里面移植过来的,现在 的这个新版本的库 不老版本的 库  ...

哦,我前久使用SD+fatfs,开始老是读写失败,就是把SD的时钟改小点好的。
maisheng 回答时间:2017-3-29 09:23:30
我也觉得直接改成HAL_SD_ReadBlocks_DMA不合适,因为调用之后直接返回后不见得已经读完了
hpdell 回答时间:2017-3-29 11:42:36
maisheng 发表于 2017-3-29 09:23
我也觉得直接改成HAL_SD_ReadBlocks_DMA不合适,因为调用之后直接返回后不见得已经读完了 ...

你好,你的意思还是使用查询就可以了,是吧 ??
maisheng 回答时间:2017-3-29 15:39:47
hpdell 发表于 2017-3-29 11:42
你好,你的意思还是使用查询就可以了,是吧 ??

不太好确定 你测试试试 反正我的read_dma只能读4个字节
xmshao 回答时间:2017-3-29 16:20:53
你看看这两个下面两个函数:
HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout);
HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout);

评分

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

查看全部评分

hpdell 回答时间:2017-3-29 21:25:02
xmshao 发表于 2017-3-29 16:20
你看看这两个下面两个函数:
HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uin ...

你好,这个最新的固件库 v1.6版本里面已经木有你所说的那两个函数了,

在 v1.6 版本之前是有的,但是在 v1.6 版本里面已经找不到了
gdszyj 回答时间:2017-4-7 09:20:36
这两天也是遇到同样的问题,我在想用DMA的中断是否可以呢?
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版