WinCE 的串口问题,数据接收不完整!! 求帮助啊

时间:2021-05-04 17:41:43
发送缓冲区 用 0x00 - 0x7F填充,共1KB

发送的时候有时候一次write是写不完的。

另外,接收端接收的数量和发送的数量对不上。

我要是将发送缓冲区全部置成0xFF,则发送没有问题,接收也没有问题。

我想问问,是不是0x00-0x7f中,有些字符是有特殊含义的?

9 个解决方案

#1


我想问问,是不是0x00-0x7f中,有些字符是有特殊含义的?

有吗?没有吧!

你是用什么工具来看接受的字符数量呢???是不是这个工具把字符滤掉了呢???


如果你查看的是寄存器,还不知道答案,那就上示波器吧!


#2


应该不是字符有特殊含义的原因。
楼主写串口是通过wince的系统api writeFile来写的。
还是通过c#等SerialPort控件来写的
另外串口的超时时间是怎么设置的。

#3


使用API WriteFile   ReadFile  C语言
关键是我发送全0xFF就没事,线程中统计的数据总量,首发以致。对发送线程中丢数据也有检测,全发0xFF就没事(换0x00, 0x20 。。。都可以)。 就是给发送数据的缓冲区设置成字节和字节不一样的值就不行了!真奇怪,有没有碰到过,我完全迷茫了!!

#4


发送全部一样的数据,例如0xff,就没事。这种理解不准确。因为看不出数据的变化,实际上是看不出来没有发丢的。所以不要再纠结在一样的数据就没错,不一样的数据就有错上面了。
还有你说的发送缓冲设置不知道是什么意思。发送是查询发送的吗?接收呢,是中断接收的吗?串口发送是一个字节一个字节发送的吗?丢失的部分是在数据末尾,还是什么地方。多总结调试的现象,用排除法来排除各种情况。
你也可以把错误的情况说的更具体一点,再发上来。

#5


应该是你程序的问题,例如,可能是你接收端统计个数出错。

#6


发送统计是根据API的返回值, 接收是根据写入的文件大小以及API的返回值。因此我认为统计是没有错的。
各位大虾:我还是贴代码,有劳各位不吝赐教!

发送

DWORD CComm::XmitThreadProc(LPVOID lParam) 
{
Parameter *lpParam = (Parameter *)lParam;
DWORD dwTotalXmit = 0;
DWORD dwOnceXmit = 0;
PBYTE pBuf;
BOOL fRet;
DWORD timeBegin = 0;
DWORD timeEnd = 0;
timeBegin = GetTickCount();
BYTE dat[1024] = {0};
// memset(dat, 0xff, 1024); // 置全0xff
        /**********/
        int i;
for (i=0; i<1024; i++) {
dat[i] = i%0x80;
}
        /************/
for (;;) {
pBuf = dat;
fRet = WriteFile(lpParam->hComm, pBuf, 1024, &dwOnceXmit, NULL);
if (!fRet) {
_tprintf(_T("xmit error, code:%d...\n"), GetLastError());
return 1;
} else {
if (dwOnceXmit < 1024) {  // 位置1
_tprintf(_T("COM%d Send lost.\n"), lpParam->dwPortID);
}
dwTotalXmit += dwOnceXmit;
}
if (WaitForSingleObject(lpParam->hStopEvt, 0) == WAIT_OBJECT_0) {
break;
}
Sleep(lpParam->dwDelay);
}
if (timeEnd == 0) {
timeEnd = GetTickCount();
}
lpParam->dwActualLen = dwTotalXmit;
lpParam->dwSpeed = (DWORD)(dwTotalXmit / ((timeEnd-timeBegin)/1000.f));
return 0;
}


接收部分 前半部分都是定义,主要是那个for循环中

