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

通过TCP传输数据到STM32,并写到SD卡上,速度很慢

[复制链接]
mnydxk 提问时间:2018-1-23 16:28 /
本帖最后由 mnydxk 于 2018-1-23 16:38 编辑

上位机通过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;
}




时钟配置

时钟配置

中断配置

中断配置
收藏 评论5 发布时间:2018-1-23 16:28

举报

5个回答
nyszx 回答时间:2018-1-23 16:57:49
可以先看一下是TCP接收慢,还是SD写入慢

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

mnydxk 回答时间:2018-1-23 19:16:19
nyszx 发表于 2018-1-23 16:57
可以先看一下是TCP接收慢,还是SD写入慢

刚刚用KEIL断点调试看了一下时间,当我的上位机设置一次发送4KB的数据,STM32接收4KB的数据,然后将4KB的数据存入到SD卡中,接收的速度是21.84KB/s,写SD卡的速度为682.5KB/S;
如果是2KB数据,接收速度是21.6KB/s,写SD卡速度是392.233KB/s;
TCP接收的速度好像很慢。。。
衔胆栖冰 回答时间:2018-1-24 13:44:48
如图,大佬,你的主时钟设置了8MHz ? SDIO时钟从4MHz? 这个频率能跑起来就不错了。 162628lc5qosxccsxcsnzk.png

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

mnydxk 回答时间:2018-1-25 10:15:33
衔胆栖冰 发表于 2018-1-24 13:44
如图,大佬,你的主时钟设置了8MHz ? SDIO时钟从4MHz? 这个频率能跑起来就不错了。

...

要求是设置成8Mhz,没有办法,但是感觉还是太慢了。。
HAL库时钟设置的SDIO为HCLK的1/2
无薪税绵 回答时间:2018-3-6 14:58:35
不知道你使用的网络芯片是什么。
一般情况下,网络带宽,最小都有10M的,不可能会慢的。

估计是你的网络处理有延时吧。
试试 ping 一下你的STM32板子的IP地址,看看延时是多少。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

所属标签

相似问题

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