首页
社区
课程
招聘
[求助]WIN32串口开发,读取数据错乱
发表于: 2017-7-10 21:01 4777

[求助]WIN32串口开发,读取数据错乱

2017-7-10 21:01
4777

出现问题是这样的:

1.当我程序运行起来,串口已经打开准备接收数据,这时用串口助手向串口发送数据,数据正常。

2.但是我先用串口助手不停发数据,然后再打开写的程序接收程序,数据出现错乱,这里的错乱不是指顺序错乱,而是出现了发送数据里根本没有的数据。


不停发送的是16字节数据:AA 00 00 08 00 00 00 01 00 AA 00 00 AA 00 AA

情况1数据正常:

情况2数据错乱:

出现了根本没有的数据。

————————————————————————————————————————————————————————————————————

我用两个串口助手互传,都接收正常,肯定是程序的问题。所以希望大神们帮我看一看代码。

我准备用的是线程+同步IO读取。


串口配置代码如下,都是抄的网上的,感觉这部分出错的概率比较大?

void SETUP_DCB()
{
	DCB dcb;
	memset(&dcb, 0, sizeof(DCB) );
	GetCommState(hComFile, &dcb);
	dcb.DCBlength = sizeof(DCB);
	dcb.BaudRate = 9600; //波特率
	dcb.fParity = FALSE; //无奇偶校验
	dcb.Parity = NOPARITY; //无校验
	dcb.StopBits = ONESTOPBIT; //1位停止位
	dcb.ByteSize = 8; //数据位数
	dcb.fOutxCtsFlow = 0;
	dcb.fOutxDsrFlow = 0;
	dcb.fDtrControl = DTR_CONTROL_DISABLE;
	dcb.fDsrSensitivity = 0;
	dcb.fRtsControl = RTS_CONTROL_DISABLE;
	dcb.fOutX = 0;
	dcb.fInX = 0;
	dcb.fErrorChar = 0;
	dcb.fBinary = 1;
	dcb.fNull = 0;
	dcb.fAbortOnError = 0;
	dcb.wReserved = 0;
	dcb.XonLim = 2;
	dcb.XoffLim = 4;
	dcb.XonChar = 0x13;
	dcb.XoffChar = 0x19;
	dcb.EvtChar = 0;
	SetCommState(hComFile, &dcb);
}
		hComFile = CreateFile(L"COM3", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
		if (hComFile == INVALID_HANDLE_VALUE)
		{
			CloseHandle(hComFile);
			return TRUE;
		}
		SETUP_DCB();
		hThread = CreateThread(NULL, 0, MyThreadFunction, NULL, 0, &ThreadID);			


线程读取代码,主要功能就是帧同步,但是数据都是错乱的肯定不能同步了。

以下代码就读取错乱,读取的17字节不对:

DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
...
		i = ReadCount;
		while (i)
		{
			ClearCommError(hComFile, &Errors, &comstat);
			ReadFile(hComFile, pBuffer + ReadCount - i, i, &NumberOfRead, NULL);
			i -= NumberOfRead;
		}
...
}

完整读取代码:

DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
	DWORD NumberOfRead;
	DWORD Errors;
	COMSTAT comstat;
	unsigned char BUFFER[17], *pBuffer;
	unsigned char header, i;
	int ReadCount;
	ReadCount = 17;
	pBuffer = BUFFER;
	while (1)
	{
		i = ReadCount;
		while (i)
		{
			ClearCommError(hComFile, &Errors, &comstat);
			ReadFile(hComFile, pBuffer + ReadCount - i, i, &NumberOfRead, NULL);
			i -= NumberOfRead;
		}
		if (BUFFER[0] == 0xAA && BUFFER[16] == 0xAA) //有效帧
		{
			ReadCount = 17;
			pBuffer = BUFFER;
			continue;
		}
		for (header = 1; header < 17 && BUFFER[header] != 0xAA; header++);
		for (i = header; i < 17; i++)
			BUFFER[i - header] = BUFFER[i];
		ReadCount = header;
		pBuffer = BUFFER + (17 - ReadCount);
	}
}


希望大神指点指点,非常感谢!


[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 286
活跃值: (57)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
xjj
2
没细看帖子,一般乱码,考虑一下波特率。
2017-7-11 08:16
0
雪    币: 3
活跃值: (118)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
xjj 没细看帖子,一般乱码,考虑一下波特率。
可是也有正确接受的情况,波特率都是9600。我用串口助手30ms发16字节,是不是发的太快要做一些处理?
2017-7-11 09:18
0
雪    币: 1432
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
见到快乐
2017-7-11 09:27
0
雪    币: 3
活跃值: (118)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5

我用C#下的SerialPort写了一下,仍然出现这个问题。到底是哪里的问题的呢?下载的串口助手情况一和二接收都正常。

            _serialPort = new SerialPort();
            _serialPort.PortName = "com3";
            _serialPort.BaudRate = 9600;
            _serialPort.Parity = Parity.None;
            _serialPort.DataBits = 8;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Handshake = Handshake.XOnXOff;
            _serialPort.Open();
            for (int i = 0; i < 17; i++)
            {
                BUFFER[i] = (byte)_serialPort.ReadByte();
            }


2017-7-11 13:49
0
雪    币: 248
活跃值: (1056)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6

Write_Com_Port.hEvent

Read_Com_Port.hEvent

1、

invoke  CreateFile,CTXT("\\.\COM1"),GENERIC_READ or GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,NULL

    .if (eax == INVALID_HANDLE_VALUE)

        invoke  GetLastError

        .if (eax == ERROR_ACCESS_DENIED)

            movzx   eax,ComportNumber

            invoke  wsprintf,addr szString_buffer,CTXT("Com%d is already in use !"),eax

            invoke  MessageBox,0,addr szString_buffer,CTXT("eRROR:.."),MB_ICONINFORMATION            

        .endif

        jmp     ComPortError

    .endif

    mov     hComPort,eax

2、

invoke  ReadFile,hComPort,addr Buffer_RX,countInQue,addr countInQue,addr Read_Com_Port  

.if (!eax)

    invoke  GetLastError

    .if (eax == ERROR_IO_PENDING)

        invoke  GetOverlappedResult,hComPort,addr Read_Com_Port,addr countInQue,TRUE

;////////////////////////////////////////////////////////////////////////////////////////

invoke  WriteFile,hComPort,lpString,dwStringLength,addr dwSend,addr Write_Com_Port

    .if (!eax)

        invoke  GetLastError

        .if (eax == ERROR_IO_PENDING)

            invoke  GetOverlappedResult,hComPort,addr Write_Com_Port,addr dwSend,TRUE

2017-7-12 10:03
0
游客
登录 | 注册 方可回帖
返回
//