📄 chuankoudlg.cpp
字号:
}
BOOL CChuankouDlg::OpenPort2(CWnd* pPortOwner,
UINT portNo , /*串口号*/
UINT baud , /*波特率*/
UINT parity , /*奇偶校验*/
UINT databits , /*数据位*/
UINT stopbits /*停止位*/
)
{
DCB commParam;
TCHAR szPort[15];
// 已经打开的话,直接返回
if (m_hComm2 != INVALID_HANDLE_VALUE)
{
return TRUE;
}
ASSERT(pPortOwner != NULL);
ASSERT(portNo > 0 && portNo < 5);
//设置串口名
wsprintf(szPort, L"COM%d:", portNo);
//打开串口
m_hComm2 = CreateFile(
szPort,
GENERIC_READ | GENERIC_WRITE, //允许读和写
0, //独占方式(共享模式)
NULL,
OPEN_EXISTING, //打开而不是创建(创建方式)
0,
NULL
);
if (m_hComm2 == INVALID_HANDLE_VALUE)
{
// 无效句柄,返回。
TRACE(_T("CreateFile 返回无效句柄"));
return FALSE;
}
// 得到打开串口的当前属性参数,修改后再重新设置串口。
// 设置串口的超时特性为立即返回。
if (!GetCommState(m_hComm2,&commParam))
{
return FALSE;
}
commParam.BaudRate = baud; // 设置波特率
commParam.fBinary = TRUE; // 设置二进制模式,此处必须设置TRUE
commParam.fParity = TRUE; // 支持奇偶校验
commParam.ByteSize = databits; // 数据位,范围:4-8
commParam.Parity = NOPARITY; // 校验模式
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_hComm2, &commParam))
{
TRACE(_T("SetCommState error"));
return FALSE;
}
//设置串口读写时间
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts (m_hComm2, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 10;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
if(!SetCommTimeouts( m_hComm2, &CommTimeOuts ))
{
TRACE( _T("SetCommTimeouts 返回错误") );
return FALSE;
}
m_pPortOwner = pPortOwner;
//指定端口监测的事件集
SetCommMask (m_hComm2, EV_RXCHAR);
//分配设备缓冲区
SetupComm(m_hComm2,1024,1024);
//初始化缓冲区中的信息
PurgeComm(m_hComm2,PURGE_TXCLEAR|PURGE_RXCLEAR);
m_hReadCloseEvent2 = CreateEvent(NULL,TRUE,FALSE,NULL);
// m_hWriteCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
//创建读串口线程
m_hReadThread2 = CreateThread(NULL,0,ReadThreadFunc2,this,0,&m_dwReadThreadID);
//创建写串口线程
// m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc,this,0,&m_dwWriteThreadID);
TRACE(_T("串口打开成功"));
return TRUE;
}
//串口读线程函数
DWORD CChuankouDlg::ReadThreadFunc1(LPVOID lparam)
{
CChuankouDlg *ceSeries = (CChuankouDlg*)lparam;
DWORD evtMask;
BYTE * readBuf = NULL;//读取的字节
DWORD actualReadLen=0;//实际读取的字节数
DWORD willReadLen;
DWORD dwReadErrors;
COMSTAT cmState;
// 清空缓冲,并检查串口是否打开。
ASSERT(ceSeries->m_hComm1 !=INVALID_HANDLE_VALUE);
// AfxMessageBox(_T("1"));
//清空串口
PurgeComm(ceSeries->m_hComm1, PURGE_RXCLEAR | PURGE_TXCLEAR );
SetCommMask (ceSeries->m_hComm1, EV_RXCHAR | EV_CTS | EV_DSR );
while (TRUE)
{
if (WaitCommEvent(ceSeries->m_hComm1,&evtMask,0))
{
SetCommMask (ceSeries->m_hComm1, EV_RXCHAR | EV_CTS | EV_DSR );
//表示串口收到字符
if (evtMask & EV_RXCHAR)
{
// AfxMessageBox(_T("3"));
ClearCommError(ceSeries->m_hComm1,&dwReadErrors,&cmState);
willReadLen = cmState.cbInQue ;
if (willReadLen <= 0)
{
continue;
}
readBuf = new BYTE[willReadLen];
ReadFile(ceSeries->m_hComm1, readBuf, willReadLen, &actualReadLen,0);
//如果读取的数据大于0,
if (actualReadLen>0)
{
// ceSeries->read(ceSeries->m_pPortOwner,readBuf,actualReadLen);
// AfxMessageBox(_T("ol"));
//触发读取回调函数
ceSeries->OnSeriesRead1(ceSeries->m_pPortOwner,readBuf,actualReadLen);
// AfxMessageBox(_T("ol"));
}
}
}
//如果收到读线程退出信号,则退出线程
if (WaitForSingleObject(ceSeries->m_hReadCloseEvent1,500) == WAIT_OBJECT_0)
{// AfxMessageBox(_T("exit"));
break;
}
}
return 0;
}
//串口读线程函数
DWORD CChuankouDlg::ReadThreadFunc2(LPVOID lparam)
{
CChuankouDlg *ceSeries = (CChuankouDlg*)lparam;
DWORD evtMask;
BYTE * readBuf = NULL;//读取的字节
DWORD actualReadLen=0;//实际读取的字节数
DWORD willReadLen;
DWORD dwReadErrors;
COMSTAT cmState;
// 清空缓冲,并检查串口是否打开。
ASSERT(ceSeries->m_hComm2 !=INVALID_HANDLE_VALUE);
// AfxMessageBox(_T("1"));
//清空串口
PurgeComm(ceSeries->m_hComm2, PURGE_RXCLEAR | PURGE_TXCLEAR );
SetCommMask (ceSeries->m_hComm2, EV_RXCHAR | EV_CTS | EV_DSR );
while (TRUE)
{
if (WaitCommEvent(ceSeries->m_hComm2,&evtMask,0))
{
SetCommMask (ceSeries->m_hComm2, EV_RXCHAR | EV_CTS | EV_DSR );
//表示串口收到字符
if (evtMask & EV_RXCHAR)
{
// AfxMessageBox(_T("3"));
ClearCommError(ceSeries->m_hComm2,&dwReadErrors,&cmState);
willReadLen = cmState.cbInQue ;
if (willReadLen <= 0)
{
continue;
}
readBuf = new BYTE[willReadLen];
ReadFile(ceSeries->m_hComm2, readBuf, willReadLen, &actualReadLen,0);
//如果读取的数据大于0,
if (actualReadLen>0)
{
// ceSeries->read(ceSeries->m_pPortOwner,readBuf,actualReadLen);
// AfxMessageBox(_T("ol"));
//触发读取回调函数
ceSeries->OnSeriesRead2(ceSeries->m_pPortOwner,readBuf,actualReadLen);
// AfxMessageBox(_T("ol"));
}
}
}
//如果收到读线程退出信号,则退出线程
if (WaitForSingleObject(ceSeries->m_hReadCloseEvent2,500) == WAIT_OBJECT_0)
{// AfxMessageBox(_T("exit"));
break;
}
}
return 0;
}
//关闭读线程
void CChuankouDlg::CloseReadThread1()
{
SetEvent(m_hReadCloseEvent1);
//设置所有事件无效无效
SetCommMask(m_hComm1, 0);
//清空所有将要读的数据
PurgeComm( m_hComm1, PURGE_RXCLEAR );
//等待10秒,如果读线程没有退出,则强制退出
if (WaitForSingleObject(m_hReadThread1,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hReadThread1,0);
}
m_hReadThread1 = NULL;
}
//关闭读线程
void CChuankouDlg::CloseReadThread2()
{
SetEvent(m_hReadCloseEvent2);
//设置所有事件无效无效
SetCommMask(m_hComm2, 0);
//清空所有将要读的数据
PurgeComm( m_hComm2, PURGE_RXCLEAR );
//等待10秒,如果读线程没有退出,则强制退出
if (WaitForSingleObject(m_hReadThread2,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hReadThread2,0);
}
m_hReadThread2 = NULL;
}
void CChuankouDlg::ClosePort1()
{
//表示串口还没有打开
if (m_hComm1 == INVALID_HANDLE_VALUE)
{
return ;
}
//关闭读线程
CloseReadThread1();
//关闭串口
if (!CloseHandle (m_hComm1))
{
m_hComm1 = INVALID_HANDLE_VALUE;
return ;
}
m_hComm1 = INVALID_HANDLE_VALUE;
// AfxMessageBox(_T("ClosePort"));
}
void CChuankouDlg::ClosePort2()
{
//表示串口还没有打开
if (m_hComm2 == INVALID_HANDLE_VALUE)
{
return ;
}
//关闭读线程
CloseReadThread2();
//关闭串口
if (!CloseHandle (m_hComm2))
{
m_hComm2 = INVALID_HANDLE_VALUE;
return ;
}
m_hComm2 = INVALID_HANDLE_VALUE;
// AfxMessageBox(_T("ClosePort"));
}
//私用方法,用于向串口写数据,被写线程调用
BOOL CChuankouDlg::WritePort(HANDLE hComm,const BYTE *buf,DWORD bufLen)
{
// AfxMessageBox( _T("WritePort") );
DWORD dwNumBytesWritten;
DWORD dwHaveNumWritten =0 ; //已经写入多少
ASSERT(hComm != INVALID_HANDLE_VALUE);
do
{
// AfxMessageBox( _T("gogo") );
if (WriteFile (hComm, //串口句柄
buf+dwHaveNumWritten, //被写数据缓冲区
bufLen- dwHaveNumWritten, //被写数据缓冲区大小
&dwNumBytesWritten, //函数执行成功后,返回实际向串口写的个数
NULL)) //此处必须设置NULL
{
dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;
//写入完成
if (dwHaveNumWritten == bufLen)
{
// AfxMessageBox( _T("yes ok") );
return TRUE;
}
// Sleep(10);
}
else
{
return FALSE;
}
}while (TRUE);
return TRUE;
}
void CChuankouDlg::OpenThind1(CWnd* pPortOwner)
{ m_pPortOwner = pPortOwner;
m_hReadCloseEvent1 = CreateEvent(NULL,TRUE,FALSE,NULL);
//创建读串口线程
m_hReadThread1 = CreateThread(NULL,0,ReadThreadFunc1,this,0,&m_dwReadThreadID);
}
void CChuankouDlg::OpenThind2(CWnd* pPortOwner)
{ m_pPortOwner = pPortOwner;
m_hReadCloseEvent2 = CreateEvent(NULL,TRUE,FALSE,NULL);
//创建读串口线程
m_hReadThread2 = CreateThread(NULL,0,ReadThreadFunc2,this,0,&m_dwReadThreadID);
}
void CChuankouDlg::OnCheck1()
{
UpdateData(true);
if(m_16)
{
m_dis=true;
}
else{
m_dis=false;
}
}
void CChuankouDlg::OnSetfocusEdit2()
{
SipShowIM(SIPF_ON);
}
void CChuankouDlg::OnKillfocusEdit2()
{
SipShowIM(SIPF_OFF);
}
void CChuankouDlg::OnSetfocusEdit5()
{
SipShowIM(SIPF_ON);
}
void CChuankouDlg::OnKillfocusEdit5()
{
SipShowIM(SIPF_OFF);
}
void CChuankouDlg::OnTimer(UINT nIDEvent)
{
//ShowWindow(false);
KillTimer(1);
CDialog::OnTimer(nIDEvent);
}
void CChuankouDlg::OnButton5()
{
((CEdit*)GetDlgItem(IDC_EDIT1))->SetWindowText(_T(""));
}
void CChuankouDlg::OnButton6()
{
((CEdit*)GetDlgItem(IDC_EDIT2))->SetWindowText(_T(""));
}
void CChuankouDlg::OnButtonSend2()
{
// TODO: Add your control notification handler code here
if(!m_Cortrol2)
{
AfxMessageBox(_T("串口没有打开!"));
return;
}
BYTE *pData;
UpdateData(true);
((CEdit*)GetDlgItem(IDC_EDIT5))->GetWindowText(m_strSend);
if(m_strSend==_T(""))
{
return;
}
if(m_16)
{
CByteArray hexdata;
int len=String2Hex(m_strSend,hexdata);
bufLen=len;
pData=new BYTE[len];
for(int k=0;k<len;k++)
{
pData[k]= hexdata[k];
}
}else{
bufLen = m_strSend.GetLength()*2;
pData = new BYTE(bufLen);
CopyMemory(pData,m_strSend.GetBuffer(m_strSend.GetLength()),bufLen);
}
con2+=bufLen;
if (!WritePort(m_hComm2,pData,bufLen))
{
AfxMessageBox(L"写串口失败\r\n\r请检查串口连接!");
ClosePort2();
return;
}
delete pData;
pData=NULL;
CString LEN;
LEN.Format(_T("%d"),con2);
((CEdit*)GetDlgItem(IDC_EDIT6))->SetWindowText(LEN);
//ReadPort();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -