c++学习 | MFC —— 串口通信(三)接收数据


上一节中我们完成了串口监听线程的创建和线程响应函数的创建,在线程响应函数中,有这样一条语句:

if(ComStat.cbInQue)  //如果有数据到达
		{
			pDlg->ProcessCOMMNotification(EV_RXCHAR,0);
		}

一、ProcessCOMMNotification消息处理函数

.h文件

BOOL ProcessCOMMNotification(UINT wParam, long lParam);	 //串口消息处理

.cpp文件

//当有数据到达串口时响应函数
BOOL CSerialComSoftwareDlg::ProcessCOMMNotification (UINT wParam,long lParam)
{
	CFile getdatafile;  //定义一个文件变量
	CFileException e;   //与文件相关异常变量
//	AfxMessageBox("begin read!");
	BOOL judgefile=m_writetofile.GetCheck();  //写入到文件选项是否选中
	//判断串口是否已关闭
	if(!m_bConnected)
		return FALSE;
	//判断收到的是否读缓冲消息
	if((EV_RXCHAR&wParam)!=EV_RXCHAR)
		return FALSE;
	//判断是否写入文件,并打开文件,将指针定在文件末尾
	if(judgefile)
	{
		getdatafile.Open(m_savefilename,CFile::modeCreate+CFile::modeNoTruncate+CFile::modeWrite,&e);
		getdatafile.SeekToEnd();
	}
	//将数据读入CString变量中
	CString StrTemp;
	BYTE abIn[MAXBLOCK];
	int len;
 
	len=ReadBlock(abIn,MAXBLOCK);   //读取缓存区中的数据存入abIn[]
//	AfxMessageBox("I have getten it!");
	if(!len)
	{
		AfxMessageBox(_T("读字符出错,请检查。"));
		return FALSE;
	}
	for(int i=0;i<len;i++)
	{
		BYTE bt=abIn[i];
		if(m_ctrlHexDisplay.GetCheck())  //十六进制显示
			StrTemp.Format(_T("%02x "),bt);  
		else
		    StrTemp.Format(_T("%c"),bt);  //字符串显示
 
		m_strRXData+=StrTemp;
		if(judgefile)
			{		
				getdatafile.Write(StrTemp,1);  //写入文件		
			}
	}
	m_rxlen+=len;
	//将字符显示在指定位置
	if(judgefile)
		getdatafile.Close();  //关闭文件
	m_EditRXData.SetWindowText(m_strRXData);
 
	DispStatus();  //状态栏显示
 
	return TRUE;
}

二、读取串口缓冲区中数据函数ReadBlock()

//读缓冲区
int CSerialComSoftwareDlg::ReadBlock(BYTE *abIn, int MaxLength)
{
	BOOL JudgeRead;
	COMSTAT ComStat;
	DWORD dwErrorFlags,dwLength;
	ClearCommError(m_hCom,&dwErrorFlags,&ComStat);  //清除通信的硬件错误并获取串口信息
	if(dwErrorFlags>0)
	{
		AfxMessageBox(_T("读串口错,请检查参数设置。"));
		PurgeComm(m_hCom,PURGE_RXABORT|PURGE_RXCLEAR);
		return 0;
	}
	dwLength=((DWORD)MaxLength<ComStat.cbInQue?MaxLength:ComStat.cbInQue);  //读取指定长度字符或者所有缓冲区数据
	memset(abIn,0,MaxLength);
	//如果有字符即读入
	if(dwLength)
	{
		JudgeRead=ReadFile(m_hCom,abIn,dwLength,&dwLength,&m_osRead);//读出字符至abIn处
		if(!JudgeRead)
		{
			//如果重叠操作未完成,等待直到操作完成
			if(GetLastError()==ERROR_IO_PENDING)
			{
//				WaitForSingleObject(m_osRead.hEvent,INFINITE);
				GetOverlappedResult(m_hCom,&m_osRead,&dwLength,TRUE);
				m_osRead.Offset=0;
//				m_osRead.Offset=(m_osRead.Offset+dwLength)%MAXBLOCK;
			}
			else
				dwLength=0;
		}
	}
	return dwLength;
}
  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值