#include "StdAfx.h"
#include "Comm_C.h"
Comm_C::Comm_C():rec_flag(0),strbuf("")
{
}
Comm_C::~Comm_C(void)
{
}
void Comm_C::Init_Comm(TCHAR *portname,int BaudRate)
{
OpenPort(portname);
SetPortConfig(BaudRate);
old_m_ov = m_ov;
m_ov.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//不明觉厉!!!
Open_rec_Thread();
InitializeCriticalSection(&g_cs); //使用前必须初始化
}
void Comm_C::Close_Comm()
{
m_ov = old_m_ov;
CloseHandle(hComm);//很重要!!
Close_rec_Thread();
DeleteCriticalSection(&g_cs);
}
bool Comm_C::OpenPort(TCHAR *portname)
{
hComm = CreateFile(portname, //串口号
GENERIC_READ | GENERIC_WRITE, //允许读写
0, //通讯设备必须以独占方式打开
0, //无安全属性
OPEN_EXISTING, //通讯设备已存在
FILE_FLAG_OVERLAPPED, //异步I/O
0); //通讯设备不能用模板打开
if (hComm == INVALID_HANDLE_VALUE)
{
CloseHandle(hComm);
AfxMessageBox(_T("串口打开失败,请保证串口是否被占用!"));
return FALSE;
}
else
return true;
}
bool Comm_C::SetPortConfig(int rate_arg,//波特率 19200
int Parity_width,//奇偶校验位 0
int data_width,//数据位 8
int stop_width)//停止位 1
{
DCB dcb;
memset(&dcb,0,sizeof(dcb));
if(!GetCommState(hComm,&dcb))//获取当前DCB配置
{
AfxMessageBox(_T("串口属性设置失败,请重试!"));
return FALSE;
}
// set DCB to configure the serial port
dcb.DCBlength = sizeof(dcb); //DCB结构体大小
/* ---------- Serial Port Config ------- */
dcb.BaudRate = rate_arg; //波特率
//波特率修改失败时在这里加断点!!!!!很神奇的说!!!
dcb.Parity = Parity_width;//奇偶校验
dcb.fParity = 0; //是否进行奇偶校验
dcb.StopBits = stop_width; //停止位数
dcb.ByteSize = data_width;//数据宽度,一般为8
dcb.fOutxCtsFlow = 0;//CTS线上的硬件握手
dcb.fOutxDsrFlow = 0; //DSR线上的硬件握手
dcb.fDtrControl = DTR_CONTROL_DISABLE;//DTR控制
dcb.fDsrSensitivity = 0;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fOutX = 0;//是否使用XON/XOFF协议
dcb.fInX = 0; //是否使用XON/XOFF协议
/* ----------------- misc parameters ----- */
dcb.fErrorChar = 0;//发送错误协议
dcb.fBinary = 1;
dcb.fNull = 0;
dcb.fAbortOnError = 0;
dcb.wReserved = 0;
dcb.XonLim = 2;
dcb.XoffLim = 4;
dcb.XonChar = 0x13;
dcb.XoffChar = 0x19;
dcb.EvtChar = 0;
// set DCB
if(!SetCommState(hComm,&dcb))
{
AfxMessageBox(_T("串口属性设置失败,请重试!"));
return false;
}
//else
// AfxMessageBox(_T("串口属性设置成功!"));
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout=MAXDWORD;
timeouts.ReadTotalTimeoutConstant=0;
timeouts.ReadTotalTimeoutMultiplier=0;
timeouts.WriteTotalTimeoutConstant=50;
timeouts.WriteTotalTimeoutMultiplier=2000;
if(!SetCommTimeouts(hComm, &timeouts))//设置串口通信事件。
{
AfxMessageBox(_T("串口通信事件设置失败,请重试!"));
return false;
}
SetCommMask(hComm, EV_RXCHAR); //当有字符在inbuf中时产生这个事件
PurgeComm(hComm,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|PURGE_TXABORT);//清除串口的所有操作
//AfxMessageBox(_T("操作成功!"));
return true;
}
void Comm_C::usart_sendbyte(byte msg)
{
BOOL bWrite = TRUE;
BOOL bResult = TRUE;
DWORD BytesSent = 0;
byte* Pmsg= &msg;
//HANDLE m_hWriteEvent;
//ResetEvent(m_hWriteEvent);//有个啥用
EnterCriticalSection(&g_cs);
if (bWrite)
{
m_ov.Offset = 0;
m_ov.OffsetHigh = 0;
// Clear buffer
bResult = WriteFile(hComm, // Handle to COMM Port
Pmsg, // Pointer to message buffer in calling finction
1, // Length of message to send
&BytesSent, // Where to store the number of bytes sent
&m_ov ); // Overlapped structure
if (!bResult)
{
DWORD dwError = GetLastError();
switch (dwError)
{
case ERROR_IO_PENDING:
{
// continue to GetOverlappedResults()
BytesSent = 0;
bWrite = FALSE;
break;
}
default:
{
// all other error codes
//ProcessErrorMessage("WriteFile()");
AfxMessageBox(_T("WriteFile()!"));
}
}
}
} // end if(bWrite)
if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult(hComm, // Handle to COMM port
&m_ov, // Overlapped structure
&BytesSent, // Stores number of bytes sent
TRUE); // Wait flag
// deal with the error code
if (!bResult)
{
//ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
AfxMessageBox(_T("GetOverlappedResults() in WriteFile()!"));
}
} // end if (!bWrite)
// Verify that the data size send equals what we tried to send
if (BytesSent != 1)
{
AfxMessageBox(_T("WARNING: WriteFile() error.. !"));
//printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)m_szWriteBuffer));
}
LeaveCriticalSection(&g_cs);
}
byte Comm_C::Thread_usart_receivebyte()
{
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
for (;;)
{
EnterCriticalSection(&g_cs);
bResult = ClearCommError(hComm, &dwError, &comstat);
LeaveCriticalSection(&g_cs);
if (comstat.cbInQue == 0)
continue;
EnterCriticalSection(&g_cs);
if (bRead)
{
byte* pRXBuff = new byte[comstat.cbInQue];
bResult = ReadFile(hComm, // Handle to COMM port
pRXBuff, // RX Buffer Pointer
comstat.cbInQue, // Read one byte
&BytesRead, // Stores number of bytes read
&m_ov); // pointer to the m_ov structure
if (!bResult)
{
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING:
{
bRead = FALSE;
break;
}
default:
{
break;
}
}
}
else
{
bRead = TRUE;
for (int i=0;i!=comstat.cbInQue;i++)
vec_byte.push_back(pRXBuff[i]);
delete []pRXBuff;
}
} // close if (bRead)
if (!bRead)
{
bRead = TRUE;
bResult = GetOverlappedResult(hComm, // Handle to COMM port
&m_ov, // Overlapped structure
&BytesRead, // Stores number of bytes read
TRUE); // Wait flag
}
LeaveCriticalSection(&g_cs);
}
}
DWORD WINAPI Comm_C::rec_Thread(LPVOID LParameter)
{
while ((((Comm_C*)LParameter)->hComm) != INVALID_HANDLE_VALUE)
{
((Comm_C*)LParameter) -> Thread_usart_receivebyte();//注意优先级!!!
}
return 0;
}
byte Comm_C::usart_receivebyte()
{
while(vec_byte.empty());
EnterCriticalSection(&g_cs);
tmp = vec_byte[0];
vec_byte.erase(vec_byte.begin());
LeaveCriticalSection(&g_cs);
return tmp;
return NULL;
}
bool Comm_C::Open_rec_Thread()
{
rec_hComm = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)rec_Thread,(LPVOID)this,0,NULL);
return 1;
}
bool Comm_C::Close_rec_Thread()
{
TerminateThread(rec_hComm,0x00);//结束线程
return 1;
}