HANDLE hCom;
hCom = CreateFile(_T("COM3"),//COM1口
GENERIC_READ|GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
0, //同步方式
NULL);
if(hCom == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DCB dcb;
GetCommState(hCom, &dcb);
//波特率 110 300 600 1200 2400 4800 9600 14400 19200 38400 56000 57600 115200 128000 256000
dcb.BaudRate = CBR_9600;
//数据位 5 6 7 8
dcb.ByteSize = 8;
//校验位
//none无校验 NOPARITY
//even偶校验 EVENPARITY
//odd奇校验 ODDPARITY
//mark符号校验 MARKPARITY
//space空格校验 SPACEPARITY
dcb.Parity = NOPARITY;
//停止位
//1位 ONESTOPBIT
//1.5位 ONE5STOPBITS
//2位 TWOSTOPBITS
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(hCom, &dcb))
{
return FALSE;
}
COMMTIMEOUTS TimeOut;
memset(&TimeOut, 0, sizeof(TimeOut));
TimeOut.ReadIntervalTimeout = MAXDWORD;
SetCommTimeouts(hCom, &TimeOut);
SetupComm(hCom, 1024, 1024);
PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
DWORD written = 0;
BYTE s[8];
s[0]=0x01;
s[1]=0x03;
s[2]=0x00;
s[3]=0x00;
s[4]=0x00;
s[5]=0x01;
s[6]=0x84;
s[7]=0x0A;
//s[6]和s[7]是CRC_16的校验的低位和高位
WriteFile(hCom, s, 8, &written,NULL);
BYTE pBuff[1024];
DWORD read = 0;
ReadFile(hCom , pBuff , 1024 , &read , NULL);
CloseHandle(hCom);
在发送数据时需要注意的是:
比如我们进行modbus发送:01 03 00 00 00 01 84 0A 这个数据,
用下面的方式发送是不成功的
BYTE *sWrite = _T("01 03 00 00 00 01 84 0A ");
int len = strlen(sWrite);
WriteFile(hCom, sWrite, len, &written,NULL);
应该用下面的方式发送
BYTE sWrite[1024];
sWrite[0] = 0x01;
sWrite[1] = 0x03;
sWrite[2] = 0x00;
sWrite[3] = 0x00;
sWrite[4] = 0x00;
sWrite[5] = 0x01;
sWrite[6] = 0x84;
sWrite[7] = 0x0a;
WriteFile(hCom, sWrite, 8, &written,NULL);
这就是 串口调试助手上需要点16进制发送,才能发送成功的原因,其实简单来说就是 “01” 不等于 0x01。
它在内部进行了转换,把字符串的 “01” 转换成整数的01,下面的代码实现:
TCHAR* ch = _T(“01”);
int byte;
_stscanf_s(ch, _T("%x"), &byte);
同步通信比异步通信实现简单,可以适合小数据量的通信,但是它在发送数据和接收数据时,会阻塞线程,直到数据返回时才会继续运行,所以一般建议用异步通信来实现。