先把代码贴上。说明在后面!
void CFanDlg::OnButtonSendCommond()
{
CString string="AA0104070000B6";
//senddata通过串口发送命令到下位机
CString temp;
//写串口命令的每一位
temp=string.Mid(0,1);
m_com.buffer[0]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(2,1);
m_com.buffer[1]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(4,1);
m_com.buffer[2]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(6,1);
m_com.buffer[3]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(8,1);
m_com.buffer[4]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(10,1);
m_com.buffer[5]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(12,1);
m_com.buffer[6]=CString_Tran_Int(temp);
//将命令通过串口发送出去
m_com.ComWrite(m_com.buffer,7);
}LRESULT CFanDlg::OnReceive(WPARAM wParam, LPARAM lParam)
{
char sz[255];
CString outputstring="";
CString str;
CString s;
int len = m_com.ReadString(sz,255);
for(int i=0;i<len;i++)
{
s.Format("%02x",(BYTE)sz[i]);
str += s + " ";
}
outputstring=str;
str+="\r\n";
//将结果数据显示在文本框
m_edit.SetWindowText(str);
return 0;
}
DWORD CSerial::ThreadProc()//串口线程,异步方式
{
if(!::SetCommMask(m_hCom, m_dwMaskEvent))
{
::MessageBox(m_hNotifyWnd, " SetCommMask failed", "", 0);
return -1;
}
DWORD dwError, dwMask, dwTrans;
COMSTAT Stat;
while(!m_bExit)
{
dwMask = 0;
if(!::WaitCommEvent(m_hCom, &dwMask, &m_WaitOl))
{
if(::GetLastError() == ERROR_IO_PENDING)
{
::GetOverlappedResult(m_hCom, &m_WaitOl, &dwTrans, TRUE);
}
else
continue;
}
switch(dwMask)
{
case EV_RXCHAR:
{
::ClearCommError(m_hCom, &dwError, &Stat);
if(Stat.cbInQue >= m_dwNotifyNum)
{
if(::IsWindow(m_hNotifyWnd))
::PostMessage(m_hNotifyWnd, WM_COM_RECEIVE, 0, 0);
}
}
break;
case EV_TXEMPTY:
OnTXEmpty();
break;
default:
continue;
}
}
return 0;
}
程序目标:在窗口中向串口发命令,串口处理命令后,向窗口返回结果,结果数据显示在窗口上
实现方法:串口单独一个线程,循环监听串口事件,见ThreadProc函数,采用异步通信。窗口函数OnButtonSendCommond向串口发送命令,窗口函数OnReceive响应串口发回的消息(自定义消息WM_COM_RECEIVE)从串口读结果数据,显示在窗口上.
出现问题:向串口写一条命令,串口线程函数执行了两次case EV_RXCHAR:,窗口函数onreceive也执行了两次。本来第一次数据是正确的,可第二次又读为空又把正确数据覆盖掉了。还有设断点调试的时候一切正常,case EV_RXCHAR:和窗口函数onreceive都执行一次。实在没辙了,请高手帮我解脱了吧,睡不着觉呀。我也知道这是两个线程协调问题,可是就是不知道错在什么地方,请谅解一个新手的无知。
void CFanDlg::OnButtonSendCommond()
{
CString string="AA0104070000B6";
//senddata通过串口发送命令到下位机
CString temp;
//写串口命令的每一位
temp=string.Mid(0,1);
m_com.buffer[0]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(2,1);
m_com.buffer[1]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(4,1);
m_com.buffer[2]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(6,1);
m_com.buffer[3]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(8,1);
m_com.buffer[4]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(10,1);
m_com.buffer[5]=CString_Tran_Int(temp);
temp="";
temp=string.Mid(12,1);
m_com.buffer[6]=CString_Tran_Int(temp);
//将命令通过串口发送出去
m_com.ComWrite(m_com.buffer,7);
}LRESULT CFanDlg::OnReceive(WPARAM wParam, LPARAM lParam)
{
char sz[255];
CString outputstring="";
CString str;
CString s;
int len = m_com.ReadString(sz,255);
for(int i=0;i<len;i++)
{
s.Format("%02x",(BYTE)sz[i]);
str += s + " ";
}
outputstring=str;
str+="\r\n";
//将结果数据显示在文本框
m_edit.SetWindowText(str);
return 0;
}
DWORD CSerial::ThreadProc()//串口线程,异步方式
{
if(!::SetCommMask(m_hCom, m_dwMaskEvent))
{
::MessageBox(m_hNotifyWnd, " SetCommMask failed", "", 0);
return -1;
}
DWORD dwError, dwMask, dwTrans;
COMSTAT Stat;
while(!m_bExit)
{
dwMask = 0;
if(!::WaitCommEvent(m_hCom, &dwMask, &m_WaitOl))
{
if(::GetLastError() == ERROR_IO_PENDING)
{
::GetOverlappedResult(m_hCom, &m_WaitOl, &dwTrans, TRUE);
}
else
continue;
}
switch(dwMask)
{
case EV_RXCHAR:
{
::ClearCommError(m_hCom, &dwError, &Stat);
if(Stat.cbInQue >= m_dwNotifyNum)
{
if(::IsWindow(m_hNotifyWnd))
::PostMessage(m_hNotifyWnd, WM_COM_RECEIVE, 0, 0);
}
}
break;
case EV_TXEMPTY:
OnTXEmpty();
break;
default:
continue;
}
}
return 0;
}
程序目标:在窗口中向串口发命令,串口处理命令后,向窗口返回结果,结果数据显示在窗口上
实现方法:串口单独一个线程,循环监听串口事件,见ThreadProc函数,采用异步通信。窗口函数OnButtonSendCommond向串口发送命令,窗口函数OnReceive响应串口发回的消息(自定义消息WM_COM_RECEIVE)从串口读结果数据,显示在窗口上.
出现问题:向串口写一条命令,串口线程函数执行了两次case EV_RXCHAR:,窗口函数onreceive也执行了两次。本来第一次数据是正确的,可第二次又读为空又把正确数据覆盖掉了。还有设断点调试的时候一切正常,case EV_RXCHAR:和窗口函数onreceive都执行一次。实在没辙了,请高手帮我解脱了吧,睡不着觉呀。我也知道这是两个线程协调问题,可是就是不知道错在什么地方,请谅解一个新手的无知。
我不知道你发送的数据是你的字符串格式呢,还是需要转换为十六进制,至于你的问题,线程函数应该是全局函数,这个你肯定是设置正确了的,其他好像我没发现什么问题,所以暂时不了然,MARK下。
就是说一旦是进入default了,就一直执行case语句了,还是另外有解释呢?
可以在消息发送过去后,Sleep(100)
的参数试试。我上次也有这样问题。后来把TRUE改成FALSE就行了,也不知道为什么
然后,GetOverlappedResult没有检查返回值啊