现在的位置: 首页 > 综合 > 正文

结构化后,死在WriteFile()中的串口写函数

2017年12月28日 ⁄ 综合 ⁄ 共 5310字 ⁄ 字号 评论关闭

串口设置的可能的顺序:

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
--------------------------------------------------------------------------------
串口写入时引起的窗口,无法结束,进程也无法杀死。分析:
 这是因为本进程被挂起了,它在等待“数据集准备好” 或“清除以发送” 的信号,只有这两
 信号才能使本进程继续执行或被杀死掉。否则它永远留在系统内存中。
结论:
 系统级挂起方法能很好地防止本程序资源被销毁掉。

抱歉!评论已关闭.