DWORD CComm::RecvThreadProc(LPVOID lParam)
{
Parameter *lpParam = (Parameter *)lParam;
DWORD dwTotalRecv = 0;
DWORD dwOnceRecv = 0;
BOOL fRet;
DWORD timeBegin = 0;
DWORD timeEnd = 0;
BOOL isBegin = false;
BYTE recvBuf[1024];
ZeroMemory(recvBuf, sizeof(recvBuf));
TCHAR fileName[MAX_PATH];
BYTE bound[4];
BOOL isEnd = false;
DWORD boundCnt = 0;
ZeroMemory(fileName, _countof(fileName)*sizeof(fileName[0]));
_stprintf_s(fileName, _countof(fileName), TEXT("COM%d.bin"), lpParam->dwPortID);
HANDLE hFile = CreateFile(fileName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
return 1;
}
DWORD dwWriteBytes;
DWORD dwEvt;
SetCommMask(lpParam->hComm, EV_RXCHAR);
for (;;) {
if (WaitCommEvent(lpParam->hComm, &dwEvt, NULL)) {
SetCommMask(lpParam->hComm, EV_RXCHAR);
if (dwEvt & EV_RXCHAR) {
if (!isBegin) {
timeBegin = GetTickCount();
isBegin = true;
}
fRet = ReadFile(lpParam->hComm, recvBuf, sizeof(recvBuf), &dwOnceRecv, NULL);
if (!fRet) {
CloseHandle(hFile);
hFile = NULL;
return 1;
} else {
if (!WriteFile(hFile, recvBuf, dwOnceRecv, &dwWriteBytes, NULL)) {
CloseHandle(hFile);
hFile = NULL;
return 1;
} else {
FlushFileBuffers(hFile);
dwTotalRecv += dwOnceRecv;
ZeroMemory(recvBuf, sizeof(recvBuf));
}
}
}
}
if (WaitForSingleObject(lpParam->hStopEvt, 0) == WAIT_OBJECT_0) {
break;
}
Sleep(lpParam->dwDelay);
}
if (timeEnd == 0) {
timeEnd = GetTickCount();
}
CloseHandle(hFile);
hFile = NULL;
// 计算速度,填充参数
lpParam->dwSpeed = (DWORD)(dwTotalRecv / ((timeEnd-timeBegin)/1000.f));
lpParam->dwActualLen = dwTotalRecv;
lpParam->pDataBuf = NULL;
return 0;
}


加入发送里头我只做全部置0xff的话,收发统计都正常,如果用那个循环将缓冲区用0-127填充,再发送就不行了,这种情况下,偶尔 位置1(见注释)还会判断失败

#7


这个东西要好好调整的

#8


参考下串口实例
http://download.csdn.net/source/3114525

#9


问题解决了,确实有敏感字符  打开串口的时候启动了软件xon/xoff, 发送的数据中字符存在DC1 DC3,造出如是问题。

多谢各位关注
晚上结贴

#1


我想问问,是不是0x00-0x7f中,有些字符是有特殊含义的?

有吗?没有吧!

你是用什么工具来看接受的字符数量呢???是不是这个工具把字符滤掉了呢???


如果你查看的是寄存器,还不知道答案,那就上示波器吧!


#2


应该不是字符有特殊含义的原因。
楼主写串口是通过wince的系统api writeFile来写的。
还是通过c#等SerialPort控件来写的
另外串口的超时时间是怎么设置的。

#3


使用API WriteFile   ReadFile  C语言
关键是我发送全0xFF就没事,线程中统计的数据总量,首发以致。对发送线程中丢数据也有检测,全发0xFF就没事(换0x00, 0x20 。。。都可以)。 就是给发送数据的缓冲区设置成字节和字节不一样的值就不行了!真奇怪,有没有碰到过,我完全迷茫了!!

#4


发送全部一样的数据,例如0xff,就没事。这种理解不准确。因为看不出数据的变化,实际上是看不出来没有发丢的。所以不要再纠结在一样的数据就没错,不一样的数据就有错上面了。
还有你说的发送缓冲设置不知道是什么意思。发送是查询发送的吗?接收呢,是中断接收的吗?串口发送是一个字节一个字节发送的吗?丢失的部分是在数据末尾,还是什么地方。多总结调试的现象,用排除法来排除各种情况。
你也可以把错误的情况说的更具体一点,再发上来。

#5


应该是你程序的问题,例如,可能是你接收端统计个数出错。

#6


发送统计是根据API的返回值, 接收是根据写入的文件大小以及API的返回值。因此我认为统计是没有错的。
各位大虾:我还是贴代码,有劳各位不吝赐教!

发送

