OpenEdv-开源电子网

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

STM32F103VETX SDIO 写卡问题。

[复制链接]

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
91
金钱
91
注册时间
2018-7-27
在线时间
19 小时
发表于 2019-3-21 11:47:33 | 显示全部楼层 |阅读模式
本帖最后由 hezhenghedao 于 2019-3-22 10:14 编辑

用STM32CUBEMX 生成 SDIO 4线模式。  在配置dma下图所示,STM32F103VETX  怎么只有配接收的,DMA,要么配置为发送,要么就配置为接收,我看STM32F4 系列的,就可以单独配置,SDIO_RX 和 TX,难道只能配要么读,或 写 单边DMA吗?  

微信图片_20190321111618.png

2、通过MX生成的代码(设置为接收的),只能DMA接收,  DMA发送,不行,但也不报错,就是不中断,和DMA中断。
看代码也没什么区别,内容一样,但是现在只能DMA读,不能DMA写就是里面DMA写的 /* Write Blocks in Polling mode */ 看里面备注了一个,写DMA怎么都不中断,也不DMA回调 , 接收有中断和回调。
后来改了,DMA读,常规模式写就可以 或者 配DMA写,常规模式读也是可以用,就是不能DMA发和收同时配 。

3、这软件不能直接像STM32F4 系列的 可以配置,读 和 写分开配吗?看手册只有一个通道4是SDIO的DMA.
微信图片_20190321111422.png
STM32F103VETX  另外初始化,也是只能初始化单边的DMA 下面话的意思,只能单向的配置吗》

/*多个外围DMA句柄指针指向同一个DMA句柄。请注意,只有一个通道可以执行所有请求的DMAs。* /

/*在调用HAL_SD_ReadBlocks_DMA或HAL_SD_WriteBlocks_DMA之前,请确保更改传输方向。* /

__HAL_LINKDMA (hsd hdmarx hdma_sdio);

__HAL_LINKDMA (hsd hdmatx hdma_sdio);

    /* Several peripheral DMA handle pointers point to the same DMA handle. Be aware that there is only one channel to perform all the requested DMAs. */

    /* Be sure to change transfer direction before calling   HAL_SD_ReadBlocks_DMA or HAL_SD_WriteBlocks_DMA. */
    __HAL_LINKDMA(hsd,hdmarx,hdma_sdio);
    __HAL_LINKDMA(hsd,hdmatx,hdma_sdio);




现在重新改了一下,写入数据前调用一下。void MX_SDIO_SD_Tx_Init(void)  变一下,方向,就可以中DMA写中断,写返回为0也是正确的,但奇怪是实际并没有写入进去,有知道什么原因的吗?


void MX_SDIO_SD_Rx_Init(void)
{
   /* SDIO DMA Init */
    /* SDIO Init */
    hdma_sdio.Instance = DMA2_Channel4;
    hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;
    hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_sdio.Init.Mode = DMA_NORMAL;
    hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_sdio) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(&hsd,hdmarx,hdma_sdio);
    __HAL_LINKDMA(&hsd,hdmatx,hdma_sdio);
}
void MX_SDIO_SD_Tx_Init(void)
{
            /* SDIO DMA Init */
    /* SDIO Init */
    hdma_sdio.Instance = DMA2_Channel4;
    hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;
    hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_sdio.Init.Mode = DMA_NORMAL;
    hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_sdio) != HAL_OK)
    {
      Error_Handler();
    }
    __HAL_LINKDMA(&hsd,hdmarx,hdma_sdio);
    __HAL_LINKDMA(&hsd,hdmatx,hdma_sdio);
}



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
91
金钱
91
注册时间
2018-7-27
在线时间
19 小时
 楼主| 发表于 2019-4-2 11:39:17 | 显示全部楼层
解决了
最后改了一下,写入读取都可以DMA了。
就是多加了停止之前的DMA 然后再变一下方向后,再读,或写即可
    /* Stop any ongoing transfer and reset the state*/
    HAL_DMA_Abort(&hdma_sdio);   
    /* Deinitialize the Channel for new transfer */
    HAL_DMA_DeInit(&hdma_sdio);

HAL_StatusTypeDef SD_DMAConfigTx(SD_HandleTypeDef *hsd)
{
  //static DMA_HandleTypeDef hdma_tx;
  HAL_StatusTypeDef status;

        /* Invalidate the dma tx handle*/
  hsd->hdmatx = NULL;
        hsd->hdmarx = NULL;
        
  if(hsd->hdmatx == NULL)
  {

               
    /* Several peripheral DMA handle pointers point to the same DMA handle.
     Be aware that there is only one channel to perform all the requested DMAs. */
    /* Be sure to change transfer direction before calling
     HAL_SD_ReadBlocks_DMA or HAL_SD_WriteBlocks_DMA. */

                hdma_sdio.Instance                 = DMA2_Channel4;
    hdma_sdio.Init.Direction           = DMA_MEMORY_TO_PERIPH;
    hdma_sdio.Init.PeriphInc           = DMA_PINC_DISABLE;
    hdma_sdio.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_sdio.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
                hdma_sdio.Init.Mode                                                   = DMA_NORMAL;
    hdma_sdio.Init.Priority            = DMA_PRIORITY_LOW;   

    /* Stop any ongoing transfer and reset the state*/
    HAL_DMA_Abort(&hdma_sdio);

    /* Deinitialize the Channel for new transfer */
    HAL_DMA_DeInit(&hdma_sdio);

    /* Configure the DMA Channel */
    status = HAL_DMA_Init(&hdma_sdio);     
               
    //__HAL_LINKDMA(hsd, hdmatx, hdma_tx);
                //__HAL_LINKDMA(hsd,hdmatx,hdma_sdio);
    __HAL_LINKDMA(hsd,hdmarx,hdma_sdio);
    __HAL_LINKDMA(hsd,hdmatx,hdma_sdio);
               
    /* NVIC configuration for DMA transfer complete interrupt */
    HAL_NVIC_SetPriority(DMA2_Channel4_5_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);  
  }
  else
  {
    status = HAL_OK;
  }

  return (status != HAL_OK? HAL_ERROR : HAL_OK);
}



HAL_StatusTypeDef SD_DMAConfigRx(SD_HandleTypeDef *hsd)
{
  //static DMA_HandleTypeDef hdma_rx;
  HAL_StatusTypeDef status = HAL_ERROR;

        /* Invalidate the dma tx handle*/
  hsd->hdmatx = NULL;
        hsd->hdmarx = NULL;
        
  if(hsd->hdmarx == NULL)
  {
    /* Configure DMA Rx parameters */
                hdma_sdio.Instance                 = DMA2_Channel4;
    hdma_sdio.Init.Direction           = DMA_PERIPH_TO_MEMORY;
    hdma_sdio.Init.PeriphInc           = DMA_PINC_DISABLE;
    hdma_sdio.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_sdio.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
                hdma_sdio.Init.Mode                                                    = DMA_NORMAL;
    hdma_sdio.Init.Priority            = DMA_PRIORITY_LOW;

    /* Stop any ongoing transfer and reset the state*/
    HAL_DMA_Abort(&hdma_sdio);

    /* Deinitialize the Channel for new transfer */
    HAL_DMA_DeInit(&hdma_sdio);

    /* Configure the DMA Channel */
    status = HAL_DMA_Init(&hdma_sdio);
        /* Associate the DMA handle */
                //__HAL_LINKDMA(hsd,hdmarx,hdma_sdio);
    __HAL_LINKDMA(hsd,hdmarx,hdma_sdio);
    __HAL_LINKDMA(hsd,hdmatx,hdma_sdio);
    /* NVIC configuration for DMA transfer complete interrupt */
    HAL_NVIC_SetPriority(DMA2_Channel4_5_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
  }
  else
  {
    status = HAL_OK;
  }

  return (status != HAL_OK? HAL_ERROR : HAL_OK);
}

回复 支持 反对

使用道具 举报

0

主题

295

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
335
金钱
335
注册时间
2019-3-26
在线时间
9 小时
发表于 2019-4-2 14:45:44 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-23 14:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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