解决方案 »
- 存储过程的调用
- 请教大家,LRC校验是怎么算的?
- 谁能帮个忙,有这本书《Introduction to Visual C++ 6.0 Standard Edition》中文版吗?
- 这个问题比较恶心,请大家帮忙
- 一个简单的MFC 为题 我是新手我不会
- 关于CPropertySheet类的编程
- 请高手谈谈防止程序内存泄漏的方法和检测方法,急啊~~~~~~~`
- 有两家公司:1东软国际商务软件公司 2:大连华信 从前途考虑,你会选择哪家?
- 谁知道哪里能下载《visual c++ 技术内幕》中文版???
- Change the background of control on dialog and view
- 如何向一个不创建窗口的进程发送消息?
- NoteExPress求教
别人的库用起来爽,出问题了。
你就知道惨了。
// .h
typedef void (WINAPI *ZY_RECV_COMDATA)(void* pParam, BYTE *data, int dataLen);
class CMyCom
{
public:
CMyCom(void);
~CMyCom(void);
public:
BOOL Open(int nComID, void* pMainWnd, ZY_RECV_COMDATA pFun, DWORD nRate = 9600);
void Close();
void Send(BYTE *pBuf, int nLen);
BOOL IsOpen();
HANDLE m_hCom;
ZY_RECV_COMDATA m_CallBackFun;
void* m_pMainWnd;
};//.cpp
CMyCom::CMyCom()
{
m_hCom = NULL;
m_pMainWnd = NULL;
}CMyCom::~CMyCom()
{
}DWORD WINAPI ThreadReciveData(LPVOID lpParameter)
{
CMyCom* pMyCom = (CMyCom*)lpParameter;
HANDLE hCom = pMyCom->m_hCom; BYTE data[512];
DWORD wCount;
while(1)
{
if(!ReadFile(hCom, data, 512, &wCount, NULL))
{
pMyCom->m_hCom = NULL;
break;
} if(wCount > 0)
{
pMyCom->m_CallBackFun(pMyCom->m_pMainWnd, data, wCount);
}
Sleep(1);
}
return 1;
}BOOL CMyCom::Open(int nComID, void* pMainWnd, ZY_RECV_COMDATA pFun, DWORD nRate)
{
if(m_hCom) return FALSE; WCHAR szCOMID[32];
wsprintfW(szCOMID, L"COM%d", nComID); m_hCom = CreateFileW(
szCOMID, // 串口号
GENERIC_READ | GENERIC_WRITE, // 允许读写
0, // 因为串行口不支持任何共享模式, 必须以独占方式打开
NULL, // 定义安全属性,一般不用,可设为NULL
OPEN_EXISTING, // 定义文件创建方式, 对串口必须设为OPEN_EXISTING,表示打开已经存在的文件;
NULL/*FILE_FLAG_OVERLAPPED*/, // 为该文件指定定义文件属性和标志,这个程序中设为FILE_FLAG_OVERLAPPED,表示异步通信方式异步I/O
NULL); // 指向一个模板文件的句柄,串口无模板可言,设为NULL if (m_hCom == INVALID_HANDLE_VALUE)
{
Close();
return FALSE;
} DCB dcb;
if(!GetCommState(m_hCom, &dcb))
{
AfxMessageBox(L"获得串口信息失败!");
return FALSE;
} // 9600,N,8,1
dcb.BaudRate = nRate; // 波特率9600
dcb.fParity = 0; // 0=无校验 1=开启校验
dcb.Parity = NOPARITY; // 校验方式,值0~4分别对应无校验、奇校验、偶校验、校验置位、校验清零
dcb.ByteSize = 8; // 一个字节的数据位个数
dcb.StopBits = ONESTOPBIT; // 0=1位 1=1.5位 2=2位
dcb.fBinary = 1; // 以二进制方式来处理串口 if(!SetCommState(m_hCom, &dcb))
{
AfxMessageBox(L"设置串口信息失败!");
return FALSE;
} if(!SetupComm(m_hCom, 1024, 1024)) //输入输出缓冲区
{
AfxMessageBox(L"设置串口缓冲区长度失败");
return FALSE;
} COMMTIMEOUTS CommTimeouts; CommTimeouts.ReadIntervalTimeout = MAXDWORD; /* Maximum time between read chars. */
CommTimeouts.ReadTotalTimeoutMultiplier = 0; // 以毫秒为单位指定一个乘数,该乘数用来计算读操作的总限时时间。每个读操作的总限时时间等于读操作所需的字节数与该值的乘积。
CommTimeouts.ReadTotalTimeoutConstant = 0; // 以毫秒为单位指定一个常数,用于计算读操作的总限时时间。每个操作的总限时时间等于
CommTimeouts.WriteTotalTimeoutMultiplier = 50; // 同上
CommTimeouts.WriteTotalTimeoutConstant = 2000; // 同上
if(!SetCommTimeouts(m_hCom, &CommTimeouts))
{
AfxMessageBox(L"串口超时设置失败~");
return FALSE;
} PurgeComm(m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); m_pMainWnd = pMainWnd;
m_CallBackFun = pFun; CloseHandle(CreateThread(NULL, 0, ThreadReciveData, LPVOID(this), 0, NULL));
return TRUE;
}void CMyCom::Close()
{
CloseHandle(m_hCom);
m_hCom = NULL;
}void CMyCom::Send(BYTE *pBuf, int nLen)
{
if(m_hCom)
{
DWORD wCount = 0;
WriteFile(m_hCom, pBuf, nLen, &wCount, NULL);
}
}BOOL CMyCom::IsOpen()
{
return m_hCom != NULL;
}// 使用
// 窗体函数
void CMianDlg::OnCommXX(BYTE *data, int dataLen)
{
}
//回调函数
void WINAPI OnComRecvData(void* pParam, BYTE *data, int dataLen)
{
CMianDlg *pDlg = (CMianDlg*)pParam;
pDlg->OnCommMscommXX(data, dataLen);
}
m_Com.Open(1, this/*接收窗体指针*/, OnComRecvData, 9600);
我以前写的,不一定规范,你可以试下
另外usb转串的时候可能会有意外发生,测试的时候最好不要用usb转串,程序完成后再使用usb转串,分别测一次,有利于定位错误
PS:MOXA公司开发的串口库PCOMM还是非常好用的,使用非常方便,推荐一下哦。