|
//打开串口
hPort=CreateFile(lpszPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
BOOL CSerial::InitDCB()
{
DCB PortDCB;//声明一个DCB结构
DWORD dwError;
PortDCB.DCBlength = sizeof (DCB); //初始化 DCBlength
GetCommState (hPort, &PortDCB); //得到端口的默认设置信息
//改变DCB结构设置
PortDCB.BaudRate =CBR_115200; //波特率
PortDCB.fBinary = TRUE; //Win32不支持非二进制串行传输模式,必须为TRUE
PortDCB.fParity = TRUE; //启用奇偶校验
PortDCB.fOutxCtsFlow = FALSE; //串行端口的输出由CTS线控制
PortDCB.fOutxDsrFlow = FALSE; //关闭串行端口的DSR流控制
PortDCB.fDtrControl = DTR_CONTROL_DISABLE; //启用DTR线
PortDCB.fDsrSensitivity = FALSE; //如果设为TRUE将忽略任何输入的字节,除非DSR线被启用
// PortDCB.fTXContinueOnXoff = TRUE; //当为TRUE时,如果接收缓冲区已满且驱动程序已传送XOFF字符,将使驱动程序停止传输字符
// PortDCB.fTXContinueOnXoff = FALSE;
PortDCB.fOutX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输出
PortDCB.fInX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输入
// PortDCB.fErrorChar = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
// PortDCB.fNull = FALSE; //设为TRUE将使串行驱动程序忽略收到的空字节
PortDCB.fRtsControl = RTS_CONTROL_DISABLE; //启用RTS线
PortDCB.fAbortOnError = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
PortDCB.ByteSize = 8; //每字节的位数
PortDCB.Parity = EVENPARITY; //偶校验
PortDCB.StopBits = ONESTOPBIT; //每字节一位停止位
//根据DCB结构配置端口
if (!SetCommState (hPort, &PortDCB))
{ //不能配置串行端口
MessageBox (NULL, TEXT("Unable to configure the serial port!"), TEXT("Error!"), MB_OK);
dwError = GetLastError (); //获得错误原因的代码
return FALSE;
}
return TRUE;
}
BOOL CSerial::InitCommTimeouts()
{
COMMTIMEOUTS CommTimeouts; //声明一个COMMTIMEOUTS结构
DWORD dwError;
//得到超时参数
GetCommTimeouts (hPort, &CommTimeouts);
//改变COMMTIMEOUTS结构设置
//不使用这个逾时功能,ReadFile直到所有字符接收完才会返回
CommTimeouts.ReadIntervalTimeout = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
//不使用这个逾时功能,WriteFile直到所有字符接收完才会返回
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant=0;
if (!SetCommTimeouts(hPort,&CommTimeouts)) //设置端口超时值
{ //不能设置超时值
MessageBox (NULL, TEXT("Unable to set the time-out parameters!"),TEXT("Error!"), MB_OK);
dwError = GetLastError (); //获得错误原因的代码
return FALSE;
}
return TRUE;
}
DWORD CSerial::WritePort(byte *buf,DWORD dwCharToWrite)
{
BOOL fWriteState;
DWORD dwBytesWritten;
//写入数据
// PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
//PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);
fWriteState=WriteFile(hPort,buf,dwCharToWrite,&dwBytesWritten,NULL);
if(!fWriteState) //不能写数据
{
MessageBox(NULL,TEXT("You can't write the data to the port!"),TEXT("Error!"),MB_OK);
dwBytesWritten=0;
}
//PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
//PurgeComm(hPort,PURGE_TXCLEAR);
return dwBytesWritten;
}
DWORD WINAPI ReadPortThread(LPVOID lpvoid)
{
BOOL fReadState; //读入信息时返回值,若为TRUE就是正确读入
DWORD dwCommModemStatus; //串口状态,以判断是否有事件发生
DWORD dwLength; //读入信息的长度
COMSTAT ComStat; //串口状态的详细情况表,
DWORD dwErrorFlags; //读串口状态的标志
BOOL readStatus=FALSE; //读入信息的状态,若为TRUE就是正在读入但还没有读完
int iCounter=0;
DWORD dwBytes;
byte Byte;
SetCommMask(hPort,EV_RXCHAR); //设置程序响应的事件
PurgeComm(hPort,PURGE_RXCLEAR|PURGE_TXCLEAR); //清空串口的接收缓冲区,必要性不大,但有保证作用
//ClearCommError(hPort,&dwErrorFlags,&ComStat); //清除串口状态标志,并返回当前状态
while (hPort != INVALID_HANDLE_VALUE) //程序在串口有效的状态下,无限循环
{
if(WaitCommEvent(hPort, &dwCommModemStatus,0)) //等待串口的事件发生,当dwCommModemStatus值为1时表示接收到数据
{
SetCommMask (hPort, EV_RXCHAR); //重新设置程序响应的事件,但这个只是保证程序的安全性,一般并不起作用
if (dwCommModemStatus & EV_RXCHAR) //检测收到的事件是否为"接收字符"的事件
{
ClearCommError(hPort,&dwErrorFlags,&ComStat); //清除串口状态标志,并返回当前状态
dwLength=ComStat.cbInQue; //cbInQue返回在串行驱动程序输入队列中的字符数
if(dwLength>0)//防止无故产生事件
{
//从串口读取数据
//读入数据,并返回数据长度,采用同步方式
if(dwLength<10240)
{
fReadState=ReadFile(hPort,&fbuf[0],dwLength,&dwLength,NULL);
if(!fReadState)
{
MessageBox(NULL,TEXT("Can't fetch the data!"),TEXT("Reading Error!"),MB_OK); //不能从串口读取数据
}
else
{
//ProcessReceive((WPARAM)dwLength,(LPARAM)fbuf);
::SendMessage(m_hWnd,WM_COMM_RCHAR2,(WPARAM)dwLength,(LPARAM)fbuf); //通知主窗口数据已经得到可以处理
}
}
else//当缓存溢出就处理读掉
{
DWORD j=dwLength%10240;
for(int i=0;i
fReadState=ReadFile(hPort,&fbuf[0],dwLength,&dwLength,NULL);
fReadState=ReadFile(hPort,&fbuf[0],j,&j,NULL);
}
}
}
}
// PurgeComm(hPort,PURGE_RXCLEAR);//清空串口的接收缓冲区,必要性不大,但有保证作用
//重新获得串口状态,必要性不大,48表示没有事件产生
GetCommModemStatus (hPort, &dwCommModemStatus);
}
return 0;
}
自己把这几个函数研究下 基本串口能实现 传输了 |
|