串口设置的可能的顺序:
1.打开端口,CreateFile();
[获取当前串口状态到DCB结构中,GetCommState(hcom,&config_);][DCB,串行通信设备控制设置的定义]
2.配置DCB,设备控制块,结构数据.
3.设置串口超时结构构成员。
4.设置串口,SetupComm(); [为指定的通信设备,初始化通信参数]
5.设置串口状态, SetCommState(); [据设备控制块,配置通信设备。重新初始化所有硬件与控制设置,但不清空队列]
6.设置串口超时值, SetCommTimeouts();
7.清空串口缓存, PurgeComm(); [废弃所有输入、输出缓冲中的字符,对于特定的通信资源,终止未完成的读写操作。]
8.往串口写数据, WriteFile();
9.关闭串口, CloseHandle();
[12.15,2010]
----------------------------------------------------------------------------------------------------------------------
#include<windows.h>
#include<iostream>
#include<tchar.h>
//填充配置数据到缓冲区中
void coverConfig(BYTE *outData)
{
HANDLE hFile;
hFile=CreateFile(_T("F://workcode//2008cplus//sendRs232c//calibaration.cfg"),
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
LONG IDistance=0;
DWORD dwPtr = SetFilePointer(hFile,IDistance,NULL,FILE_BEGIN);
DWORD dwAppend=1038;
DWORD dwFileSize;
ReadFile(hFile,outData,dwAppend,&dwFileSize,NULL);
//WriteFile(hFile,outData,dwAppend,&dwFileSize,NULL);
}
void SetDCB(struct _DCB *config_)
{
DWORD BaudRate=115200; //波特率
BYTE StopBits=0; // one stopbit
BYTE Parity=NOPARITY;
BYTE ByteSize=8;
config_->fBinary= 1; //must be true
config_->fParity=1; //执行校验位,报告错误
config_->fOutxCtsFlow=1; //监控"清除发送"信号
config_->fOutxDsrFlow=1; //监控"数据设置准备",DSR,信号
config_->fDtrControl=DTR_CONTROL_ENABLE; //DTR,数据终端准备,流控制
config_->fDsrSensitivity=FALSE; //对"数据设置准备"信号敏感
config_->fTXContinueOnXoff=FALSE; //关于XoffLim的反应。
config_->fErrorChar=FALSE; //字节接收带着检验错误指示符
config_->fNull=FALSE; //空字节被丢弃,when true
config_->fRtsControl=RTS_CONTROL_ENABLE; //启用RTS,请求发送,
config_->fAbortOnError=FALSE; //发生错误就终止传输
config_->fDummy2=0;
config_->wReserved=0;
config_->DCBlength= sizeof(config_); //28 字节
config_->BaudRate= BaudRate;
config_->Parity= Parity; //no parity
config_->ByteSize= ByteSize; //in off byte size
config_->StopBits= StopBits;
config_->fOutX= 1; //启用xon/xoff控制,用于传输
config_->fInX= 1; //用于接收
config_->XonLim= 2048;//充许的最小的缓冲区大小
config_->XoffLim= 2048;//充许的最大的缓冲区大小
config_->XonChar= 17; //传输与发送时用的XON值
config_->XoffChar= 19;//----------------XOFF值
config_->ErrorChar=0; //用于替换带有校验错误字节的字符值
config_->EofChar=0; //表示数据结束的字符的值。
config_->EvtChar=0; //发送事件信号的字符的值
config_->wReserved1=0;
}
void OpenComm(HANDLE * hcom)
{
*hcom=CreateFile(_T("com1"),
GENERIC_READ|GENERIC_WRITE,
0,//不共享
NULL, //默认安全设置
OPEN_EXISTING, //打开存在的端口
FILE_ATTRIBUTE_NORMAL,
//FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //default
NULL); //default
}
//设置并口超时
void SetCommTimeouts(COMMTIMEOUTS *comTimeOut)
{
comTimeOut->ReadIntervalTimeout=0xFFFFFFFF; // 接收时,两字符间最大的时延
comTimeOut->ReadTotalTimeoutMultiplier=0; // 读取每字节的超时
comTimeOut->ReadTotalTimeoutConstant=1000;
// 读串口数据的固定超时
// 总超时 = ReadTotalTimeoutMultiplier * 字节数 + ReadTotalTimeoutConstant
comTimeOut->WriteTotalTimeoutConstant=0;
comTimeOut->WriteTotalTimeoutMultiplier=2*CBR_9600/115200;
}
int main()
{
HANDLE hcom;
OpenComm(&hcom);
if(hcom==INVALID_HANDLE_VALUE)
{
std::cout<<"cannot open the commPort!"<<std::endl;
return FALSE;
}
DCB config_;
ZeroMemory(&config_,sizeof(config_));
//获取已有的串口状态
if(GetCommState(hcom,&config_)==0) //status ok
{
printf("Get configuration port has problem./n");
return false;
}
SetDCB(&config_);
/*COMMPROP comm1Prop;
GetCommProperties(hcom,&comm1Prop);*/
//------------------------------------------------------
COMMTIMEOUTS comTimeOut;
SetCommTimeouts(&comTimeOut);
BYTE outputData[1038];
//打开配置文件
coverConfig(outputData);
DWORD sizeBuffer=1038;
DWORD length=0;
DWORD status=0;
//initiating Comm
DWORD dwInQueue=1038, dwOutQueue=1038;
SetupComm(hcom,dwInQueue,dwOutQueue);
PurgeComm(hcom,PURGE_TXABORT|PURGE_TXABORT|PURGE_RXCLEAR|PURGE_TXCLEAR);
SetCommTimeouts(hcom,&comTimeOut);
if(SetCommState(hcom,&config_)==0)
{
printf("Set configuration port has problem./n");
DWORD CommStateSetError=GetLastError();
printf("SetCommStateError Code:%d/n",CommStateSetError);
return FALSE;
}
OVERLAPPED overlapped;
LPOVERLAPPED lpOverlapped=&overlapped;
ZeroMemory(lpOverlapped,sizeof(lpOverlapped));
/*lpOverlapped.Offset=0;
lpOverlapped.OffsetHigh=0;
lpOverlapped.hEvent=0;*/
if(status=WriteFile(hcom, //句柄
outputData, //数据缓冲区指针
sizeBuffer, //字节数
&length, //接收成功发送数据长度的指针
NULL
//lpOverlapped
)==0)
{
DWORD StatusWriteFile=GetLastError();
printf("Reading of serial communication has problem./n");
return false;
}
CloseHandle(hcom);
}
可能的问题:
1)串口打开函数,使用的参数不完全合适。
2)DCB,结构成员值设置不恰当。
3)写入串口函数不合适。
4)串口各设置函数使用不全或顺序不对。
问题是第二个。
串口传输时,影响重大的DCB成员:
1.StopBits
2.fOutxCtsFlow
3.fOutxDsrFlow
--------------------------------------------------------------------------------
串口写入时引起的窗口,无法结束,进程也无法杀死。分析:
这是因为本进程被挂起了,它在等待“数据集准备好” 或“清除以发送” 的信号,只有这两
信号才能使本进程继续执行或被杀死掉。否则它永远留在系统内存中。
结论:
系统级挂起方法能很好地防止本程序资源被销毁掉。