串口通信中关于CSerialPort类中的RecvData()如何使用?

hj0710101707 2013-07-08 09:08:14
1、串口通信中CSerialPort类中的BOOL CSerialPort::RecvData(LPTSTR lpszData, const int nSize)如何使用??最好有相关例子可以参考参考。本人第一次接触串口通讯,不是很懂,求大神指教。最好有写好的例子供参考。
2、另外用winAPI函数编写串口通讯的一个函数,如下面所写的
void CMainFrame::Mp285_Move(float xValue, float yValue, float zValue)
{
xValue*=25;
yValue*=25;
zValue*=25;
long xValue285, yValue285, zValue285;
//4 She 5 Ru
xValue285 = round_45(xValue);
yValue285 = round_45(yValue);
zValue285 = round_45(zValue);

DWORD dwWritten;
char Buf[14]; //输入缓冲区
char lpBuf[40]; //接收缓冲区
unsigned long nRead;

Buf[0]='m';
memcpy(Buf+1,(char*)&xValue285,4);
memcpy(Buf+5,(char*)&yValue285,4);
memcpy(Buf+9,(char*)&zValue285,4);
Buf[13]='\r';

m_n285IsMoving=TRUE;

DWORD dwWTrans;
OVERLAPPED osWrite={0}; //写操作使用的OVERLAPPED结构osWrite
osWrite.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL); //默认的安全属性、使用自动重置信号状态、信号状态设为无信号状态、无事件名称
//write buf contents to the instrument
::WriteFile(hCom[1],Buf,14,&dwWritten, &osWrite); //发送数据
//True: Wait forever until the writting process is done
GetOverlappedResult(hCom[1],&osWrite,&dwWTrans,TRUE);

DWORD dwReader;
OVERLAPPED osRead={0}; //读操作使用的OVERLAPPED结构osRead
osRead.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
ResetEvent(osRead.hEvent);
//Read response from instrument to lpBuf //(接收数据)
::ReadFile(hCom[1], lpBuf, 1, &nRead, &osRead); //hCom[1]: 串口的句柄,
// lpBuf: 读入的数据存储的地址,即读入的数据将存储在以该指针的值为首地址的一片内存区
// 1 : 要读入的数据的字节数
//&nRead: 指向一个DWORD数值,该数值返回读操作实际读入的字节数
//&osRead: 重叠操作时,该参数指向一个OVERLAPPED结构,同步操作时,该参数为NULL
// GetSystemTime(&sTime1);
//Wait untill the moving is finished.
while (m_n285IsMoving)
{
// MP285_PeekandPump();
if (GetOverlappedResult(hCom[1],&osRead,&dwReader,FALSE))
{
m_n285IsMoving=FALSE;
}
}
CloseHandle(osWrite.hEvent);
CloseHandle(osRead.hEvent);
}
我想要问的是上位机通过(::WriteFile(hCom[1],Buf,14,&dwWritten, &osWrite); ) 发送数据后,然后通过(::ReadFile(hCom[1], lpBuf, 1, &nRead, &osRead); ),上位机接收下位机发送的数据,(1)这里上位机接收的1个字节数据用来做什么的?在程序中看不出来啊。(2)一般下位机发送给上位机的数据有什么作用?(3)如何用CSerialPort这个类改写上面的这个整个函数??求大神指教!!不胜感激!!
...全文
1226 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hj0710101707 2014-03-08
  • 打赏
  • 举报
回复
我后来没用那个类了,用了API函数编写的,结贴,谢谢各位!
kuroro 2013-10-16
  • 打赏
  • 举报
回复
龚建伟的书有介绍的
FlyingTiger_Sun 2013-10-04
  • 打赏
  • 举报
