//[Default] Fill in the DCB: baud=9,600 bps, 8 data bits, no parity, and 1 stop bit. dcb.BaudRate = bandRate; // set the baud rate dcb.ByteSize = byteSize; // data size, xmit, and rcv dcb.Parity = parity; // no parity bit 0 dcb.StopBits = stopBits; // one stop bit 0 //设置串口设备状态 fSuccess = SetCommState(m_hDev, &dcb); if (!fSuccess) { sprintf(m_errMsg,"设置设备状态信息失败 -> %d.\n\n", GetLastError()); ::MessageBox(NULL,m_errMsg,"提示",0); return; }
BOOL CCESeries::OpenPort(void * pOwner,
UINT portNo , /*串口号*/
UINT baud , /*波特率*/
UINT parity , /*奇偶校验*/
UINT databits , /*数据位*/
UINT stopbits /*停止位*/
)
{
DCB commParam;
TCHAR szPort[15]; ASSERT(pOwner!=NULL);
m_pOwner = pOwner;
// 已经打开的话,直接返回
if (m_hComm != INVALID_HANDLE_VALUE)
{
return TRUE;
}
//设置串口名
wsprintf(szPort, L"COM%d:", portNo);
//打开串口
m_hComm = CreateFile(
szPort,
GENERIC_READ | GENERIC_WRITE, //允许读和写
0, //独占方式(共享模式)
NULL,
OPEN_EXISTING, //打开而不是创建(创建方式)
0,
NULL
);
if (m_hComm == INVALID_HANDLE_VALUE)
{
// 无效句柄,返回。
TRACE(_T("CreateFile 返回无效句柄\n"));
return FALSE;
}
// 得到打开串口的当前属性参数,修改后再重新设置串口。
if (!GetCommState(m_hComm,&commParam))
{
//关闭串口
CloseHandle (m_hComm);
m_hComm = INVALID_HANDLE_VALUE;
return FALSE;
}
//设置串口参数
commParam.BaudRate = baud; // 设置波特率
commParam.fBinary = TRUE; // 设置二进制模式,此处必须设置TRUE
commParam.fParity = TRUE; // 支持奇偶校验
commParam.ByteSize = databits; // 数据位,范围:4-8
commParam.Parity = parity; // 校验模式
commParam.StopBits = stopbits; // 停止位
commParam.fOutxCtsFlow = FALSE; // No CTS output flow control
commParam.fOutxDsrFlow = FALSE; // No DSR output flow control
commParam.fDtrControl = DTR_CONTROL_ENABLE;
// DTR flow control type
commParam.fDsrSensitivity = FALSE; // DSR sensitivity
commParam.fTXContinueOnXoff = TRUE; // XOFF continues Tx
commParam.fOutX = FALSE; // No XON/XOFF out flow control
commParam.fInX = FALSE; // No XON/XOFF in flow control
commParam.fErrorChar = FALSE; // Disable error replacement
commParam.fNull = FALSE; // Disable null stripping
commParam.fRtsControl = RTS_CONTROL_ENABLE;
// RTS flow control
commParam.fAbortOnError = FALSE; // 当串口发生错误,并不终止串口读写
//设置串口参数
if (!SetCommState(m_hComm, &commParam))
{
TRACE(_T("SetCommState error"));
//关闭串口
CloseHandle (m_hComm);
m_hComm = INVALID_HANDLE_VALUE;
return FALSE;
}
//设置串口读写时间
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts (m_hComm, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 10;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
if(!SetCommTimeouts( m_hComm, &CommTimeOuts ))
{
TRACE( _T("SetCommTimeouts 返回错误") );
//关闭串口
CloseHandle (m_hComm); m_hComm = INVALID_HANDLE_VALUE;
return FALSE;
}
//指定端口监测的事件集
SetCommMask (m_hComm, EV_RXCHAR);
//分配串口设备缓冲区
SetupComm(m_hComm,512,512);
//初始化缓冲区中的信息
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
CString strEvent;
strEvent.Format(L"Com_ReadCloseEvent%d",portNo);
m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,strEvent); //创建串口读数据监听线程
m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);
TRACE(_T("串口打开成功"));
m_bOpened = TRUE;
return TRUE;
}
BOOL CCESeries::WriteSyncPort(const BYTE*buf , DWORD bufLen)
{
DWORD dwNumBytesWritten;
DWORD dwHaveNumWritten =0 ; //已经写入多少
int iInc = 0; //如果3次写入不成功,返回FALSE
ASSERT(m_hComm != INVALID_HANDLE_VALUE);
do
{
if (WriteFile (m_hComm, //串口句柄
buf+dwHaveNumWritten, //被写数据缓冲区的首地址
bufLen - dwHaveNumWritten, //被写数据缓冲区大小
&dwNumBytesWritten, //函数执行成功后,返回实际向串口写的个数
NULL)) //此处必须设置NULL
{
dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;
//写入完成
if (dwHaveNumWritten == bufLen)
{
break;
}
iInc++;
if (iInc >= 3)
{
return FALSE;
}
Sleep(10);
}
else
{
return FALSE;
}
}while (TRUE);
return TRUE;
}
然后不管接不接串口,都在写串口,WriteFile的时候,死掉,然后程序无响应。
HANDLE m_hDev;
char m_errMsg[200];
//连接串口
void ConnectOperation(const char* commPort, DWORD bandRate, BYTE byteSize, BYTE parity, BYTE stopBits)
{
m_hDev = CreateFile(commPort,
GENERIC_READ | GENERIC_WRITE,
0, // comm devices must be opened w/exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if (m_hDev == INVALID_HANDLE_VALUE) {
sprintf(m_errMsg,"打开串口设备错误 -> %d.\n\n", GetLastError());
::MessageBox(NULL,m_errMsg,"提示",0);
return;
}
DCB dcb;
BOOL fSuccess;
//获取串口设备状态信息
fSuccess = GetCommState(m_hDev, &dcb);
if (!fSuccess) {
sprintf(m_errMsg,"获取设备状态信息失败 -> %d.\n\n", GetLastError());
::MessageBox(NULL,m_errMsg,"提示",0);
return;
}
//[Default] Fill in the DCB: baud=9,600 bps, 8 data bits, no parity, and 1 stop bit.
dcb.BaudRate = bandRate; // set the baud rate
dcb.ByteSize = byteSize; // data size, xmit, and rcv
dcb.Parity = parity; // no parity bit 0
dcb.StopBits = stopBits; // one stop bit 0
//设置串口设备状态
fSuccess = SetCommState(m_hDev, &dcb);
if (!fSuccess) {
sprintf(m_errMsg,"设置设备状态信息失败 -> %d.\n\n", GetLastError());
::MessageBox(NULL,m_errMsg,"提示",0);
return;
}
COMMTIMEOUTS comTimeOut;
comTimeOut.ReadIntervalTimeout = 1;//接收时,两字符间最大的时延
comTimeOut.ReadTotalTimeoutMultiplier = 1;//读取每字节的超时
comTimeOut.ReadTotalTimeoutConstant = 1;//读串口数据的固定超时
comTimeOut.WriteTotalTimeoutMultiplier = 1;//写每字节的超时
comTimeOut.WriteTotalTimeoutConstant = 1;//写串口数据的固定超时
//设备串口设备超时时限
fSuccess = SetCommTimeouts(m_hDev,&comTimeOut);
if (!fSuccess) {
sprintf(m_errMsg,"设置设备读写超时延迟失败 -> %d.\n\n", GetLastError());
::MessageBox(NULL,m_errMsg,"提示",0);
return;
}
//设备串口设备读写缓冲区大小,单位字节
fSuccess = SetupComm(m_hDev,640,640);
if (!fSuccess) {
sprintf(m_errMsg,"设置设备读写缓冲区失败 -> %d.\n\n", GetLastError());
::MessageBox(NULL,m_errMsg,"提示",0);
return;
}
}
//写入数据
void WriteDataToPort(const char *data)//不要超过缓冲区大小
{
DWORD recvLen;
if (!::WriteFile(m_hDev,data,strlen(data),&recvLen,NULL))
{
::MessageBox(NULL,"写入数据到串口设备失败","提示",0);
}
}
//读取数据
void ReadDataFromPort()
{
char recvMsg[640];
memset(recvMsg,0,sizeof(recvMsg));
DWORD recvLen;
if (!::ReadFile(m_hDev,recvMsg,640,&recvLen,NULL))
{
::MessageBox(NULL,"从串口设备读取数据失败","提示",0);
}
}
这里面使用OpenPort时不知怎么设为偶校验