Serial Port Communication
Last Page, DOS
In Windows 95 there's difference between Borland C and Visual C.
Here is a part of souce code in Borland C, come from
KingFox:
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;
}
Call CreateFile() to open port 1, and setup communication parameter (115200bps,
no check, 8-bit, 1-bit stop)using SetCommState(),
and then read and write serial port for rotation.
ReadFile() is used for receiveing data, and WriteFile is used for sending data.
The application will jump out of the loop when it receive ESC code (0x1b) and
close serial port by CloseHandle().
You should compile this software as a Win32 Console.
While running this application, you can run Hyper Terminal in another computer
and set up communication parameter as the same as this one: 115200bps,
no check, 8-bit, 1-bit stop and turn off "Local Echo" in "Terminal Emulation Parameter"
When you input characters in Hyper Terminal, the computer which is running
the application will display the ASCII of characters.
^Top
Here is a member function of a class in VC.
You can add it in your software.
/*-------------------------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;
}
Use OpenHandle(hComm) to close Comm Port.
^Top
|