串行通讯问题


上一页


糟糕,我手头没有WIN3.2下的串口程序。倒是可以随便在什么杂志上抄下来给你,OPENCOM,CLOSECOM之类。可是毕竟没有亲自试过...要不,你把你的历经磨炼的程序MAIL给我,让我填满这个空格?

回页首



在95下,BC与VC稍有不同了。下面这个BC下的程序是
老狐狸的:


int main()
{
   HANDLE HdComm;
   DWORD DwError;
   DCB Dcb;
   unsigned char Msg[128], Data;
   int RealNum;

   // Open the COMM port.
   HdComm = CreateFile( "COM1", GENERIC_READ | GENERIC_WRITE, 0,
        NULL, OPEN_EXISTING, 0, NULL );
   if ( HdComm == (COMMPORT)0xFFFFFFFF ) // If COMM port can't be opened, then ...
   {
      DwError = GetLastError();  // Display error code, and abort.
      FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, DwError, 0, Msg, 124, 0 );
      printf( "Cannot Open Port COM1 !\nError Code: %d, - %s.\n", DwError, Msg );

      return;
   }

   // Initialize COMM port.
   SetupComm( HdComm, 1024, 1024 );
   GetCommState( HdComm, &Dcb );
   Dcb.BaudRate = BAUD_115200;
   Dcb.Parity = NOPARITY;
   Dcb.ByteSize = 8;
   Dcb.StopBits = ONESTOPBIT;
   SetCommState( HdComm, &Dcb );

   do {
      ReadFile( HdComm, &Data, 1, &RealNum, NULL );  // Recieve the char from COM1
      WriteFile( HdComm, &Data, 1, &RealNum, NULL ); // Write the recieved data to COM1
      printf( "%02x    ", Data );                    // Display the data
   } while( Data != 0x1b );                          // Loop until the data is ESC
   
   CloseHandle( HdComm );
   return 0;
}

这个程序段的作用是调用CreateFile()打开串口1,用SetCommState()设置通讯参数 (115200bps,无校验,8-bit字长,1-bit停止位),然后循环读/写串行口,接收数据采用ReadFile(),发送数据采用WriteFile(),当接收到的数据为ESC字符(ASCII码为0x1b)时,退出循环,最后调用CloseHandle()关闭串行口。
注意本程序作为Win32 Console程序编译(因其使用了printf这样的控制台函数)。
运行本程序之后,在另一台计算机上运行WIN95的“超级终端”,设置通讯参数为115200bps,无校验,8-bit字长,1-bit停止位,并关闭 “终端仿真参数”中的“本地回显”。在超级终端中键入字符,终端窗口中会显示键入的字符,同时运行演示程序的计算机屏幕上显示键入字符的ASCII代码。

回页首

下面是比较完整的VC 下的某个类的成员,你一看就知道应该如何把它加到你程序中。

