mnydxk 发表于 2018-1-23 16:28:44

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

本帖最后由 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;}



nyszx 发表于 2018-1-23 16:57:49

可以先看一下是TCP接收慢,还是SD写入慢

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? 这个频率能跑起来就不错了。

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]
查看完整版本: 通过TCP传输数据到STM32,并写到SD卡上,速度很慢