找回密码
 立即注册
查看: 77|回复: 5

关于STC-ISP串口发送文件的问题 | 已清楚

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:14
  • 最近打卡:2025-12-16 13:03:08
已绑定手机

1

主题

5

回帖

67

积分

注册会员

积分
67
发表于 2025-11-15 01:03:13 | 显示全部楼层 |阅读模式
截图20251115005716.png



发送文件比较大,为了正确传输。需要分包发送 + 应答式发送
测试发现文件大小必须是数据包的整数倍,如果有余数则不发送。
请问下这个问题怎么解决?还是我哪里设置错了。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:266
  • 最近打卡:2025-12-16 08:29:17

812

主题

1万

回帖

2万

积分

管理员

积分
21274
发表于 2025-11-15 08:35:20 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:14
  • 最近打卡:2025-12-16 13:03:08
已绑定手机

1

主题

5

回帖

67

积分

注册会员

积分
67
发表于 2025-11-15 22:12:16 | 显示全部楼层
神*** 发表于 2025-11-15 08:35
用最新软件测试下

深圳国芯人工智能有限公司-工具软件

截图20251115220443.png

试过了,还是不行。
有的文件数据大小不好分完整的包。或者单包的数量很小,包的总数很多,传输效率太低。
要是能发送剩余的字节数,或者自动补全也行。大不了过滤无效字节。

点评

串口助手发送文件,本来就是数据不足,自动填0补全 我测试的数据如下: [attachimg]121404[/attachimg] 我看你发送的最后一包数据也有自动填0补全 [attachimg]121405[/attachimg] 可能是你的计数器少计了一包  详情 回复 发表于 2025-11-17 12:15
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:109
  • 最近打卡:2025-12-16 11:05:13

30

主题

1215

回帖

4619

积分

超级版主

积分
4619
发表于 2025-11-17 12:15:59 | 显示全部楼层
梦回*** 发表于 2025-11-15 22:12
试过了,还是不行。
有的文件数据大小不好分完整的包。或者单包的数量很小,包的总数很多,传输效率太 ...

串口助手发送文件,目前的设计就是数据不足,自动填0补全
我测试的数据如下:
截图202511171207133789.jpg

我看你发送的最后一包数据也有自动填0补全
截图202511171209227629.jpg

可能是你的计数器少计了一包

附件是我的测试代码,你可以测试看看

文件发送测试代码.zip

61.04 KB, 下载次数: 1

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:14
  • 最近打卡:2025-12-16 13:03:08
已绑定手机

1

主题

5

回帖

67

积分

注册会员

积分
67
发表于 2025-11-17 13:06:04 | 显示全部楼层
zh*** 发表于 2025-11-17 12:15
串口助手发送文件,目前的设计就是数据不足,自动填0补全
我测试的数据如下:

麻烦帮我看下代码