/*-------------------------Private function.----------------*/
// Function name    : TEMP::InitComm
// Description        : Initial Comm Port.
// Return type        : BOOL :TRUE if success
// Argument            : LPVOID lpInitData:a point to COMM_CONFIG structure.
// COMM_CONFIG: deviceName="COM2",stopBits=1,BaundRates="9600",dataBits=7,parity=2
BOOL TEMP::InitComm(LPVOID lpInitData)
{
    char szPort[8]; 
    
    ComDevice *pCommConfig = (ComDevice *)lpInitData;

    m_nTimeOut = pCommConfig->timeOut;
    strcpy(szPort,pCommConfig->deviceName);//"COM2"
    HANDLE hComm = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, 
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL 
        /*| FILE_FLAG_OVERLAPPED*/, NULL );
    if ( INVALID_HANDLE_VALUE==hComm )
        return FALSE;

    int errorCode  = SetupComm( hComm, RX_QUEU, TX_QUEU );
    DWORD temp;
    if( errorCode == 0 )
        temp=GetLastError();

    BYTE stopbits;
    switch ( pCommConfig->stopBits )
    {    // 0=1stopbit, 1=1.5stopbits, 2=2stopbits.
        case 1:
            stopbits = 0;
            break;
        case 2:
            stopbits = 2;
            break;
        default:
            stopbits = 0;
    }
    DCB dcb;
    GetCommState( hComm, &dcb );
    dcb.BaudRate = (DWORD)pCommConfig->baudRate;
    dcb.ByteSize = (BYTE)pCommConfig->dataBits;
    dcb.StopBits = stopbits;//
    dcb.fParity=!(pCommConfig->parity ==  0);

    dcb.Parity =  (BYTE)pCommConfig->parity;
    // dcb.ExChar =  FALSE;
    if ( !SetCommState(hComm, &dcb  ) )

    {    temp  =  GetLastError(); //6  The handle   isinvalid.

        ERROR_INVALID_HANDLE CloseHandle( hComm ); 
        TRACE( "Error in SetCommDcb.\n" );
        ASSERT( FALSE); 
        m_nLastErrorCode = USER_VAR_DCB_ERROR;
        return FALSE;
        } 

    DWORD flag;  
            
    flag = EV_RXCHAR;
    SetCommMask( hComm,  flag|EV_BREAK  );
    VERIFY(PurgeComm(hComm,  PURGE_TXABORT  |  
        PURGE_RXABORT | PURGE_TXCLEAR  |  PURGE_RXCLEAR));  
    COMMTIMEOUTS CommTimeOuts;
    CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
    CommTimeOuts.ReadTotalTimeoutMultiplier=  0 ;
    CommTimeOuts.ReadTotalTimeoutConstant = 0  ;
    CommTimeOuts.WriteTotalTimeoutMultiplier =  10;
        //2*CBR_9600/BAUDRATE( npTTYInfo   ) ;
    CommTimeOuts.WriteTotalTimeoutConstant = 0 ;
    if(SetCommTimeouts(  hComm, &CommTimeOuts ) = =  0)
    {//FAILS! 
        TRACE("SetCommTimeouts Fail!\n");
        m_nLastErrorCode =  GetLastError();
        return FALSE; 
    }
    m_hComm = hComm;
    return TRUE;
}
//
/*
Function name    :    TEMP::PhysicalSend //
Description        :    Send from Comm Port //
Return type        :    int : how many bytes has been send(in byte) //
                    -1 if failed.
Argument        :    char * buf:Buffer for send date. //
Argument        :    int nLen:Lengh of data in Buffer. int
*/
TEMP::PhysicalSend(char * buf, int nLen) {
if
    ( nLen < =0 ) return 1; 
    char *pData="new" 
    char[nLen+2]; 
    memcpy( pData, buf, nLen ); 
    pData[nLen]="0;";
    ULONG nSend="0;";
    if(!WriteFile(m_hComm, pData, nLen, &nSend, NULL)) 
        { delete[] pData; 
        m_nLastErrorCode="GetLastError();" 
        return 1; //1121 A serial I/O operation completed because 
                //the time-out period expired. 
                //(The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.) 
        } 
    #ifdef _DEBUG 
        pData[nLen]="0;" 
    #endif 
    delete[] pData; 
    return (int)nSend; 
} 

// Function name    : TEMP::PhysicalReceive 
// Description        : Check if there's data in Serial Port. If yes, receive. 
// Return type        : BOOL :TRUE:received. 
//                      FALSE:No data, or error. 
// Argument            : char * pReceive:Point to Receive Buffer. 
// Argument            : int & nLen:Lengh (return) 
BOOL TEMP::PhysicalReceive(char * pReceive, int & nLen) 
{ 
    DWORD dwError; 
    COMSTAT cs; 
    ULONG nByteRead="0;" 
    ClearCommError( m_hComm, &dwError, &cs ); 
    int errorcode; 
    if ( cs.cbInQue ) 
        { BOOL bReadSuc= "ReadFile(m_hComm," pReceive, cs.cbInQue, &nByteRead, NULL); 
        if ( bReadSuc &&nByteRead>0 )
        {
            nLen = (int) nByteRead;
            return TRUE;
        }
    }
    errorcode=GetLastError();//debug
//    TRACE("PhysicalReceive ERROR!\n");
    return FALSE;
}

至于关闭串口只是OpenHandle(hComm)一句而已。

回页首  上一页


Copyright 1998-2002 Fadshop.net, Inc. All rights reserved. jhj123@163.net