利用mscomm控件进行串口调试时,发现数据无法立即发送

常州大龙虾 2018-03-15 03:58:56
环境是vs2013,利用mscomm控件进行的串口连接。具体问题是在一个按钮函数内,我需要发送并接收四次指令。将发送接收设为一个单元,我必须在每个单元之间加入一个afxmessage来中断才能实现四次指令。如果我在单元间或者单元内放入延迟函数都无法获得响应,不加弹框的话四次指令都不执行。怎样才能避免弹框并实现指令的发送与接收呢?
...全文
547 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2018-03-20
  • 打赏
  • 举报
回复
1 你可以 通过 while ((m_MyMSComm.GetOutBufferCount() > 0) && !m_bCancel) 来 检查 发送 是不是 结束。 2 不要用 sleep void CUseMsComm32OCXDlg::DoEvents() { MSG msg; // Process existing messages in the application's message queue. // When the queue is empty, do clean up and return. while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {// has msg if (!AfxGetThread()->PumpMessage()) return; } } 3 OnComm 处理 太简单 要 包括错误处理 case ComEventRxOver: // Receive buffer overflow. strError="R buffer Overflow"; break; case ComEventRxParity: // Parity Error. strError="Parity Error"; break; case ComEventTxFull: // Transmit buffer full. strError="T buf Full"; break;
常州大龙虾 2018-03-20
  • 打赏
  • 举报
回复
那是不是因为afxmessagebox 弹框起到了一个中断的作用,导致发送与接收同步了呢?那还有没有什么中断函数可以避免弹框?或者是怎么处理这种异步情况?
schlafenhamster 2018-03-20
  • 打赏
  • 举报
回复
发送 是 发送 ,接受 是 接受, 2者 要 分开 。 因为 RS232 串口 是 全工(发送,接受) 异步 的。
常州大龙虾 2018-03-20
  • 打赏
  • 举报
回复
发送按钮内的代码:
void CMMC200_MotionControlSoftwareDlg::OnBnClickedButton4()
{
	
	m_strTXData = _T("1POS?");
	CString str=_T("");
	int len = m_strTXData.GetLength();
	for (int k = 0; k<len; k++)
	{
		CString strtemp;
		strtemp.Format(_T("%02X "), m_strTXData[k]);
		str.Append(strtemp);
	}
	str += _T("0A 0D");
	m_strTXData = str;
	//CByteArray senddata;
	//Str2Hex(m_strTXData, senddata);
	//m_ctrlComm.put_Output(COleVariant(senddata));//发送数据

	::SendMessage(m_hWnd, COM_SENDMSG, 0, 0);
	Sleep(500);
	//AfxMessageBox(_T(""));
	AfxMessageBox(m_strRXData);
	UpdateData(false);
	// TODO:  在此添加控件通知处理程序代码
}
串口控件函数:
void CMMC200_MotionControlSoftwareDlg::OnComm()
{
	// TODO:  在此处添加消息处理程序代码
	VARIANT variant_inp;
	COleSafeArray safearray_inp;
	LONG len, k;
	BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
	CString strtemp;
	if (m_ctrlComm.get_CommEvent() == 2) //事件值为2表示接收缓冲区内有字符
	{              ////////以下你可以根据自己的通信协议加入处理代码
		variant_inp = m_ctrlComm.get_Input(); //读缓冲区
		safearray_inp = variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
		len = safearray_inp.GetOneDimSize(); //得到有效数据长度
		for (k = 0; k<len; k++)
			safearray_inp.GetElement(&k, rxdata + k);//转换为BYTE型数组
		for (k = 0; k<len; k++) //将数组转换为Cstring型变量
		{
			BYTE bt = *(char*)(rxdata + k); //字符型

			strtemp.Format(_T("%c"), bt);//将接收到的BYTE型数据转换为对应的十六进制
			m_strRXData.Append(strtemp);
			//m_strRXData = Hex2Ascii(m_strRXData);
		}
	}
	UpdateData(FALSE); //更新编辑框内容
}
N阶魔方 2018-03-20
  • 打赏
  • 举报
回复
接收属于消息映射函数,是自动调用的函数,你可以加入相关处理,理论上来讲你不能主动去调用。因为你不知道什么时候接收数据准备完成。你可以在接收函数中放入一些全局变量来标记处理情况。或者在接收函数末尾加入发送数据处理,注意,要加入防止死循环的处理。
常州大龙虾 2018-03-19
  • 打赏
  • 举报
回复
而如果我在oncomm函数与显示返回的字符串之间加入afxmessagebox(_T("")),反馈的值就接上了。我就是不知道出了啥问题
常州大龙虾 2018-03-19
  • 打赏
  • 举报
回复
可能涉及到消息机制,我代码不方便拿出来,我举个简单的例子,oncomm函数作用是调用串口控件函数让其发送指令。在一个按钮函数内,我调用一个oncomm函数并以afxmessageBox的方式显示通过串口传递回的字符串,实验结果是第一次按按钮字符串是默认空的值,第二次按显示的是第一次发送指令接收到的值。简而言之,在一个按钮函数内,本应执行发送指令在让接收到的值显示出来,实际情况是执行是执行了,但是由于消息队列的原因反馈没有接上。
走好每一步 2018-03-19
  • 打赏
  • 举报
回复
估计楼主没理解异步编程
赵4老师 2018-03-16
  • 打赏
  • 举报
回复
参考《编译原理》中的词法分析和有限状态自动机。
schlafenhamster 2018-03-15
  • 打赏
  • 举报
回复
要看你的代码
常州大龙虾 2018-03-15
  • 打赏
  • 举报
回复
更正一下,是在一个单元内也就是发送与接收间加入afxmessage来中断

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