//////////////////////////////////////////////////////////////////////////////////////////////////
//Command format = Index(2) + Command(2) + Length(2) + Data(Length)
//Packet format = STX(1) + Index(1) + ~Index(1) + Command(2) + Length(2) + Data(Length)+CRC(2)
//STX--发送一个包的开始标志   Index--数据包被分成定长1024来发送,看现在发送是第几个
//~Index--标志接收是否正确    正确的话Index=~(~Index)
//Command--ACK/NCK   Length--表示数据的长度 
//CRC(2)--计算机CRC
//////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CRS232Device::bSend(LPCSTR lpszBuff, int nLen, int *pnError)
//lpszBuff--要发送的数据  nLen--数据长度   pnError--错误标志
{
int nLeft;
unsigned char ucIndex;
BYTE szBuff[SIZE_PACKET];
BYTE nSeed;
WORD nCRC;
BOOL bWrite; LPCSTR lpszSRC = lpszBuff; ucIndex = nLen / SIZE_PACKET_DATA;//计算总共几个包(SIZE_PACKET_DATA=1024-9)
if (nLen % SIZE_PACKET_DATA)
ucIndex++; nLeft = nLen; while (nLeft > 0)
{
memset(szBuff, 0, sizeof(szBuff)); szBuff[0]=(BYTE)STX;//包的标记
szBuff[1] = (BYTE)ucIndex; //第几个包
szBuff[2] =  (BYTE)~ucIndex;

if (nLeft >= SIZE_PACKET_DATA)
{
szBuff[3] = LOBYTE(SIZE_PACKET_DATA);
szBuff[4] = HIBYTE(SIZE_PACKET_DATA);
memcpy(szBuff + 5, lpszSRC, SIZE_PACKET_DATA);
lpszSRC += SIZE_PACKET_DATA;
nLeft -= SIZE_PACKET_DATA;
}
else
{
szBuff[3] = LOBYTE(nLeft);
szBuff[4] = HIBYTE(nLeft);
memcpy(szBuff + 5, lpszSRC, nLeft);
nLeft = 0;
} nCRC = 0;
for (int i = 1 ; i < 1022 ; i++)//计算CRc,从Index(1)开始计算
{
nSeed = (BYTE)(nCRC / 1024);
nCRC <<= 8;
nCRC ^= crc_tab[(BYTE)(nSeed ^ szBuff[i])];
}
szBuff[1022] = LOBYTE(nCRC);
szBuff[1023] = HIBYTE(nCRC); bWrite=WriteFile(m_hDevice,szBuff,nLen-nSeed,(LPDWORD)nSeed,NULL);//发送文件 if(!bWrite)
{
*pnError=COMMAND_DISCONNECT;
return FALSE;
} ucIndex--;
}
FlushFileBuffers(m_hDevice); return TRUE;
}BOOL CRS232Device::bReceive(LPSTR lpszBuff, int *pnError)
{
unsigned char ucIndex1,ucIndex2;
int nLast,nSTX,nLen;
BYTE szBuff[SIZE_PACKET];
BYTE nRecv;
WORD nCRC;
LPSTR lpszDest;
BOOL bRead;
HANDLE hReadEvent; hReadEvent=CreateEvent(NULL,TRUE,TRUE,NULL);//创建文件
if(hReadEvent==NULL)
{
*pnError=GetLastError();
return FALSE;
}

lpszDest = lpszBuff;
nSTX=-1; do
{
memset(szBuff, 0, sizeof(szBuff));
nLast=nSTX;
nSTX=szBuff[0]; if (WaitForMultipleObjects(1, &hReadEvent, FALSE, m_nRecvTimeout) != WAIT_OBJECT_0)//等待
{
*pnError = ERRORCODE_TIMEOUT;
return FALSE;
} if (nLast != -1 && (nLast - 1) != nSTX)
{
*pnError = ERRORCODE_WRONGPACKET;
return FALSE;
} nCRC = 0; for (int i = 1 ; i < 1022 ; i++)//计算CRC
{
nRecv = (BYTE)(nCRC / 1024);
nCRC <<= 8;
nCRC ^= crc_tab[(BYTE)(nRecv ^ szBuff[i])];
}

ucIndex1=szBuff[1];
ucIndex2=szBuff[2]; if(ucIndex1!=~ucIndex2)
{
*pnError=ERRORCODE_WRONGPACKET;
return FALSE;
} if (szBuff[SIZE_PACKET - 2] != LOBYTE(nCRC) || szBuff[SIZE_PACKET - 1] != HIBYTE(nCRC))
{
*pnError = ERRORCODE_CRCCHECK;
return FALSE;
} nLen = MAKEWORD(szBuff[3], szBuff[4]);
memcpy(lpszDest, szBuff + 5, nLen); ReadFile(m_hDevice,lpszDest,nLen-nRecv,(LPDWORD)nRecv,NULL);//接收 lpszDest += nLen; } while (ucIndex1 > 1); return TRUE;
}
这样写RS232来传输Send,和对应的Recv正确吗?
主要是Recv,自己还是不太理解,第一次做通信,问题好多.

解决方案 »

  1.   

    接收的方式
    BOOL  bResult = TRUE;
    BOOL  bRead = TRUE;
    for (;;)
    {
       if (bRead)
           bResult = ReadFile(m_hDevice,lpszDest,nLen-nRecv,(LPDWORD)nRecv,NULL);//
           if (!bResult)  
           { 
    switch (dwError = GetLastError()) 

    case ERROR_IO_PENDING: 
    {       bRead = FALSE;
         break;
    }
    default:
    {
    break;

            }
    }
    else
    { bRead = TRUE;
    }
    //lpszDest对你的数据进行处理
    }
      

  2.   

    bWrite=WriteFile(m_hDevice,szBuff,nLen-nSeed,(LPDWORD)nSeed,NULL);//发送文件 
    //第4个参数是返回值,指本次write实际写入的字节数,最好改成这样
    DWORD dwWrite;
    bWrite=WriteFile(m_hDevice,szBuff,nLen-nSeed,&dwWrite,NULL);//发送文件 
    //读串口的也一样。//读取的时候的CreateEvent()和WaitForMultipleObjects是做什么用的?
    //现在串口的读写都是同步方式,注意CreateFile的时候也用同步方式。
      

  3.   

    //以事件驱动的读线程
    DWORD TheardEvent(LPVOID pParam)
    {
    BOOL bCommState = TRUE;
    DWORD deEvtMask, dwRes, dwLength;
    DWORD dwErrors;
    COMSTAT ComStat;
    int i;
    CString str;
    BOOL bifwan = FALSE;
    BYTE bmydata[25]; OS.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    while (bCommState)//串口打开状态 
    {
    WaitCommEvent(hCom, &deEvtMask, &OS);
    dwRes = WaitForSingleObject(OS.hEvent, INFINITE);
    if(WAIT_OBJECT_0 == dwRes)  //得到事件监视结果
    {
    if(EV_RXCHAR == deEvtMask)
    {
    ClearCommError(hCom, &dwErrors, &ComStat);
    dwLength = ComStat.cbInQue; if (dwLength > 0)                   //接受缓冲区数据长度大于0
    {
    ReadComm(dwLength, bmydata);//读取数据
    }                                //这个地方可以把这次接收的数据拷贝到一个数组内
                                    //然后判断接收这次的数据后,是否形成了完整的一包数据
    if(bifwan)//如果接收到完整的一包数据,通知主线程处理(显示什么的)
    {          //否则就要继续接收,知道收到完整的一包
    ::PostMessage(HWND(mainhandle), WM_DEBUG, 0, 0);
    bifwan = FALSE;
    } }
    }
    }
    return 0;
    }//接收函数
    BYTE ReadComm(char* cBuffer, int iReadNum)
    {
    OVERLAPPED Read_OS;
    DWORD dwRead;
    DWORD dwRes; memset(&Read_OS,0,sizeof(OVERLAPPED));
    Read_OS.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
    if(Read_OS.hEvent == NULL)
    return 0x01;

    if(!ReadFile(hCom, cBuffer, iReadNum, &dwRead, &Read_OS))
    {
    if(GetLastError() != ERROR_IO_PENDING)
    {
    CloseHandle(Read_OS.hEvent);
    return 0x02; //连接错误
    }
    else
    {
    dwRes = WaitForSingleObject(Read_OS.hEvent, 500); //设置半秒超时
    switch(dwRes)
    {
    case WAIT_OBJECT_0: //消息到达
    if (!GetOverlappedResult(hCom, &Read_OS, &dwRead, FALSE))
    {
    CloseHandle(Read_OS.hEvent);
    return 0x02; //连接错误
    }
    else
    {
    CloseHandle(Read_OS.hEvent);
    return 0; //读取成功
    }
    case WAIT_TIMEOUT: //超时时间已过
    CloseHandle(Read_OS.hEvent);
    return 0x04;
    default:
    {
    CloseHandle(Read_OS.hEvent);
    return 0x03; //Error in the WaitForSingleObject; abort.This indicates a problem with the OVERLAPPED structure's event handle.
    }
    }
    }
    }
    else
    {
    CloseHandle(Read_OS.hEvent);
    return 0; //读取成功
    }

    CloseHandle(Read_OS.hEvent);
    return 0;
    }
      

  4.   

    这样写RS232来传输Send,和对应的Recv正确吗?
    主要是Recv,自己还是不太理解,第一次做通信,问题好多.
    --------------------------------------------------
    其实你首先要看看你的程序结果如何,是否达到了你的要求