VC实现串口通信例程 作者:阮帮秋[2]

[入库:2005年8月18日] [更新:2007年3月27日]

本文简介:选择自 candycat 的 blog

  dword readtotaltimeoutmultiplier;
  dword readtotaltimeoutconstant;
  dword writetotaltimeoutmultiplier;
  dword writetotaltimeoutconstant;
  } commtimeouts,*lpcommtimeouts;
  区间超时:(仅对从端口中读取数据有用)它指定在读取两个字符之间要经历的时间
  总超时: 当读或写特定的字节数需要的总时间超过某一阈值时,超时触发.
  超时公式:
  readtotaltimeout = (readtotaltimeoutmultiplier * bytes_to_read)
  + readtotaltimeoutconstant
  writetotaltimeout = (writetotaltimeoutmuliplier * bytes_to_write)
  + writetototaltimeoutconstant
  note:在设置超时时参数0为无限等待,既无超时
  参数maxdword为立即返回
  超时设置:
  getcommtimeouts(hcomm,&timeouts);
  setcommtimeouts(hcomm,&timeouts);

10.查询方式读写数据

  例程:
  commtimeouts to;
  dword readthread(lpdword lpdwparam)
  {
  byte inbuff[100];
  dword nbytesread;
  if(!(cp.dwprovcapabilities&pcf_inttimeouts))
  return 1l;
  memset(&to,0,sizeof(to));
  to.readintervaltimeout = maxdword;
  setcommtimeouts(hcomm,&to);
  while(breading)
  {
  if(!readfile(hcomm,inbuff,100,&nbytesread,null))
  locprocesscommerror(getlasterror());
  else
  if(nbytesread)
  locprocessbytes(inbuff,nbytesread);
  }
  purgecomm(hcomm,purge_rxclear);
  return 0l;
  }
  note:
  purgecomm()是一个清除函数,它可以中止任何未决的后台读或写,并且可以冲掉i/o缓冲区.
  bool purgecomm(handle hfile,dword dwflags);
  dwflages的有效值:
  purge_txabort: 中止后台写操作
  pruge_rxabort: 中止后台读操作
  pruge_txclear: 清除发送缓冲区
  pruge_rxclear: 清除接收缓冲区
  技巧:
  可通过clearcommerror()来确定接收缓区中处于等待的字节数。
  bool clearcommerror(
  handle hfile, // handle to communications device
  lpdword lperrors, // pointer to variable to receive error codes
  lpcomstat lpstat // pointer to buffer for communications status
  );
  clearcommerror()将返回一个comstat结构:
  typedef struct _comstat { // cst
  dword fctshold : 1; // tx waiting for cts signal
  dword fdsrhold : 1; // tx waiting for dsr signal
  dword frlsdhold : 1; // tx waiting for rlsd signal
  dword fxoffhold : 1; // tx waiting, xoff char rec`d
  dword fxoffsent : 1; // tx waiting, xoff char sent
  dword feof : 1; // eof character sent
  dword ftxim : 1; // character waiting for tx
  dword freserved : 25; // reserved
  dword cbinque; // bytes in input buffer
  dword cboutque; // bytes in output buffer
  } comstat, *lpcomstat;
  其中的cbinque和cboutque中即为缓冲区字节。

11.同步i/o读写数据

  commtiomouts to;
  dword readthread(lpdword lpdwparam)
  {
  byte inbuff[100];
  dword nbyteread,dwerrormask,ntoread;
  comstat comstat;
  if(!cp.dwprovcapabilities&pcf_totaltimeouts)
  return 1l;
  memset(&to,0,sizeof(to));
  to.readtotaltimeoutmultiplier = 5;
  to.readtotaltimeoutconstant = 50;
  setcommtimeouts(hcomm,&to);
  while(breading)
  {
  clearcommerror(hcomm,&dwerrormask,&comstat);
  if(dwerrormask)
  locprocesscommerror(dwerrormask);
  if(comstat.cbinque >100)
  ntoread = 100;
  else
  ntoread = comstat.cbinque;
  if(ntoread == 0)
  continue;
  if(!readfile(hcomm,inbuff,ntoread,&nbytesread,null))
  locprocesscommerror(getlasterror());
  else
  if(nbytesread)
  locprocessbytes(inbuff,nbytesread);
  }
  return 0l;
  }

12.异步i/o读写数据

  当createfile()中的fdwattrsandflags参数为file_flag_overlappen时, 端口是为异步i/o打开的,此时可以在readfile的最后一个参数中指定一个overlapped结构,使数据的读操作在后台进行。windows 95包括了异步i/o的许多变种。
  typedef struct _overlapped {
  dword internal;
  dword internalhigh;
  dword offset;
  dword offsethigh;
  handle hevent;
  } overlapped;
  对于串行口仅hevent成员有效,其于成员必须为0。
  例程:
  commtimeouts to;
  ...
  dword readthread((lpdword lpdwparam)
  {
  byte inbuff[100];
  dword nrytesread,endtime,lrc;
  static overlapped o;
  if(!cp.dwprovcapabilities & pcf_totaltimeouts)
  return 1l;
  memset(&to,0,sizeof(to));
  to.readtotaltimeoutmultiplier = 5;
  to.readtotaltimeoutconstant = 1000;
  setcommtimeouts(hcomm,&to);
  o.hevent = createevent(null,true,false,null);
  while(breading)
  {
  if(!readfile(hcomm,inbuff,10,&nbytesread,&o))
  {
  nbytesread = 0;
  if(lrc=getlasterror() == error_io_pending)
  {
  endtime = gettickcount() + 1000;
  while(!getoverlappedresult(hcomm,&o,&nbytesread,false))
  if(gettickcount() > endtime) break;
  }
  if(nbytesread) locprocessbytes(inbuff,nbytesread);
  }
  else
  {
  if(nbytesread) locprocessbytes(inbuff,nbytesread);
  resetevent(o.hevent);
  }
  }
  purgecomm(hcomm,purge_rxclear);
  return 0l;
  }
  这一例程是对一开始读缓冲区就读到所需的字节时的处理:
  while(breading)
  {
  if(!readfile(hcomm,inbuff,10,&nbytesread,&o))
  {

本文关键:,串行口,DWORD,缓冲区,
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top