在哪里下载的也忘掉了,在2000下用起来没有问题,但98下面,发送的len与written不一样,发送len为8字节,但WriteFile调用后,实际写过去的字节数变量written为0,但接收方也明明看到有8个字节送过来的。请高手看一眼代码,以前没有在98下面试过,这一试傻眼了,查了MSDN好像也没有什么不对的地方啊:(comaccess.h////////////////////////////////////////////////////////////////////////////////////////
//
// Project: Class ComAccess
// Overlapped serial IO communication class
// System: Win9x WinNT
// File: comaccess.h
// Start date: 17.11.1997
// Update: 31.07.1998
// Version: 1.2
// Author: Patrick Feuser [email protected] Germany
// Copyright © 1997. Alle Rechte vorbehalten
//
////////////////////////////////////////////////////////////////////////////////////////#ifndef _COMACCESS_H_
#define _COMACCESS_H_
#include <windows.h>
class ComAccess
{
private: HANDLE m_hCom; // Device handle OVERLAPPED m_ov; // A structure that contains informations which are
// used for asynchronous input and output operations TCHAR m_lpszErrorMessage[256];public: ComAccess(VOID);
ComAccess(LPCSTR lpszPortNum); ~ComAccess() { Close(); }
// For more definitions see <winbase.h>
BOOL Open(LPCSTR lpszPortNum = "com1",
DWORD dwBaudRate = CBR_9600,
BYTE byParity = NOPARITY,
BYTE byStopBits = TWOSTOPBITS,
BYTE byByteSize = 8); VOID Close(VOID);
DWORD WriteData(LPCVOID pdata, DWORD len);
DWORD ReadData(LPVOID pdest, DWORD len, DWORD dwMaxWait = 500); LPSTR GetErrorMessage(VOID) { return m_lpszErrorMessage; }private: VOID ErrorToString(LPCSTR lpszMessage); BOOL IsNT(VOID);
};
#endif // _COMACCESS_H_
//
// Project: Class ComAccess
// Overlapped serial IO communication class
// System: Win9x WinNT
// File: comaccess.h
// Start date: 17.11.1997
// Update: 31.07.1998
// Version: 1.2
// Author: Patrick Feuser [email protected] Germany
// Copyright © 1997. Alle Rechte vorbehalten
//
////////////////////////////////////////////////////////////////////////////////////////#ifndef _COMACCESS_H_
#define _COMACCESS_H_
#include <windows.h>
class ComAccess
{
private: HANDLE m_hCom; // Device handle OVERLAPPED m_ov; // A structure that contains informations which are
// used for asynchronous input and output operations TCHAR m_lpszErrorMessage[256];public: ComAccess(VOID);
ComAccess(LPCSTR lpszPortNum); ~ComAccess() { Close(); }
// For more definitions see <winbase.h>
BOOL Open(LPCSTR lpszPortNum = "com1",
DWORD dwBaudRate = CBR_9600,
BYTE byParity = NOPARITY,
BYTE byStopBits = TWOSTOPBITS,
BYTE byByteSize = 8); VOID Close(VOID);
DWORD WriteData(LPCVOID pdata, DWORD len);
DWORD ReadData(LPVOID pdest, DWORD len, DWORD dwMaxWait = 500); LPSTR GetErrorMessage(VOID) { return m_lpszErrorMessage; }private: VOID ErrorToString(LPCSTR lpszMessage); BOOL IsNT(VOID);
};
#endif // _COMACCESS_H_
//
// Project: Class ComAccess
// Overlapped serial IO communication class
// System: Win9x WinNT
// File: comaccess.cpp
// Start date: 17.11.1997
// Update: 31.07.1998
// Version: 1.2
// Author: Patrick Feuser [email protected] Germany
// Copyright © 1997. Alle Rechte vorbehalten
//
////////////////////////////////////////////////////////////////////////////////////////#include "StdAfx.h"
#include "comaccess.h"////////////////////////////////////////////////////////////////////////////////////////
//
// Constructors
//ComAccess::ComAccess(VOID)
{
m_hCom = 0;
m_lpszErrorMessage[0] = '\0';
ZeroMemory(&m_ov, sizeof(m_ov));
}
ComAccess::ComAccess(LPCSTR lpszPortNum)
{
ComAccess::ComAccess();
ComAccess::Open(lpszPortNum);
}////////////////////////////////////////////////////////////////////////////////////////
//
// Function: Open(LPCSTR lpszPortNum,
// DWORD dwBaudRate,
// BYTE byParity,
// BYTE byStopBits,
// BYTE byByteSize)
//
// Return value: BOOL TRUE or FALSE
//BOOL ComAccess::Open(LPCSTR lpszPortNum,
DWORD dwBaudRate,
BYTE byParity,
BYTE byStopBits,
BYTE byByteSize)
{
DCB dcb; // structure that defines the control setting for a serial communications device
BOOL bSuccess;
m_hCom = CreateFile(lpszPortNum, // pointer to name of the file
GENERIC_READ|GENERIC_WRITE, // access mode
0, // comm devices must be opened w/exclusive-access
NULL, // no security attributs
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL); // hTemplate must be NULL for comm devices if ( m_hCom == INVALID_HANDLE_VALUE )
{
// handle the error
ComAccess::ErrorToString("Open(): CreateFile() failed, invalid handle value");
return FALSE;
} //
// Omit the call to SetupComm to use the default queue sizes.
// Get the current configuration.
//
bSuccess = GetCommState(m_hCom, &dcb); if ( ! bSuccess )
{
// Handle the error.
ComAccess::ErrorToString("Open(): GetCommState() failed");
ComAccess::Close(); return FALSE;
} //
// Fill in the DCB: baud=9600, 8 data bits, no parity, 1 stop bit are default parameters
// dcb.BaudRate = dwBaudRate;
dcb.ByteSize = byByteSize;
dcb.Parity = byParity;
dcb.StopBits = byStopBits;
bSuccess = SetCommState(m_hCom, &dcb); if ( ! bSuccess )
{
// Handle the error.
ComAccess::ErrorToString("Open(): SetCommState() failed");
ComAccess::Close(); return FALSE;
} return TRUE;
}////////////////////////////////////////////////////////////////////////////////////////
//
// Function: Close(VOID)
//
// Return value: VOID
//VOID ComAccess::Close(VOID)
{
if ( m_hCom > 0 )
{
CloseHandle(m_hCom);
} m_hCom = 0;
}////////////////////////////////////////////////////////////////////////////////////////
//
// Function: WriteData(LPCVOID pdata,
// DWORD len)
//
// Return value: DWORD -1 failed, above, num written bytes
//DWORD ComAccess::WriteData(LPCVOID pdata,
DWORD len)
{
BOOL bSuccess;
DWORD written = 0; if ( len < 1 )
return(0); // create event for overlapped I/O
m_ov.hEvent = CreateEvent(NULL, // pointer to security attributes
FALSE, // flag for manual-reset event
FALSE, // flag for initial state
""); // pointer to event-object name if ( m_ov.hEvent == INVALID_HANDLE_VALUE )
{
// Handle the error.
ComAccess::ErrorToString("WriteData(): CreateEvent() failed");
return(-1);
} bSuccess = WriteFile(m_hCom, // handle to file to write to
pdata, // pointer to data to write to file
len, // number of bytes to write
&written, // pointer to number of bytes written
&m_ov); // pointer to structure needed for overlapped I/O
if ( ComAccess::IsNT() )
{
bSuccess = GetOverlappedResult(m_hCom, &m_ov, &written, TRUE); if ( bSuccess )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("WriteData(): GetOverlappedResult() failed"); CString msg_1;
msg_1.Format ("len is %d, written is %d",len,written);
ComAccess::ErrorToString(msg_1);
return(-1);
}
}
else
if ( len != written )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
CString msg_1;
msg_1.Format ("len is %d, written is %d",len,written);
ComAccess::ErrorToString(msg_1); return(-1);
} CloseHandle(m_ov.hEvent); written = 8;
return written;
}////////////////////////////////////////////////////////////////////////////////////////
//
// Function: ReadData(LPVOID pdest,
// DWORD len,
// DWORD dwMaxWait)
//
// Return value: DWORD -1 failed, above, num read bytes
//
DWORD len,
DWORD dwMaxWait)
{
BOOL bSuccess;
DWORD result = 0,
read = 0, // num read bytes
mask = 0; // a 32-bit variable that receives a mask
// indicating the type of event that occurred if ( len < 1 ) return(0); // create event for overlapped I/O m_ov.hEvent = CreateEvent(NULL, // pointer to security attributes
FALSE, // flag for manual-reset event
FALSE, // flag for initial state
""); // pointer to event-object name if ( m_ov.hEvent == INVALID_HANDLE_VALUE )
{
// Handle the error.
ComAccess::ErrorToString("ReadData(): CreateEvent() failed");
return(-1);
} // Specify here the event to be enabled bSuccess = SetCommMask(m_hCom, EV_RXCHAR); if ( ! bSuccess )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("ReadData(): SetCommMask() failed");
return(-1);
}
// WaitForSingleObject bSuccess = WaitCommEvent(m_hCom, &mask, &m_ov); if ( ! bSuccess )
{
int err = GetLastError(); if ( err == ERROR_IO_PENDING)
{
result = WaitForSingleObject(m_ov.hEvent, dwMaxWait); //wait dwMaxWait
// milli seconds before returning
if ( result == WAIT_FAILED )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("ReadData(): WaitForSingleObject() failed");
return(-1);
}
}
}
// The specified event occured?
if ( mask & EV_RXCHAR)
{
bSuccess = ReadFile(m_hCom, // handle of file to read
pdest, // address of buffer that receives data
len, // number of bytes to read
&read, // address of number of bytes read
&m_ov); // address of structure for data if ( ComAccess::IsNT() )
{
bSuccess = GetOverlappedResult(m_hCom, &m_ov, &read, TRUE); if ( ! bSuccess )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("WriteData(): GetOverlappedResult() failed"); return(-1);
}
}
else
if ( ! bSuccess )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("ReadData(): ReadFile() failed"); return(-1);
}
}
else
{
// Handle the error.
CloseHandle(m_ov.hEvent);
wsprintf(m_lpszErrorMessage, "Error ReadData(): No EV_RXCHAR occured\n"); return(-1);
}
CloseHandle(m_ov.hEvent);
return read;
}////////////////////////////////////////////////////////////////////////////////////////
//
// Function: ErrorToString(LPCSTR lpszMessage)
//
// Return value: VOID
//VOID ComAccess::ErrorToString(LPCSTR lpszMessage)
{
LPVOID lpMessageBuffer;
DWORD error = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, // source and processing options
NULL, // pointer to message source
error, // requested message identifie
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // the user default language.
(LPTSTR) &lpMessageBuffer, // pointer to message buffer
0, // maximum size of message buffer
NULL); // address of array of message inserts // and copy it in our error string
wsprintf(m_lpszErrorMessage,"%s: (%d) %s\n", lpszMessage, error, lpMessageBuffer); LocalFree(lpMessageBuffer);
}////////////////////////////////////////////////////////////////////////////////////////
//
// Function: IsNT(VOID)
//
// Return value: BOOL True or False
//BOOL ComAccess::IsNT(VOID)
{
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi); if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
return TRUE;
}
else
{
return FALSE;
}
}
跟我的程序差不多啊。
我的也能在2000下用,
98我也没特意去试过。
我看程序是没什么问题,
发现设置 DCB结构的时候,最后一个参数要去调,
else
if ( len != written )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
CString msg_1;
msg_1.Format ("len is %d, written is %d",len,written);
ComAccess::ErrorToString(msg_1);
return(-1);
}
如果发送8个字节,则len为8,而written实际写入串口的数据为0,但对方已经接收到数据的。我强制将written默认为8,但读的时候还是有问题。
void CMotorCtrlPanelView::SendUsart(BYTE oprcode, UINT addr, UINT data)
{
ComAccess * com;
CString msg;
unsigned char TxUsartData[10];
unsigned char RxUsartData[20];
int send_result;
int read_result;
WORD textlen;
INT16 temp;
*TxUsartData = 0xFF;
*(TxUsartData + 1) = oprcode;
temp.intall = addr;
*(TxUsartData + 2) = temp.intbyte .HighByte;
*(TxUsartData + 3) = temp.intbyte .LowByte;
temp.intall = data;
*(TxUsartData + 4) = temp.intbyte .HighByte ;
*(TxUsartData + 5) = temp.intbyte .LowByte ;
reg_crc=0xffff;
for(int i=0; i<6; i++)
{
crc_chk(*(TxUsartData + i));
}
temp.intall = reg_crc;
*(TxUsartData + 6) = temp.intbyte .LowByte ;
*(TxUsartData + 7) = temp.intbyte .HighByte ;
if ( ! (com = new ComAccess()) )
{
msg.Format("*** Error: Not enough memory to create ComAccess object!\n");
textlen = m_out_msg.GetWindowTextLength ();
m_out_msg.SetSel (textlen,textlen);
m_out_msg.ReplaceSel (msg);
return;
}
if(!com->Open ("com1", CBR_9600, NOPARITY, TWOSTOPBITS, 8))
{
msg.Format ("*** Error: Can't open communication device!\n", "%s", com->GetErrorMessage());
textlen = m_out_msg.GetWindowTextLength ();
m_out_msg.SetSel (textlen,textlen);
m_out_msg.ReplaceSel (msg);
delete com;
return;
}
send_result = com->WriteData(TxUsartData, 8);
if ( send_result < 0 )
{
msg.Format ("*** Error: %s\n", com->GetErrorMessage ());
textlen = m_out_msg.GetWindowTextLength ();
// m_out_msg.SetFocus ();
m_out_msg.SetSel (textlen,textlen);
m_out_msg.ReplaceSel (msg);
}
else
{
msg.Format ("Waiting...");
textlen = m_out_msg.GetWindowTextLength ();
m_out_msg.SetSel (textlen,textlen);
m_out_msg.ReplaceSel (msg);
TxMsgCount ++;
}
read_result = com->ReadData(RxUsartData, 20);
if ( (read_result < 0) )
{
msg.Format ("*** Error:%s\n", com->GetErrorMessage());
textlen = m_out_msg.GetWindowTextLength ();
m_out_msg.SetSel (textlen,textlen);
m_out_msg.ReplaceSel (msg); msg.Format ("*** Error: Operation is failed!\n");
textlen = m_out_msg.GetWindowTextLength ();
m_out_msg.SetSel (textlen,textlen);
m_out_msg.ReplaceSel (msg);
}
else
{
msg.Format ("Operation is successed!");
textlen = m_out_msg.GetWindowTextLength ();
m_out_msg.SetSel (textlen,textlen);
m_out_msg.ReplaceSel (msg); // process the status
}
// close communication device
com->Close();
// destruct the communication device object and free memory
delete com;
}
这个真搞不懂?你说的 written为8,为什么 len 还是不等于written
是不是len 有问题??
else
if ( len != written )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
CString msg_1;
msg_1.Format ("len is %d, written is %d",len,written);
ComAccess::ErrorToString(msg_1);
return(-1);
}
这段代码,而且很多代码例程里面都没有这段代码的。
但是在98下面依然读不到数据,代码会进入这里:
else
if ( ! bSuccess )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("ReadData(): ReadFile() failed"); return(-1);
}
我依然屏蔽掉这段代码,但数据没有读到。
WIN2000下面是没有问题的。
但读数据还是有问题!
m_ov.hEvent = CreateEvent(NULL, // pointer to security attributes
FALSE, // flag for manual-reset event
FALSE, // flag for initial state
""); // pointer to event-object name