根据上位机项目需求,需实现定时500ms发送数据帧的功能。目前使用定时器函数(SetTimer、KillTimer及Windows消息OnTimer)定时500ms,分别用同步、异步及MSComm控件三种方式实现发送及接收功能。
关键函数整理如下:
一、异步方式
a、串口初始化
DWORD dwError;
hCom=CreateFile( "COM4",
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
//FILE_ATTRIBUTE_NORMAL,//同步方式
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式
0);
if (hCom == INVALID_HANDLE_VALUE)
{
MessageBox(_T("ERROR1"));
dwError=GetLastError();
return FALSE;
}
dcb.DCBlength=sizeof(DCB);
GetCommState(hCom,&dcb);
dcb.BaudRate=38400; //波特率为9600
dcb.ByteSize=8; //每个字节有8位
dcb.Parity=NOPARITY; //无奇偶校验位
dcb.StopBits=ONESTOPBIT; //两个停止位
if(!SetCommState(hCom,&dcb))
{
MessageBox(_T("ERROR2"));
dwError=GetLastError();
return FALSE;
}
SetupComm(hCom,2048,2048); //输入缓冲区和输出缓冲区的大小都是1024
//设置超时
GetCommTimeouts(hCom,&TimeOuts);
//设定读超时
TimeOuts.ReadIntervalTimeout=100;
TimeOuts.ReadTotalTimeoutMultiplier=1;
TimeOuts.ReadTotalTimeoutConstant=100;
//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier=1;
TimeOuts.WriteTotalTimeoutConstant=200;
if(!SetCommTimeouts(hCom,&TimeOuts))
{
MessageBox(_T("ERROR3"));
dwError=GetLastError();
return FALSE;
}
b、发送函数
bool SIMULATION::UartWrite(unsigned char buffer[], DWORD dwBytesWritten)
{
DWORD dwErrorFlags;
COMSTAT ComStat;
OVERLAPPED m_osWrite;
BOOL bWriteStat;
memset(&m_osWrite,0,sizeof(OVERLAPPED));
m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
ClearCommError(hCom,&dwErrorFlags,&ComStat);
bWriteStat=WriteFile(hCom,buffer,dwBytesWritten,&dwBytesWritten,&m_osWrite);
if(!bWriteStat)
{
if(GetLastError()==ERROR_IO_PENDING)
{
WaitForSingleObject(m_osWrite.hEvent,200);
PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
return TRUE;
}
return FALSE;
}
PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
return FALSE;
}
c、接收函数
bool SIMULATION::UartRead(unsigned char buffer[], DWORD dwBytesRead)
{
//异步读串口的示例代码:
COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL bWriteStat;
DWORD dwError;
memset(&m_osRead,0,sizeof(OVERLAPPED));
m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
ClearCommError(hCom,&dwErrorFlags,&ComStat);
BOOL bReadStatus=ReadFile(hCom,buffer,dwBytesRead,&dwBytesRead,&m_osRead);
if(!bReadStatus)
{
if(GetLastError()==ERROR_IO_PENDING)
{
//WaitForSingleObject(m_osRead.hEvent,100);
GetOverlappedResult(hCom,&m_osRead,&dwBytesRead,TRUE);
PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
if(dwBytesRead>0)
return TRUE;
}
}
PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
return FALSE;
}
硬件实测定时器时间间隔为513ms左右。无法解决。