⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pc2pcview.cpp

📁 VisualC实践与提高——串口通信与工程应用篇代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
							}
							dwFileLen=arrRcvData[1]+arrRcvData[2]*256+arrRcvData[3]*65536+arrRcvData[4]*16777216;
							myFile.SetLength(dwFileLen);
							uintStxCurNo=1;
							bytRcvStatus=1;
							bytResendCount=0;

							arrSendData[0]=6;
							Write(arrSendData,1);

							break;
						}
					case 100://超时错误
						{
							//接收0态时,对超时不作处理
							break;
						}
					
					}
					break;
				}
			case 1:
				{
					switch(lParam)
					{
					case EV_RXCHAR://收到字符
						{
							switch(Detect(1))
							{
							case 0://收到指定数量的字符
								{
									break;
								}
							case 4://超时错误
								{
									DisRcv(4);
									return -1;
									break;
								}

							case 8://无效,输入缓冲区中字符数量为0
								{
									return 0;
									break;
								}

							}
							switch(Read(myByte,1))
							{
							case 0:
								{
									break;
								}
							case 4:
								{
									DisRcv(4);
									return -1;
									break;
								}
							case 16:
								{
									DisRcv(16);
									return -1;
									break;
								}
							}
							switch(myByte[0])//判断是STX还是ETX
							{
							case 2://首字符是STX
								{
									//读取数据
									arrRcvData[0]=myByte[0];
									uintRcvLen=1028;
									switch(Detect(1027))
									{
									case 0://收到指定数量的字符
										{
											//跳出switch,继续下面的操作
											break;
										}
									case 4://超时错误
										{
											DisRcv(4);
											return -1;
											break;
										}

									case 8://无效,输入缓冲区中字符数量为0
										{
											return 0;
											break;
										}
									}///
									switch(Read(myByte,1027))
									{
									case 0:
										{
											break;
										}
									case 4:
										{
											DisRcv(4);
											return -1;
											break;
										}
									case 16:
										{
											DisRcv(16);
											return -1;
											break;
										}
									}
									for(i=0;i<=1026;i++)
									{
										arrRcvData[i+1]=myByte[i];//保存数据至arrRcvData[]数组中
									}
									
									uintStxCurNo=arrRcvData[1]+arrRcvData[2]*256;
									if(uintStxCurNo==1)
									{
										myEdit.SetSel(1000000,1000000);
										myEdit.ReplaceSel("正在接收数据……\15\12");
									}
									strDis.Format("已接收(%.0f%%)",(float)((uintStxCurNo+1)*1024)/dwFileLen*100);
									m_pStatus->SetPaneText(0,strDis);     //将传输进度显示在状态条上
									myFile.Seek((uintStxCurNo-1)*1024,CFile::begin);
									myFile.Write(&arrRcvData[3],1024);

									bytResendCount=0;
									arrSendData[0]=6;
									Write(arrSendData,1);
									
									break;
								}

							case 3://首字符是ETX
								{
									//读取数据
									arrRcvData[0]=myByte[0];
									switch(Read(myByte,2))
									{
									case 0:
										{
											break;
										}
									case 4:
										{
											DisRcv(4);
											return -1;
											break;
										}
									case 16:
										{
											DisRcv(16);
											return -1;
											break;
										}
									}
									arrRcvData[1]=myByte[0];
									arrRcvData[2]=myByte[1];
									uintRcvLen=1+2+2+(arrRcvData[1]+arrRcvData[2]*256)+1;//数据总长度

									switch(Read(myByte,uintRcvLen-3))
									{
									case 0:
										{
											break;
										}
									case 4:
										{
											DisRcv(4);
											return -1;
											break;
										}
									case 16:
										{
											DisRcv(16);
											return -1;
											break;
										}
									}
									for(i=0;(UINT)i<=uintRcvLen-2;i++)
									{
										arrRcvData[i+3]=myByte[i];
									}
									//至此,完整数据已经读入arrRcvData[]中。
									uintStxCurNo=arrRcvData[3]+arrRcvData[4]*256;
									if(uintStxCurNo==1)
									{
										myEdit.SetSel(1000000,1000000);
										myEdit.ReplaceSel("正在接收数据……\15\12");
									}
									myFile.Seek((uintStxCurNo-1)*1024,CFile::begin);
									myFile.Write(&arrRcvData[5],arrRcvData[1]+arrRcvData[2]*256);

									myEdit.SetSel(1000000,1000000);
									myEdit.ReplaceSel("接收完毕!\15\12\15\12");
									strDis="已接收完毕";
									m_pStatus->SetPaneText(0,strDis);     //将传输进度显示在状态栏上
									bytRcvStatus=0;
									bytActStatus=10;
									bytSendStatus=0;
									bytResendCount=0;
									arrSendData[0]=6;
									Write(arrSendData,1);
									if(myFile.m_pStream!=NULL)
									{
										myFile.Close();//关闭打开的文件
									}
									break;
								}
							}
							break;
						}
					case 100://超时错误
						{
							break;
						}
					}
					break;
				}
			}
			break;
		}


	}
	return 0;
}

