class DCommPort
{
public:
HANDLE m_hComm;
HANDLE m_ExitThreadEvent;//串口接收线程退出事件
char *m_pRecvBuffer;
int m_recvBufferLenth;
CWnd * m_ownerDlg;
BOOL InitCommTimeouts();//设置超时参数
BOOL InitDCB();//配置串口
BOOL InitDCB(int portRate);
BOOL m_bConnected;
BOOL ClosePort(void);//关闭串口
UINT WritePort(UCHAR *buf,UINT dwBytesToWrite);//写数据
BOOL OpenPort(CString lpszPortName);//打开串口
BOOL OpenPort(CString lpszPortName, CWnd * owner, int portRate);
DCommPort();
HANDLE m_hReadThread;
virtual ~DCommPort();
};
#include "StdAfx.h"
#include "DCommPort.h"
#include "winbase.h"
BOOL DCommPort::InitCommTimeouts()
{
COMMTIMEOUTS CommTimeouts;
DWORD dwError;
//得到超时参数
GetCommTimeouts (m_hComm, &CommTimeouts);
//改变COMMTIMEOUTS结构设置
CommTimeouts.ReadIntervalTimeout = 100;
CommTimeouts.ReadTotalTimeoutMultiplier = 1;
CommTimeouts.ReadTotalTimeoutConstant = 100;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 0;
//设置端口超时值
if (!SetCommTimeouts (m_hComm, &CommTimeouts))
{
//不能设置超时值
MessageBox (NULL, TEXT("Unable to set the time-out parameters"),
TEXT("Error"), MB_OK);
dwError = GetLastError ();
return FALSE;
}
return TRUE;
}
BOOL DCommPort::InitDCB()//默认9600, 无奇偶校验
{
DCB PortDCB;
DWORD dwError;
PortDCB.DCBlength = sizeof (DCB);
//得到端口的默认设置信息
GetCommState (m_hComm, &PortDCB);
//改变DCB结构设置
PortDCB.BaudRate = 9600; //波特率
PortDCB.fBinary = TRUE; //Win32不支持非二进制串行传输模式,必须为TRUE
PortDCB.fParity = TRUE; //启用奇偶校验
//PortDCB.fOutxCtsFlow = TRUE; //串行端口的输出由CTS线控制
//PortDCB.fOutxDsrFlow = FALSE; //关闭串行端口的DSR流控制
//PortDCB.fDtrControl = DTR_CONTROL_ENABLE; //启用DTR线
//PortDCB.fDsrSensitivity = FALSE; //如果设为TRUE将忽略任何输入的字节,除非DSR线被启用
//PortDCB.fTXContinueOnXoff = TRUE; //当为TRUE时,如果接收缓冲区已满且驱动程序已传送XOFF字符,将使驱动程序停止传输字符
//PortDCB.fOutX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输出
//PortDCB.fInX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输入
//PortDCB.fErrorChar = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
//PortDCB.fNull = FALSE; //设为TRUE将使串行驱动程序忽略收到的空字节
//PortDCB.fRtsControl = RTS_CONTROL_ENABLE; //启用RTS线
//PortDCB.fAbortOnError = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.ByteSize = 8; //每字节的位数
PortDCB.Parity = NOPARITY; //无奇偶校验
PortDCB.StopBits = ONESTOPBIT; //每字节一位停止位
//根据DCB结构配置端口
if (!SetCommState (m_hComm, &PortDCB))
{
//不能配置串行端口
MessageBox (NULL, TEXT("Unable to configure the serial port"),
TEXT("Error"), MB_OK);
dwError = GetLastError ();
return FALSE;
}
return TRUE;
}
BOOL DCommPort::InitDCB( int portRate )
{
DCB PortDCB;
DWORD dwError;
PortDCB.DCBlength = sizeof (DCB);
//得到端口的默认设置信息
GetCommState (m_hComm, &PortDCB);
//改变DCB结构设置
PortDCB.BaudRate = portRate; //波特率
PortDCB.fBinary = TRUE; //Win32不支持非二进制串行传输模式,必须为TRUE
PortDCB.fParity = TRUE; //启用奇偶校验
//PortDCB.fOutxCtsFlow = FALSE; //关闭串行端口的输出由CTS线控制
//PortDCB.fOutxDsrFlow = FALSE; //关闭串行端口的DSR流控制
//PortDCB.fDtrControl = DTR_CONTROL_ENABLE; //启用DTR线
//PortDCB.fDsrSensitivity = FALSE; //如果设为TRUE将忽略任何输入的字节,除非DSR线被启用
//PortDCB.fTXContinueOnXoff = FALSE; //当为TRUE时,如果接收缓冲区已满且驱动程序已传送XOFF字符,将使驱动程序停止传输字符
//PortDCB.fOutX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输出
//PortDCB.fInX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输入
//PortDCB.fErrorChar = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
//PortDCB.fNull = FALSE; //设为TRUE将使串行驱动程序忽略收到的空字节
//PortDCB.fRtsControl = RTS_CONTROL_ENABLE; //启用RTS线
//PortDCB.fAbortOnError = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.ByteSize = 8; //每字节的位数
PortDCB.Parity = NOPARITY; //无奇偶校验
PortDCB.StopBits = ONESTOPBIT; //每字节一位停止位
//根据DCB结构配置端口
if (!SetCommState (m_hComm, &PortDCB))
{
//不能配置串行端口
MessageBox (NULL, TEXT("Unable to configure the serial port"),
TEXT("Error"), MB_OK);
dwError = GetLastError ();
return FALSE;
}
return TRUE;
}
UINT DCommPort::WritePort( UCHAR *buf,UINT dwBytesToWrite )
{
BOOL fWriteState;
DWORD dwBytesWritten = 0;
if (m_hComm == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("串口未打开!"));
return 0;
}
// for (UINT i = 0; i < dwBytesWritten; i++)
// {
// fWriteState=WriteFile(m_hComm,&buf[i], 1, &dwBytesWritten, NULL);
// }
//写入数据
fWriteState=WriteFile(m_hComm,buf,dwBytesToWrite,&dwBytesWritten,NULL);
return dwBytesWritten;
}
BOOL DCommPort::OpenPort( CString lpszPortName, CWnd * owner, int portRate )
{
DWORD dwThreadID;
m_ownerDlg = owner;
if (m_pRecvBuffer != NULL)
{
delete m_pRecvBuffer;
m_pRecvBuffer = NULL;
}
m_pRecvBuffer = new char[256];
// 打开串口
m_hComm = CreateFile(lpszPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
if(m_hComm == INVALID_HANDLE_VALUE)
{
//不能打开端口
CString strError;
strError.Format(_T("Unable to open %s, Error No.=%d"),
lpszPortName, GetLastError());
AfxMessageBox(strError);
return FALSE;
}
//串口事件:接收到一个字符
SetCommMask(m_hComm, EV_RXCHAR);
//分配设备缓冲区
SetupComm(m_hComm, 256, 256);
//配置串行端口
if(!InitDCB(portRate))
{
CString strError;
strError.Format(_T("Unable to initDCB, Error No.=%d"), GetLastError());
AfxMessageBox(strError);
return FALSE;
}
//设置端口超时值
if(!InitCommTimeouts())
{
CString strError;
strError.Format(_T("Unable to InitCommTimeouts, Error No.=%d"), GetLastError());
AfxMessageBox(strError);
return FALSE;
}
//初始化缓冲区中的信息
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
//设置端口上指定信号的状态
// SETDTR: 发送DTR (data-terminal-ready)信号
// SETRTS: 发送RTS (request-to-send)信号
//EscapeCommFunction (m_hComm, SETDTR);
//EscapeCommFunction (m_hComm, SETRTS);
//创建串口接收线程退出事件
m_ExitThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//创建一个从串口读取数据的线程
if (m_hReadThread = CreateThread (NULL, 0, ReadPortThread, this, 0,
&dwThreadID))
{
//donothing
}
else
{
//不能创建线程
CString strError;
strError.Format(_T("Unable to CreateRecvThread, Error No.=%d"), GetLastError());
AfxMessageBox(strError);
return FALSE;
}
m_bConnected=TRUE;
return TRUE;
}
DCommPort::DCommPort()
{
m_hComm = INVALID_HANDLE_VALUE;
m_pRecvBuffer = NULL;
}
DCommPort::~DCommPort()
{
if(m_hComm != INVALID_HANDLE_VALUE)
ClosePort();
}
应用就是
DCommPort port;
port.OpenPort(_T("COM1:"), this, 9600);
UCHAR sTemp[10] = {1,2,3,4,5,6,7,8,9,0};
port.WritePort(sTemp, 10);
然后跟了 一下就是writefile那个地方就死住了,writefile函数不返回。
我没做过wince。临时抱佛脚,不太知道机制有什么不同,大家指点一下吧!
这个已经是从网上扒的了,还有什么地方不对,或者需要注意吗?
------解决思路----------------------
代码太长了
------解决思路----------------------
代码凌乱又不完整,而且写的像是习惯c的人硬弄个类出来。看不下去。
------解决思路----------------------
Wince下的串口编程都是标准的接口,你上各大核心板/开发板供应商网站下个光盘资料,里头的Demo直接用。