主题:[原创]各位兄弟帮我一下
小弟想实现硬件设备与任何COM口连接都可以,现在只能与COM1口连接,用USB转换的串口不能用,为什么?大家帮我看看.
#include "stdafx.h"
#include "SerialComm.h"
#include "sut.h"
#include "MainFrm.h"
#include "SutView.h"
#include "DlgPassage1.h"
#include "DlgPassage2.h"
#include "DlgTwoPassage.h"
#include "DlgPrescribeTherapy.h"
#include "DlgMain.h"
HANDLE hComm;
OVERLAPPED osRead, osWrite;
BYTE readBuffer[1024];
BYTE nReturnValue;
//读串口
DWORD ReadBlock(DWORD dwMaxLength)
{
DWORD dwBytesRead,dwError,dwErrorFlags;
BOOL fReadStat;
COMSTAT ComStat;
dwBytesRead =0 ;
ResetEvent(osRead.hEvent);
fReadStat=ReadFile(hComm, readBuffer, dwMaxLength, &dwBytesRead, &osRead);
if(!fReadStat)
{
if (GetLastError()==ERROR_IO_PENDING)
{
while(!GetOverlappedResult(hComm,&osRead,&dwBytesRead,TRUE))
{
dwError=GetLastError();
if(dwError == ERROR_IO_INCOMPLETE) continue;
}
}
else
{
dwBytesRead = 0;
ClearCommError(hComm,&dwErrorFlags,&ComStat);
}
};
return dwBytesRead;
};
//写串口
BOOL WriteBlock(LPVOID lpByte,DWORD dwBytesToWrite)
{
BOOL fWriteStat;
DWORD dwBytesWritten;
DWORD dwErrorFlags;
DWORD dwError;
COMSTAT ComStat;
ResetEvent(osWrite.hEvent);
fWriteStat=WriteFile(hComm,lpByte,dwBytesToWrite,
&dwBytesWritten,&osWrite);
if (!fWriteStat)
{
if(GetLastError()==ERROR_IO_PENDING)
{
while(!GetOverlappedResult(hComm, &osWrite,&dwBytesWritten,TRUE))
{
dwError=GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
continue;
else
{
ClearCommError(hComm,&dwErrorFlags,&ComStat);
break;
}
}
}
else
{
ClearCommError(hComm,&dwErrorFlags,&ComStat);
return ( FALSE );
}
}
return ( TRUE ) ;
}
DWORD InquiryBlock()
{
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError(hComm,&dwErrorFlags,&ComStat);
return ComStat.cbInQue;
}
int InitSerialPort()
{
hComm = CreateFile("COM1",
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL);
if(hComm == NULL) return -1;
DCB dcb;
CString strDCB;
BOOL bReturn;
bReturn = GetCommState(hComm,&dcb);
strDCB.Format("19200,n,8,1");
bReturn = BuildCommDCB(strDCB,&dcb);
bReturn = SetCommState(hComm,&dcb);
// bReturn = GetCommState(hComm,&dcb);
/* DCB dcb ; // 定义数据控制块结构
GetCommState(hCom, &dcb ) ; //读串口原来的参数设置
dcb.BaudRate =19200;
dcb.ByteSize =8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT ;
dcb.fBinary = TRUE ;
dcb.fParity = FALSE;
SetCommState(hCom, &dcb ) ; //串口参数配置
*/
bReturn = SetCommMask(hComm,EV_RXCHAR);
bReturn = SetupComm(hComm,4096,4096);
bReturn = PurgeComm(hComm,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
COMMTIMEOUTS cto;
cto.ReadIntervalTimeout=MAXDWORD;
cto.ReadTotalTimeoutMultiplier=MAXDWORD;
cto.ReadTotalTimeoutConstant= TIMEOUTCONSTANT;
cto.WriteTotalTimeoutMultiplier=0;
cto.WriteTotalTimeoutConstant=TIMEOUTCONSTANT;
SetCommTimeouts(hComm,&cto);
osRead.Offset=0;
osRead.OffsetHigh=0;
osWrite.Offset=0;
osWrite.OffsetHigh=0;
osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
return 0;
}
//根据命令码,操作参数,生成指令
//nCode:命令码
//nData:操作参数
//byteInstruction:4个字节组成的指令
void CmdFormInstruction(byte nCode, byte nData, byte byteInstruction[])
{
byte nSerialNumber = 0;
byteInstruction[0] = 0 | (nSerialNumber<<2) | (nCode&0x3);
byteInstruction[1] = 0x40 | ((nCode>>2)&0x3f);
byteInstruction[2] = 0x80 | ((nData>>2)&0x3f);
byteInstruction[3] = 0xc0 | ((nData&0x3)<<4);
return;
}
//从返回的数据byteResult中,提取出code和value值,在nCodeReturn和nReturnValue中返回
void ExtractResult(byte byteResult[], byte &nCodeReturn,byte* nReturnValue)
{
nCodeReturn = ( ( byteResult[1]&0x3f)<<2 ) | ( byteResult[0]&0x3 );
(*nReturnValue) = ( ( byteResult[2]&0x3f)<<2 ) | ( byteResult[3]&0x30 );
}
void ResetToInit()
{
CSutView* pView = ((CSutView*)((CMainFrame*)::AfxGetMainWnd())->GetActiveView());
CDlgMain* pDlgMain = &( pView->m_DlgMain);
CDlgPrescribeTherapy* pDlgPrescribeTherapy = &(pDlgMain->m_DlgPrescribeTherapy);
CDlgPassage1* pDlgPassage1 = &(pDlgMain->m_DlgPassage1);
CDlgPassage2* pDlgPassage2 = &(pDlgMain->m_DlgPassage2);
CDlgTwoPassage* pDlgTwoPassage = &(pDlgMain->m_DlgTwoPassage);
pDlgPassage1->Reset();
pDlgPassage2->Reset();
}
//发送给串口指令后,从串口返回的字符序列判断指令的发送是否成功
//现在只是简单的判断,如果返回4个字节的内容,则发送成功,否则失败
enum BYTE_STREAM_RESULT Send2SerialSucceed(int n, byte byteResult[], byte nCode, byte nPara)
{
byte nCodeReturn;
if(n==4)
{
ExtractResult(byteResult,nCodeReturn, &nReturnValue);
if( nCodeReturn!= nCode)//返回的Code值与原值是否相同,不同,则传输出错
return ERROR_CMD_CODE;
else
return SEND_SUCCESS;
}
else
return ERROR_CMD_CODE;
}
//现在用0代表成功,-1代表失败
//输入为:指令代码code和指令参数para
//向串口写该指令,判断是否发送成功
enum SEND_INSTRUCTION_RESULT SendToSerialPort(byte nCode, byte nPara)
{
#ifdef TEST
return SEND_INSTRUCTION_SUCCESS;
#endif
int nResult = -1;
byte byteInstruction[4];
CmdFormInstruction(nCode, nPara,byteInstruction);
int nCount = 0;
while(nCount < 3)
{ //串口操作
WriteBlock(byteInstruction,4);
//读串口返回的数据
Sleep(50);
int m,n;
m = InquiryBlock();
n = ReadBlock(1024);
TRACE("Inq: %d bytes, get %d byte\n", m, n);
//成功
if(Send2SerialSucceed(n, readBuffer, nCode, nPara) == SEND_SUCCESS)//成功
break;
else
{
nCount++;
continue;
}
}
if( 3 == nCount)
{
//#ifndef SUT_TEST
//// ResetToInit();
//// AfxMessageBox("串口没有响应,通信错误!!!");
//#endif
return SEND_INSTRUCTION_FAILURE;
// return SEND_INSTRUCTION_SUCCESS;
}
else
return SEND_INSTRUCTION_SUCCESS;
}
//输入为:4个字节的byteInstruction数组
//向串口写该指令,判断是否发送成功
enum SEND_INSTRUCTION_RESULT SendByteStreamToSerialPort(byte byteInstruction[])
{
#ifdef TEST
return SEND_INSTRUCTION_SUCCESS;
#endif
int nCount = 0;
while(nCount < 3)
{ //串口操作
WriteBlock(byteInstruction,4);
//读串口返回的数据
Sleep(50);
int m,n;
m = InquiryBlock();
n = ReadBlock(1024);
TRACE("Inq: %d bytes, get %d byte\n", m, n);
//成功
byte nCode, nPara;
nCode = ( ( byteInstruction[1]&0x3f)<<2 ) | ( byteInstruction[0]&0x3 );
nPara = ( ( byteInstruction[2]&0x3f)<<2 ) | ( byteInstruction[3]&0x30 );
if(Send2SerialSucceed(n,readBuffer,nCode, nPara) == SEND_SUCCESS)//成功
break;
else
{
nCount++;
continue;
}
}
if( 3 == nCount)
{
//#ifndef SUT_TEST
// ResetToInit();
// AfxMessageBox("串口没有响应,通信错误!!!");
//#endif
return SEND_INSTRUCTION_FAILURE;
// return SEND_INSTRUCTION_SUCCESS;
}
else
return SEND_INSTRUCTION_SUCCESS;
}
#include "stdafx.h"
#include "SerialComm.h"
#include "sut.h"
#include "MainFrm.h"
#include "SutView.h"
#include "DlgPassage1.h"
#include "DlgPassage2.h"
#include "DlgTwoPassage.h"
#include "DlgPrescribeTherapy.h"
#include "DlgMain.h"
HANDLE hComm;
OVERLAPPED osRead, osWrite;
BYTE readBuffer[1024];
BYTE nReturnValue;
//读串口
DWORD ReadBlock(DWORD dwMaxLength)
{
DWORD dwBytesRead,dwError,dwErrorFlags;
BOOL fReadStat;
COMSTAT ComStat;
dwBytesRead =0 ;
ResetEvent(osRead.hEvent);
fReadStat=ReadFile(hComm, readBuffer, dwMaxLength, &dwBytesRead, &osRead);
if(!fReadStat)
{
if (GetLastError()==ERROR_IO_PENDING)
{
while(!GetOverlappedResult(hComm,&osRead,&dwBytesRead,TRUE))
{
dwError=GetLastError();
if(dwError == ERROR_IO_INCOMPLETE) continue;
}
}
else
{
dwBytesRead = 0;
ClearCommError(hComm,&dwErrorFlags,&ComStat);
}
};
return dwBytesRead;
};
//写串口
BOOL WriteBlock(LPVOID lpByte,DWORD dwBytesToWrite)
{
BOOL fWriteStat;
DWORD dwBytesWritten;
DWORD dwErrorFlags;
DWORD dwError;
COMSTAT ComStat;
ResetEvent(osWrite.hEvent);
fWriteStat=WriteFile(hComm,lpByte,dwBytesToWrite,
&dwBytesWritten,&osWrite);
if (!fWriteStat)
{
if(GetLastError()==ERROR_IO_PENDING)
{
while(!GetOverlappedResult(hComm, &osWrite,&dwBytesWritten,TRUE))
{
dwError=GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
continue;
else
{
ClearCommError(hComm,&dwErrorFlags,&ComStat);
break;
}
}
}
else
{
ClearCommError(hComm,&dwErrorFlags,&ComStat);
return ( FALSE );
}
}
return ( TRUE ) ;
}
DWORD InquiryBlock()
{
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError(hComm,&dwErrorFlags,&ComStat);
return ComStat.cbInQue;
}
int InitSerialPort()
{
hComm = CreateFile("COM1",
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL);
if(hComm == NULL) return -1;
DCB dcb;
CString strDCB;
BOOL bReturn;
bReturn = GetCommState(hComm,&dcb);
strDCB.Format("19200,n,8,1");
bReturn = BuildCommDCB(strDCB,&dcb);
bReturn = SetCommState(hComm,&dcb);
// bReturn = GetCommState(hComm,&dcb);
/* DCB dcb ; // 定义数据控制块结构
GetCommState(hCom, &dcb ) ; //读串口原来的参数设置
dcb.BaudRate =19200;
dcb.ByteSize =8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT ;
dcb.fBinary = TRUE ;
dcb.fParity = FALSE;
SetCommState(hCom, &dcb ) ; //串口参数配置
*/
bReturn = SetCommMask(hComm,EV_RXCHAR);
bReturn = SetupComm(hComm,4096,4096);
bReturn = PurgeComm(hComm,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
COMMTIMEOUTS cto;
cto.ReadIntervalTimeout=MAXDWORD;
cto.ReadTotalTimeoutMultiplier=MAXDWORD;
cto.ReadTotalTimeoutConstant= TIMEOUTCONSTANT;
cto.WriteTotalTimeoutMultiplier=0;
cto.WriteTotalTimeoutConstant=TIMEOUTCONSTANT;
SetCommTimeouts(hComm,&cto);
osRead.Offset=0;
osRead.OffsetHigh=0;
osWrite.Offset=0;
osWrite.OffsetHigh=0;
osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
return 0;
}
//根据命令码,操作参数,生成指令
//nCode:命令码
//nData:操作参数
//byteInstruction:4个字节组成的指令
void CmdFormInstruction(byte nCode, byte nData, byte byteInstruction[])
{
byte nSerialNumber = 0;
byteInstruction[0] = 0 | (nSerialNumber<<2) | (nCode&0x3);
byteInstruction[1] = 0x40 | ((nCode>>2)&0x3f);
byteInstruction[2] = 0x80 | ((nData>>2)&0x3f);
byteInstruction[3] = 0xc0 | ((nData&0x3)<<4);
return;
}
//从返回的数据byteResult中,提取出code和value值,在nCodeReturn和nReturnValue中返回
void ExtractResult(byte byteResult[], byte &nCodeReturn,byte* nReturnValue)
{
nCodeReturn = ( ( byteResult[1]&0x3f)<<2 ) | ( byteResult[0]&0x3 );
(*nReturnValue) = ( ( byteResult[2]&0x3f)<<2 ) | ( byteResult[3]&0x30 );
}
void ResetToInit()
{
CSutView* pView = ((CSutView*)((CMainFrame*)::AfxGetMainWnd())->GetActiveView());
CDlgMain* pDlgMain = &( pView->m_DlgMain);
CDlgPrescribeTherapy* pDlgPrescribeTherapy = &(pDlgMain->m_DlgPrescribeTherapy);
CDlgPassage1* pDlgPassage1 = &(pDlgMain->m_DlgPassage1);
CDlgPassage2* pDlgPassage2 = &(pDlgMain->m_DlgPassage2);
CDlgTwoPassage* pDlgTwoPassage = &(pDlgMain->m_DlgTwoPassage);
pDlgPassage1->Reset();
pDlgPassage2->Reset();
}
//发送给串口指令后,从串口返回的字符序列判断指令的发送是否成功
//现在只是简单的判断,如果返回4个字节的内容,则发送成功,否则失败
enum BYTE_STREAM_RESULT Send2SerialSucceed(int n, byte byteResult[], byte nCode, byte nPara)
{
byte nCodeReturn;
if(n==4)
{
ExtractResult(byteResult,nCodeReturn, &nReturnValue);
if( nCodeReturn!= nCode)//返回的Code值与原值是否相同,不同,则传输出错
return ERROR_CMD_CODE;
else
return SEND_SUCCESS;
}
else
return ERROR_CMD_CODE;
}
//现在用0代表成功,-1代表失败
//输入为:指令代码code和指令参数para
//向串口写该指令,判断是否发送成功
enum SEND_INSTRUCTION_RESULT SendToSerialPort(byte nCode, byte nPara)
{
#ifdef TEST
return SEND_INSTRUCTION_SUCCESS;
#endif
int nResult = -1;
byte byteInstruction[4];
CmdFormInstruction(nCode, nPara,byteInstruction);
int nCount = 0;
while(nCount < 3)
{ //串口操作
WriteBlock(byteInstruction,4);
//读串口返回的数据
Sleep(50);
int m,n;
m = InquiryBlock();
n = ReadBlock(1024);
TRACE("Inq: %d bytes, get %d byte\n", m, n);
//成功
if(Send2SerialSucceed(n, readBuffer, nCode, nPara) == SEND_SUCCESS)//成功
break;
else
{
nCount++;
continue;
}
}
if( 3 == nCount)
{
//#ifndef SUT_TEST
//// ResetToInit();
//// AfxMessageBox("串口没有响应,通信错误!!!");
//#endif
return SEND_INSTRUCTION_FAILURE;
// return SEND_INSTRUCTION_SUCCESS;
}
else
return SEND_INSTRUCTION_SUCCESS;
}
//输入为:4个字节的byteInstruction数组
//向串口写该指令,判断是否发送成功
enum SEND_INSTRUCTION_RESULT SendByteStreamToSerialPort(byte byteInstruction[])
{
#ifdef TEST
return SEND_INSTRUCTION_SUCCESS;
#endif
int nCount = 0;
while(nCount < 3)
{ //串口操作
WriteBlock(byteInstruction,4);
//读串口返回的数据
Sleep(50);
int m,n;
m = InquiryBlock();
n = ReadBlock(1024);
TRACE("Inq: %d bytes, get %d byte\n", m, n);
//成功
byte nCode, nPara;
nCode = ( ( byteInstruction[1]&0x3f)<<2 ) | ( byteInstruction[0]&0x3 );
nPara = ( ( byteInstruction[2]&0x3f)<<2 ) | ( byteInstruction[3]&0x30 );
if(Send2SerialSucceed(n,readBuffer,nCode, nPara) == SEND_SUCCESS)//成功
break;
else
{
nCount++;
continue;
}
}
if( 3 == nCount)
{
//#ifndef SUT_TEST
// ResetToInit();
// AfxMessageBox("串口没有响应,通信错误!!!");
//#endif
return SEND_INSTRUCTION_FAILURE;
// return SEND_INSTRUCTION_SUCCESS;
}
else
return SEND_INSTRUCTION_SUCCESS;
}