void CPC2PCView::OnUpdateSendfile(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (blnOpened)//根据串口是否打开,决定是否允许“发送文件”命令
	{
		if(!((bytSendStatus+bytRcvStatus)>0))//当前既没开始发送,也没开始接收
		{
			pCmdUI->Enable(true);
		}
		else
		{
			pCmdUI->Enable(false);
		}
	}
	else
	{
		pCmdUI->Enable(false);
	}
}

void CPC2PCView::OnUpdateSetupcom(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (!blnOpened)//根据串口是否打开,决定是否允许“设置”命令
	{
		pCmdUI->Enable(true);
	}
	else
	{
		pCmdUI->Enable(false);
	}
}

void CPC2PCView::OnUpdateOpencom(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (!blnOpened && blnSeted)//根据串口是否打开,决定是否允许“打开”命令
	{
		pCmdUI->Enable(true);
	}
	else
	{
		pCmdUI->Enable(false);
	}
}

void CPC2PCView::OnUpdateClosecom(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (blnOpened)//根据串口是否打开,决定是否允许“关闭”命令
	{
		if(!((bytSendStatus+bytRcvStatus)>0))//当前既没开始发送文件,也没开始接收文件
		{
			pCmdUI->Enable(true);
		}
		else
		{
			pCmdUI->Enable(false);
		}
	}
	else
	{
		pCmdUI->Enable(false);
	}
}

int CPC2PCView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CEditView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	CEdit& myEdit=this->GetEditCtrl( );
	myEdit.SetReadOnly (true);                         //将显示区域设为只读
	hWnd=GetSafeHwnd();                                    //获取当前窗口的句柄

	blnOpened=false;     //串口已经打开标志
	blnSeted=false;      //已经设置过通信参数
	bytRcvStatus=0;      //初始化时,接收状态为等待ENQ
	dwTimeoutValue=1500; //初始化事件线程超时时间
	bytActStatus=10;     //初始化为接收态
	blnNoTimeout=true;
	uintStxCurNo=0;
	bytTimeoutCounter=0;
	return 0;
}
bool CPC2PCView::DisSend(BYTE bytType)//发送态显示信息函数,bytType决定显示信息的内容
{
	CString strDis;
	CEdit& myEdit=this->GetEditCtrl();
	myEdit.SetReadOnly(true);
	myEdit.SetSel(1000000,1000000);
	switch(bytType)
	{
	case 1:
		{
			strDis="取消操作!\15\12";
			break;
		}
	case 2:
		{
			strDis="收到无效的命令!\15\12";
			break;
		}
	case 4:
		{
			strDis="对方无响应,超时错误!\15\12";
			break;
		}
	case 8:
		{
			strDis="重试次数多于3次!\15\12";
			break;
		}
	}
		
	myEdit.ReplaceSel(strDis);
	bytSendStatus=0;//恢复发送0态
	bytActStatus=10;//恢复为接收态
	bytRcvStatus=0;
	bytResendCount=0;//重试次数初始化为0
	if(myFile.m_pStream!=NULL)
	{
		myFile.Close();//关闭打开的文件
	}
	Beep(1000,50);
	return true;

}
bool CPC2PCView::DisRcv(BYTE bytType)//接收态显示信息函数,bytType决定显示信息的内容
{
	CString strDis;
	CEdit& myEdit=this->GetEditCtrl();
	myEdit.SetReadOnly(true);
	myEdit.SetSel(1000000,1000000);
	switch(bytType)
	{
	case 1:
		{
			strDis="取消操作!\15\12";
			break;
		}
	case 2:
		{
			strDis="收到无效的命令!\15\12";
			break;
		}
	case 4:
		{
			strDis="对方无响应,超时错误!\15\12";
			break;
		}
	case 8:
		{
			strDis="重试次数多于3次!\15\12";
			break;
		}
	}
		
	myEdit.ReplaceSel(strDis);
	bytRcvStatus=0;           //恢复接收0态
	bytActStatus=10;          //恢复为接收态
	bytSendStatus=0;          //发送态恢复为0态
	bytResendCount=0;         //重试次数初始化为0
	if(myFile.m_pStream!=NULL)
	{
		myFile.Close();       //关闭打开的文件
	}
	return true;
}
BYTE CPC2PCView::Read(BYTE arrBin[],int count)//读数据函数,arrBin[]存放数据,count是读的个数
{									//成功返回0,读失败返回16,超时错误返回4
	DWORD dwRes;
	DWORD dwRead;
	Rol.hEvent=CreateEvent(NULL, //创建Rol.hEvent为无信号状态
		TRUE,                 
		FALSE, 
		NULL);
	if (ReadFile(hCom,
		arrBin,
		count,                     //读取count个字节
		NULL,
		&Rol))
	{
		 //串口接收的数据已经成功读出,并存放在arrBin[]数组中
		return 0;
	}
	else
	{
		dwRes = WaitForSingleObject(Rol.hEvent, 
			2000);                      //设置2秒的读超时
		switch(dwRes)
		{
		case WAIT_OBJECT_0:
			{
				 if (!GetOverlappedResult(hCom, 
						&Rol, 
						&dwRead,             //实际读取字节数存放在dwRead中
						TRUE))
				 {   
					 //读操作失败。使用GetLastError()函数可以获取错误消息
						return 16;
				 }
				 else
				 {
					   //串口接收的数据已经成功读出,并存放在arrBin[]数组中
					 return 0;
				 }
				 break;
			}
		case WAIT_TIMEOUT:
			{
				//读操作出现超时错误。
				return 4;
			}
		}
	}
	return 0;
}