DWORD CComm::XmitThreadProc(LPVOID lParam) 
{
Parameter *lpParam = (Parameter *)lParam;
DWORD dwTotalXmit = 0;
DWORD dwOnceXmit = 0;
PBYTE pBuf;
BOOL fRet;
DWORD timeBegin = 0;
DWORD timeEnd = 0;
timeBegin = GetTickCount();
BYTE dat[1024] = {0};
// memset(dat, 0xff, 1024); // 置全0xff
        /**********/
        int i;
for (i=0; i<1024; i++) {
dat[i] = i%0x80;
}
        /************/
for (;;) {
pBuf = dat;
fRet = WriteFile(lpParam->hComm, pBuf, 1024, &dwOnceXmit, NULL);
if (!fRet) {
_tprintf(_T("xmit error, code:%d...\n"), GetLastError());
return 1;
} else {
if (dwOnceXmit < 1024) {  // 位置1
_tprintf(_T("COM%d Send lost.\n"), lpParam->dwPortID);
}
dwTotalXmit += dwOnceXmit;
}
if (WaitForSingleObject(lpParam->hStopEvt, 0) == WAIT_OBJECT_0) {
break;
}
Sleep(lpParam->dwDelay);
}
if (timeEnd == 0) {
timeEnd = GetTickCount();
}
lpParam->dwActualLen = dwTotalXmit;
lpParam->dwSpeed = (DWORD)(dwTotalXmit / ((timeEnd-timeBegin)/1000.f));
return 0;
}


接收部分 前半部分都是定义,主要是那个for循环中

DWORD CComm::RecvThreadProc(LPVOID lParam)
{
Parameter *lpParam = (Parameter *)lParam;
DWORD dwTotalRecv = 0;
DWORD dwOnceRecv = 0;
BOOL fRet;
DWORD timeBegin = 0;
DWORD timeEnd = 0;
BOOL isBegin = false;
BYTE recvBuf[1024];
ZeroMemory(recvBuf, sizeof(recvBuf));
TCHAR fileName[MAX_PATH];
BYTE bound[4];
BOOL isEnd = false;
DWORD boundCnt = 0;
ZeroMemory(fileName, _countof(fileName)*sizeof(fileName[0]));
_stprintf_s(fileName, _countof(fileName), TEXT("COM%d.bin"), lpParam->dwPortID);
HANDLE hFile = CreateFile(fileName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
return 1;
}
DWORD dwWriteBytes;
DWORD dwEvt;
SetCommMask(lpParam->hComm, EV_RXCHAR);
for (;;) {
if (WaitCommEvent(lpParam->hComm, &dwEvt, NULL)) {
SetCommMask(lpParam->hComm, EV_RXCHAR);
if (dwEvt & EV_RXCHAR) {
if (!isBegin) {
timeBegin = GetTickCount();
isBegin = true;
}
fRet = ReadFile(lpParam->hComm, recvBuf, sizeof(recvBuf), &dwOnceRecv, NULL);
if (!fRet) {
CloseHandle(hFile);
hFile = NULL;
return 1;
} else {
if (!WriteFile(hFile, recvBuf, dwOnceRecv, &dwWriteBytes, NULL)) {
CloseHandle(hFile);
hFile = NULL;
return 1;
} else {
FlushFileBuffers(hFile);
dwTotalRecv += dwOnceRecv;
ZeroMemory(recvBuf, sizeof(recvBuf));
}
}
}
}
if (WaitForSingleObject(lpParam->hStopEvt, 0) == WAIT_OBJECT_0) {
break;
}
Sleep(lpParam->dwDelay);
}
if (timeEnd == 0) {
timeEnd = GetTickCount();
}
CloseHandle(hFile);
hFile = NULL;
// 计算速度,填充参数
lpParam->dwSpeed = (DWORD)(dwTotalRecv / ((timeEnd-timeBegin)/1000.f));
lpParam->dwActualLen = dwTotalRecv;
lpParam->pDataBuf = NULL;
return 0;
}


加入发送里头我只做全部置0xff的话,收发统计都正常,如果用那个循环将缓冲区用0-127填充,再发送就不行了,这种情况下,偶尔 位置1(见注释)还会判断失败

#7


这个东西要好好调整的

#8


参考下串口实例
http://download.csdn.net/source/3114525

#9


问题解决了,确实有敏感字符  打开串口的时候启动了软件xon/xoff, 发送的数据中字符存在DC1 DC3,造出如是问题。

多谢各位关注
晚上结贴