Windows下串口编程 发送文件给单片机总有数据丢失 5C
 DWORD WINAPI ThreadWrite(LPVOID lpParameter)//进程1  
{  
    char outputData[100];//输出数据缓存  
    FILE * outfile;
    char *str = "1234567812345678";
    DWORD dwErrorFlags;
    COMSTAT ComStat;
    int c = 0;
    int rc = 0;
    BOOL bWriteStat;
    OVERLAPPED m_osWrite;

    outfile = fopen("E:/ziku/ziku.bin", "rb" );

    if( hCom==INVALID_HANDLE_VALUE )  
    {  
        puts("打开串口失败");  
        return 0;  
    }  

    DWORD strLength = 0;  
    PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
    while(rc = fread(outputData,sizeof(unsigned char),16,outfile))  
    {  
         PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);           //清空缓冲区  

        bWriteStat = WriteFile(hCom,outputData,rc,&strLength,&m_osWrite); // 串口发送字符串  

        if(!bWriteStat)
        { 
            if(GetLastError()==ERROR_IO_PENDING)
            { 
                WaitForSingleObject(m_osWrite.hEvent,10000); 
            } 

        }


        Sleep(100);  
    }  
    return 0;  
}

这样写用虚拟串口发送给串口助手时没有问题的,但是发送给单片机数据丢失特别严重望大佬指点。

4个回答

单片机和电脑处理数据的能力差的太多,可能是sleep延时不够,把while去了,尝试只发送一次试试

首先确认一下串口的参数,波特率、数据位、停止位这些是否对的上;
如果参数都对上了,用你的串口助手向模拟数据发给单片机,看看是不是会丢失。

vividzll
vividzll 这些我都试过了,串口助手发送是没有问题的,这段程序已经调了一个礼拜了,能试的我都试了
大约 2 年之前 回复

(默认串口通信的波特率、数据为、停止位都配置正确,这是基本常识,不要出错)
看你的描述,可以先验证一下是哪里出问题,可以用串口助手给单片机发是否有问题,如果也有问题就能肯定是单片机的串口模块出问题,一般丢数据,是因为单片机串口接收数据不及时,推荐接收数据采用中断方式,并且中断处理函数中,尽量少写逻辑处理,仅进行数据接收,因为中断处理时会先关中断-处理数据-开中断,如果处理数据时间太长,肯定会丢调后续的中断事件,一般考虑2点进行尝试修改:
1.中断接收数据直接使用寄存器级别的读取,如直接操作串口寄存器模块的DR(data register)进行读取数据,避免使用系统SDK封装的get data接口;
2.考虑系统时钟是否配置正确,比如大家都是9600的波特率,如果你的单片机时钟慢,那你的9600可能不准;
一般这种问题要自己修改着看,考虑各种可能原因进行尝试排除,问题答案就会越来越明晰,Good luck!

tangtang520512
haifeng1314520 确认下单片机的晶振,一般这种问题都是波特率不一致导致
大约 2 年之前 回复
vividzll
vividzll 谢谢层主回答的这么详细,单片机这边是不存在问题的,我接收本来采用的就是中断的方式,而且用网上的串口助手发送文件是可以完全接收的,所以问题是出现在这段代码里
大约 2 年之前 回复

试试,将m_osWrite置为NULL试试,
总感觉你的编程思路是同步模式,就不要随意给这种变量赋值了。

另外,你的单片机最大文件缓冲应该远不止100个字节吧。如不是,则可能还要根据错误码,GetLastError(),再结合strLength循环重复发送了。

没做过单片机编程,给你个思路了。

vividzll
vividzll 回复weixin_41986182: 那个100只是个数组,我每次从文件里读取16字节,我发送的压实16字节我不是100字节
大约 2 年之前 回复
weixin_41986182
weixin_41986182 回复weixin_41986182: 但一般情况下,区区100个字节在PC与PC上是一点问题也没有了。你的丢包可能是你的单片机文件缓冲太小再加上读的效率较低造成的。
大约 2 年之前 回复
weixin_41986182
weixin_41986182 回复weixin_41986182: 同步的话,write函数返回后就可以根据函数返回值及参数续写。异步的话不行,需要在异步触发函数里面去做这个事,因为异步的wirte函数返回了并不代表写完了。
大约 2 年之前 回复
weixin_41986182
weixin_41986182 回复vividzll: 不管同步还是异步,都有可能你要写100个字节,但实际只写了95个。所以需要你根据返回再续写后面的5个。
大约 2 年之前 回复
vividzll
vividzll 同步的也写了一个数据丢失是会好一点,但还是会丢失,按照要求我应该写异步的,因为在发送的时候还需要接收
大约 2 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问