//发送数据函数,arrBin[]存放数据,count是发送个数
//发送态时,发送数据调用这个函数
//接收态时,响应时调用这个函数发送响应代码ACK、NAK或CAN
bool CPC2PCView::Write(BYTE arrBin[],int count)
{
	DWORD	dwWrite;
	Wol.hEvent=CreateEvent(NULL, //创建Wol.hEvent事件句柄,并设置为无信号状态
		TRUE, 
		FALSE, 
		NULL);
	WriteFile(hCom,                //写数据,通过Wol结构获取操作结果
		arrBin,
		count,
		NULL,
		&Wol);
	if(GetOverlappedResult(hCom,&Wol,&dwWrite,true))
	{
		return true;
	}
	return false;

}
//检测串口输入缓冲区中是否有指定个数的数据
//返回0-有,4-超时错误,8-无效
BYTE CPC2PCView::Detect(int count)
{
	DWORD dwErrors;
	COMSTAT Rcs;
	CString strDis,strDis1;
	BYTE bytTimeCount;
	ClearCommError(hCom,                  //串口句柄
		&dwErrors,                        //存放出错信息的掩码组合
		&Rcs);                             //COMSTAT类型结构变量
	if(Rcs.cbInQue==0)
		return 8;
	bytTimeCount=0;
	while(bytTimeCount<4)
	{
		ClearCommError(hCom,                //串口句柄
			&dwErrors,                        //存放出错信息的掩码组合
			&Rcs);                             //COMSTAT类型结构变量
		if(Rcs.cbInQue>=(UINT)count)
		{
			return 0;//在输入缓冲区中找到指定数量的字符
		}
		Sleep(500);
		bytTimeCount++;
	}
	if((bytTimeCount>=4)&&(Rcs.cbInQue>0))//超时错误
	{
		return 4;//未找到
	}
	return 8;//无效状态,输入缓冲区中为0个字符
}

void CPC2PCView::OnDestroy() 
{
	
	CEditView::OnDestroy();
	
	// TODO: Add your message handler code here
	
}

void CPC2PCView::OnUpdateAppExit(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if (!blnOpened)          //根据串口是否打开,决定是否允许“退出”命令
	{
		pCmdUI->Enable(true);
	}
	else
	{
		pCmdUI->Enable(false);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -