野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 9065|回复: 2

SD卡写速度很慢,不知道怎么改

[复制链接]
发表于 2018-1-23 16:44:48 | 显示全部楼层 |阅读模式
上位机通过TCP传输数据到SD卡,传输1M多的数据,需要1分多钟,速度很慢,不知道问题出在哪里。。
主函数主要是进入TCP数据传输函数,下面是主要的代码:
TCP传输时,接收到的数据写入到SD卡中
do
{
    CovLen = getSn_RX_RSR(SOCK_PORT);         //要接受数据长度      
    recv(SOCK_PORT,Buffer_MultiBlock_Tx,CovLen);//接受CovLen的数据,存放在缓存中
    if(CovLen%512 == 0 && CovLen/512>0)
    {
           SD_Write_DMA(CovLen/512,n);         //写入到SD卡中,第一个参数:写入的块数
                                         第二个参数:写入块的地址
          n = n+(CovLen/512);
   }
   if(CovLen%512!=0 && CovLen/512 >= 0)    //不是整块时,多写一块
  {
         SD_Write_DMA((CovLen/512) + 1,n);
          n = n+(CovLen/512)+1;
   }
  lenSum += CovLen;                                      //数据发送的总长度
  printf("一共发送%lu数据",lenSum);                                                               
}while(CovLen > 0);

/**********************************************************/
/*下面是我的SD卡写函数,因为使用HAL库的DMA写总是遇到一些问题*****/
void SD_Write_DMA(int BlocNum,int Addr)
{
   if (SD_Status == HAL_OK)
   {
     /* 写多块在地址Addr
      * Buffer_MultiBlock_Tx :需要传送数据的缓存
      * BlocNum:写的块数
      */
    SD_Status = SD_WriteMultiBlocks(&hsd, Buffer_MultiBlock_Tx, Addr, BlocNum );
    /* 等待传输完成*/
    SD_Status = SD_WaitWriteOperation();
    while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER);
   }
}

/************************************************************************/
/*SD卡写函数*/
HAL_StatusTypeDef SD_WriteMultiBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
{
   HAL_StatusTypeDef errorstatus = HAL_OK;

   TransferError = HAL_OK;
     TransferEnd = 0;         //传输结束置位,在中断服务置1
    StopCondition = 1;  

    SDIO->DCTRL = 0x0;

  if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
        {
                BlockAdd *= 512U;
        }
        /*******************设置块的大小CMD16 ***********************************/

        SDIO_CmdInitStructure.Argument = (uint32_t)BlockSize;
        SDIO_CmdInitStructure.CmdIndex = SDMMC_CMD_SET_BLOCKLEN;
        SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;
        SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;
        SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;
        SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);

        errorstatus = CmdResp1Error(SDMMC_CMD_SET_BLOCKLEN);
        if (errorstatus!=HAL_OK)
  {
    return(errorstatus);
  }
        /*CMD55*/
        SDIO_CmdInitStructure.Argument = 0x00;
        SDIO_CmdInitStructure.CmdIndex = SDMMC_CMD_APP_CMD ;
        SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;
        SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;
        SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;
        SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);
        errorstatus = CmdResp1Error(SDMMC_CMD_READ_SINGLE_BLOCK);
        if (errorstatus!=HAL_OK)
  {
    return(errorstatus);
  }

        /*多块写入时的预擦除,ACMD23*/
        SDIO_CmdInitStructure.Argument = NumberOfBlocks;
        SDIO_CmdInitStructure.CmdIndex = SDMMC_CMD_SET_BLOCK_COUNT ;
        SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;
        SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;
        SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;
        SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);
        errorstatus = CmdResp1Error(SDMMC_CMD_READ_SINGLE_BLOCK);
        if (errorstatus!=HAL_OK)
  {
    return(errorstatus);
  }

        /*!< CMD25 写多块*/
        SDIO_CmdInitStructure.Argument = (uint32_t)BlockAdd;
        SDIO_CmdInitStructure.CmdIndex = SDMMC_CMD_WRITE_MULT_BLOCK ;
        SDIO_CmdInitStructure.Response = SDIO_RESPONSE_SHORT;
        SDIO_CmdInitStructure.WaitForInterrupt = SDIO_WAIT_NO;
        SDIO_CmdInitStructure.CPSM = SDIO_CPSM_ENABLE;
        SDIO_SendCommand(hsd->Instance, &SDIO_CmdInitStructure);
        errorstatus = CmdResp1Error(SDMMC_CMD_READ_SINGLE_BLOCK);
        if (errorstatus!=HAL_OK)
  {
    return(errorstatus);
  }

        /*配置数据结构体*/
        SDIO_DataInitStructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
        SDIO_DataInitStructure.DataLength = NumberOfBlocks * BLOCKSIZE;
        SDIO_DataInitStructure.DataTimeOut = SDMMC_DATATIMEOUT;
        SDIO_DataInitStructure.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
        SDIO_DataInitStructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
        SDIO_DataInitStructure.DPSM = SDIO_DPSM_ENABLE;
        SDIO_ConfigData(hsd->Instance, &SDIO_DataInitStructure);

   /*使能SD卡中断*/
        __HAL_SD_ENABLE_IT(hsd,SDIO_IT_DATAEND|SDIO_IT_RXOVERR|SDIO_IT_DTIMEOUT|SDIO_IT_DCRCFAIL);
        __HAL_SD_DMA_ENABLE(hsd);
   /*DMA传输配置*/
        SD_DMA_TxConfig(hsd);
  /*打开DMA传输*/
        HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pData, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);        
        return errorstatus;
}


回复

使用道具 举报

发表于 2018-1-23 17:58:01 | 显示全部楼层
尝试下建个大点的buff,网络接收到一定量之后再写入
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-1-23 19:18:51 | 显示全部楼层
姬银瑶 发表于 2018-1-23 17:58
尝试下建个大点的buff,网络接收到一定量之后再写入

感觉不是buff的问题,觉得程序有问题,我设置的是上位机每次发送2048个字节,STM32每次接收2048个字节,接收到一定量,是设置多个buff,最后拼在一起吗?还是怎么样?
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-4-27 05:55 , Processed in 0.026586 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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