/**
***********************************************************
* @brief 文件烧录
* @param
* @return
* @note   命令格式:FT+WR+FILE=<"文件名称">,<文件大小>,<数据包大小>,<"数据请求命令">,<\r\n><crc>
*         示例:   FT+WR+FILE="0:pictrue.bmp",5054,133,"FT_REQ",\r\ncrc
***********************************************************
*/
void Fatfs_FileBurnTask(void)
{
        static UartWriteFatfsState state = FAT_WAIT_CMD;
        static uint8_t reqCnt = 0;  // 数据请求次数
        static bool reqFlag = true; // true-立即请求,false-每隔N秒请求
        uint16_t crc_code = 0;
       
        switch(state)
        {
                case FAT_WAIT_CMD:
                        g_pktRcvdLen = UartRecvData_Get(g_recvBuf);
                        if(g_pktRcvdLen == 0)  
                        {
                                return; // 未接收到命令
                        }
                        if(g_pktRcvdLen < DATA_PACK_LEN_MIN)
                        {
                                ClearRecvBuf();
                                return;  // 数据包长度不足
                        }
                        if(strstr((const char*)g_recvBuf,"FT+WR+FILE") != NULL)
                        {
                                fileInfo.crc = g_recvBuf[g_pktRcvdLen-CRC_INDEX_OFFSET + 1] << 8 | g_recvBuf[g_pktRcvdLen-CRC_INDEX_OFFSET];
                                crc_code = usMBCRC16(g_recvBuf, g_pktRcvdLen - 2);
                                if(crc_code != fileInfo.crc)
                                {
                                        ClearRecvBuf();
                                        printf("FT_CRC_ERROR\r\n");
                                        return;  // crc校验错误
                                }

                                // 获取文件信息
                                memset(fileInfo.fileName, 0, FILE_NAME_MAX);
                                memset(fileInfo.dataReqCmd, 0, DATA_REQ_MAX);
                                int ret = sscanf((char*)g_recvBuf, "FT+WR+FILE=\"%[^\"]\",%u,%u,\"%[^\"]\"",
                                fileInfo.fileName, &fileInfo.fileSize, &fileInfo.packLen, fileInfo.dataReqCmd);
                                if(ret != 4)
                                {
                                        ClearRecvBuf();
                                        printf("FT_CMD_ERROR\r\n");
                                        return;  // 指令错误
                                }
                                ClearRecvBuf();
                               
                                // 打印参数信息
                                printf("fileName : %s\r\n",fileInfo.fileName);
                                printf("fileSize : %u\r\n", fileInfo.fileSize);
                                printf("packLen : %u\r\n", fileInfo.packLen);
                                printf("dataReqCmd : %s\r\n", fileInfo.dataReqCmd);
                                printf("crc : 0x%X\r\n", fileInfo.crc);
                               
                                if(Fatfs_InitState_Get() == false)
                                {
                                        state = FAT_WAIT_CMD;
                                        printf("fatfs init fail\r\n");
                                        return; // 文件系统参数失败
                                }
                               
                                if(f_open(&file, (const char*)fileInfo.fileName, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) // 创建一个文件,如果文件存在就覆盖掉,允许写操作
                                {
                                        printf("file open fail\r\n");
                                        return;  // 打开文件失败
                                }
                               
                                fileInfo.writeLen = 0;     // 计数清零
                                sysTime = GetSysRunTime(); // 保存系统运行时间
                                state = FAT_RECV_DATA;
                        }
                        break;
                       
                case FAT_RECV_DATA:
                        g_pktRcvdLen = UartRecvData_Get(g_recvBuf);
                        if(g_pktRcvdLen == 0)
                        {
                                //没有接收到数据,每隔5秒发送一次输请求指令
                                if((GetSysRunTime() - sysTime > 5000U) || (reqFlag == true))
                                {
                                        reqFlag = false;
                                        UartSendData(fileInfo.dataReqCmd); // 发送数据请求
                                        sysTime = GetSysRunTime();      // 保存系统运行时间
                                        reqCnt++;
                                        if(reqCnt == 12)
                                        {
                                                reqCnt = 0;
                                                f_close(&file);  // 关闭文件
                                                f_unlink((const char*)fileInfo.fileName); // 删除文件
                                                state = FAT_WAIT_CMD;
                                                printf("recv timeout\r\n");  // 接收超时
                                        }
                                }
                        }
                        else
                        {
                                reqCnt = 0;  // 请求计数清零
                                if(g_pktRcvdLen < DATA_PACK_LEN_MIN)
                                {
                                        return; // 数据包长度不符,继续等待。
                                }
                               
                                fileInfo.crc = g_recvBuf[g_pktRcvdLen-CRC_INDEX_OFFSET + 1] << 8 | g_recvBuf[g_pktRcvdLen-CRC_INDEX_OFFSET];
                                crc_code = usMBCRC16(g_recvBuf, g_pktRcvdLen - 2);
                                if(crc_code != fileInfo.crc)
                                {
                                        ClearRecvBuf();
                                        f_close(&file);  // 关闭文件
                                        f_unlink((const char*)fileInfo.fileName); // 删除文件
                                        state = FAT_WAIT_CMD;
                                        printf("FT_DATA_CRC_ERROR\r\n");
                                        return;  // 数据crc校验错误
                                }
                                // 到这里已经接到到一帧正确的数据
                               
                                uint32_t writeNum = 0;
                                if (f_write(&file, g_recvBuf, g_pktRcvdLen - 2, &writeNum) != FR_OK)  
                                {
                                        ClearRecvBuf();
                                        f_close(&file);  // 关闭文件
                                        f_unlink((const char*)fileInfo.fileName); // 删除文件
                                        state = FAT_WAIT_CMD;
                                        printf("FT_DATA_WRITE_FAIL\r\n");
                                        return;  // 数据写入失败
                                }
                               
                                if(writeNum != g_pktRcvdLen - 2)
                                {
                                        printf("write error\r\n");
                                }
                               
                                reqFlag = true;
                                printf("writeLen = %u\r\n", fileInfo.writeLen);
                               
                                ClearRecvBuf();  // 数据存储区清零
                                fileInfo.writeLen += writeNum;  // 成功写入的数据计数
                                if(fileInfo.writeLen == fileInfo.fileSize)
                                {
                                        uint32_t fileSize = f_size(&file);
                                        printf("fileSize = %u\r\n", fileSize);
                                        f_close(&file);  // 关闭文件
                                        state = FAT_WRITE_END;
                                }
                        }
                        break;
               
                case FAT_WRITE_END:
                        printf("file write end\r\n");
                        printf("data = %u\r\n", fileInfo.writeLen);
                        state = FAT_WAIT_CMD;
                        break;
               
                default:
                        state = FAT_WAIT_CMD;
                        break;
        }
}


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:14
  • 最近打卡:2025-12-16 13:03:08
已绑定手机

1

主题

5

回帖

67

积分

注册会员

积分
67
发表于 2025-11-17 13:14:02 | 显示全部楼层
zh*** 发表于 2025-11-17 12:15
串口助手发送文件,目前的设计就是数据不足,自动填0补全
我测试的数据如下:


谢谢您的提醒,我找到问题了。下面代码出现问题了,
printf提前打印信息了。而且还需要减去无效数据。




                                 printf("writeLen = %u\r\n", fileInfo.writeLen);
                              
                                ClearRecvBuf();  // 数据存储区清零
                                fileInfo.writeLen += writeNum;  // 成功写入的数据计数
                                if(fileInfo.writeLen == fileInfo.fileSize)
                                {
                                        uint32_t fileSize = f_size(&file);
                                        printf("fileSize = %u\r\n", fileSize);
                                        f_close(&file);  // 关闭文件
                                        state = FAT_WRITE_END;
                                }
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-12-16 17:54 , Processed in 0.114054 second(s), 77 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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