回复
你使用的修正版本的Cserialport类吧,这个类中,SendData和RecData是后来加上去的, 这2个函数主要是用在发送文件时调用,下面有段代码,可以参考下
BOOL CMyCommDoc::SendByXmodem(LPCTSTR lpszData, const int nLength, const int nRetryTimes)
{
	char szPacket[XMODEM_BLOCK_HEAD_SIZE + XMODEM_BLOCK_NO_SIZE + 
		  XMODEM_BLOCK_BODY_SIZE + XMODEM_BLOCK_CHK_SIZE];
    char szRecvBuff[128];
    char cPartNo = 0;
    char cChkSum = 0;
    int nRetry   = 0;
    int nTemp1, nTemp2;
	
    // Notify Destination of Data Transfer
    sprintf(szPacket, "%c", XMODEM_STA);
    m_Comm.SendData(szPacket, 1);
	Sleep(100);
    if (m_Comm.RecvData(szRecvBuff, sizeof(szRecvBuff)) && szRecvBuff[0] == XMODEM_NAK)
    {
		// Send Data
		for (nTemp1 = 0; nTemp1 < nLength; nTemp1 += XMODEM_BLOCK_BODY_SIZE)
		{

			//1.Make One Packet 
			memset(szPacket, NULL, sizeof(szPacket));
			if (cPartNo == 0xFF)
				cPartNo = 0;
			else
				cPartNo++;
			cChkSum = 0;
			szPacket[0] = XMODEM_SOH;
			szPacket[1] = cPartNo;
			szPacket[2] = 0xFF - cPartNo;
			for (nTemp2 = 0; nTemp2 < XMODEM_BLOCK_BODY_SIZE; nTemp2++)
			{
				if ((nTemp1 + nTemp2) < nLength)
					szPacket[XMODEM_BLOCK_HEAD_SIZE + XMODEM_BLOCK_NO_SIZE + nTemp2] = *(lpszData + nTemp1 + nTemp2);
				else
					szPacket[XMODEM_BLOCK_HEAD_SIZE + XMODEM_BLOCK_NO_SIZE + nTemp2] = XMODEM_EOF;
				cChkSum += szPacket[XMODEM_BLOCK_HEAD_SIZE + XMODEM_BLOCK_NO_SIZE + nTemp2];
			}
			szPacket[sizeof(szPacket) - 1] = cChkSum;

			//2.Send Packet
			m_Comm.SendData(szPacket, sizeof(szPacket));
			while (true)
			{
				Sleep(10);
				if (m_Comm.RecvData(szRecvBuff, sizeof(szRecvBuff)))
				{
					// Affirmative Answer
					if (szRecvBuff[0] == XMODEM_ACK)
						break;
					// Negative Answer
					else
						if (szRecvBuff[0] == XMODEM_NAK)
						{
							m_Comm.SendData(szPacket, sizeof(szPacket));
							nRetry++;
						}
				}
				if (nRetry >= nRetryTimes)
				{
					// Cancel Transfer
					sprintf(szPacket, "%c%c%c%c%c", XMODEM_CAN, XMODEM_CAN, XMODEM_CAN, XMODEM_CAN, XMODEM_CAN);
					m_Comm.SendData(szPacket, 5);
					return false;
				}
			}
		} // end form
	} //end if
	
    // Transfer Done
    sprintf(szPacket, "%c%c%c%c%c", XMODEM_EOT, XMODEM_EOT, XMODEM_EOT, XMODEM_EOT, XMODEM_EOT);
    m_Comm.SendData(szPacket, 5);
    return true;	
}
SendData其实和WriteToPort(LPCTSTR string)一样,好理解,在代码中手动调用就触发了写事件.它最后还是调用WriteChar()一个一个字符的来发送. RecvData未使用监视线程,调用时手动触发.若想了解详细的使用过程,你可以在网上下载 serialProject代码看下
hj0710101707 2013-07-13
  • 打赏
  • 举报
回复
有没有更好的答复的??
hj0710101707 2013-07-09
  • 打赏
  • 举报
回复
没有人会吗?求指导啊,自己先顶下~~~~~~
yaozhiyong110 2013-07-09
  • 打赏
  • 举报
回复
网上的CSerialPort类 不都是收到一个字符就发消息到到窗口吗? 参考(CSerialPort::ReceiveChar) 你再窗口消息里去取收到的数据就是啊

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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