qt5.0串口写数据返回为-1的问题

来源:互联网 发布:usb电流测试软件 编辑:程序博客网 时间:2024/06/07 22:04
 开发环境是vs2012,qt5.2.0版本。通过串口通信与步进电机控制器进行交互。步进电机连接两个电机驱动器,步进电机控制器控制两个电机运动,正反转,回零,运行到一定位置,控制输入输出停等基本操作。为了调整镜头和相机的距离,从而调整相机的放大倍率。两个电机只能分时运动,两个命令直接需要加延时,全部停除外。
       遇到两个问题,一个是串口开始写数据返回为-1的问题,另一个是由于YL1和YL2输入端功能不单一:导致回零停时或是控制停时,步进电机控制器没有返回数据(用串口调试助手不存在这个问题,我也不清楚原因),没法保证命令是否完成,于是把输入端改成YL3-YL13其中的任何两个就可以。
        再说写串口返回为-1的问题,主要以前没有做过串口通信,对过程不是很了解,对qt封装的类构造函数了解不足。其实,qt封装的代码还是调用windows底层的东西。首先,我来申明一件事:网上给的代码有的是有问题的
。因为,我是这么做的,初次向串口写数据返回为-1。然后我查阅很多资料,都没有找到问题所在,后来受到一句话启发:串口必须先打开,然后在对他配置才是有效地。然后我仔细研究了源代码,主要是Qt封装的是有一点问题。其实,我们可以迈过这个问题,就是构造函数使用问题。
     Win_QextSerialPort();
     Win_QextSerialPort(Win_QextSerialPort const& s);
     Win_QextSerialPort(const QString & name, QextSerialBase::QueryMode mode = QextSerialBase::Polling);
     Win_QextSerialPort(const PortSettings& settings, QextSerialBase::QueryMode mode = QextSerialBase::Polling);
     Win_QextSerialPort(const QString & name, const PortSettings& settings, QextSerialBase::QueryMode mode = QextSerialBase::Polling);
    这五个构造函数第三个比较常用,我开始写得是用的第5个,然后并没又再次对PortSettings进行设置,所以写数据会返回为-1.
  

来看看端口的open函数:

bool Win_QextSerialPort::open(OpenMode mode) { unsigned long confSize = sizeof(COMMCONFIG); Win_CommConfig.dwSize = confSize; DWORD dwFlagsAndAttributes = 0; if (queryMode() == QextSerialBase::EventDriven)  dwFlagsAndAttributes += FILE_FLAG_OVERLAPPED;    LOCK_MUTEX();    if (mode == QIODevice::NotOpen)        return isOpen();    if (!isOpen()) {        /*open the port*/        Win_Handle=CreateFileA(port.toAscii(), GENERIC_READ|GENERIC_WRITE,                              FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, dwFlagsAndAttributes, NULL);        if (Win_Handle!=INVALID_HANDLE_VALUE) {            /*configure port settings*/            GetCommConfig(Win_Handle, &Win_CommConfig, &confSize);            GetCommState(Win_Handle, &(Win_CommConfig.dcb));            /*set up parameters*/            Win_CommConfig.dcb.fBinary=TRUE;            Win_CommConfig.dcb.fInX=FALSE;            Win_CommConfig.dcb.fOutX=FALSE;            Win_CommConfig.dcb.fAbortOnError=FALSE;            Win_CommConfig.dcb.fNull=FALSE;            setBaudRate(Settings.BaudRate);            setDataBits(Settings.DataBits);            setStopBits(Settings.StopBits);            setParity(Settings.Parity);            setFlowControl(Settings.FlowControl);            setTimeout(Settings.Timeout_Millisec);            SetCommConfig(Win_Handle, &Win_CommConfig, sizeof(COMMCONFIG));            //init event driven approach   if (queryMode() == QextSerialBase::EventDriven) {          Win_CommTimeouts.ReadIntervalTimeout = MAXDWORD;          Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;          Win_CommTimeouts.ReadTotalTimeoutConstant = 0;        Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;        Win_CommTimeouts.WriteTotalTimeoutConstant = 0;    SetCommTimeouts(Win_Handle, &Win_CommTimeouts);             if (!SetCommMask( Win_Handle, EV_TXEMPTY | EV_RXCHAR | EV_DSR)) {              qWarning("Failed to set Comm Mask. Error code: %ld", GetLastError());     UNLOCK_MUTEX();              return false;             }             overlapThread->start();            }   QIODevice::open(mode);        }    } else {  UNLOCK_MUTEX();     return false;    }    UNLOCK_MUTEX();    return isOpen();}

而其中的:
            setBaudRate(Settings.BaudRate);
            setDataBits(Settings.DataBits);
            setStopBits(Settings.StopBits);
            setParity(Settings.Parity);
            setFlowControl(Settings.FlowControl);
            setTimeout(Settings.Timeout_Millisec);
这些函数只有在端口打开的时候才会设置有效的,具体自己看代码。 再看构造函数里面,if (!isOpen()) {}不打开又进行设置,所以说打开函数并不会PortSettings设置成功,所以在打开之后我们要单独对PortSettings进行设置。

     文件下载地址:http://sourceforge.net/projects/qextserialport/files/


     正确的写法是,以事件驱动的为例:    
     myCom = new Win_QextSerialPort(“COM1″,QextSerialBase::EventDriven);

    //定义串口对象,指定串口名和查询模式,这里使用事件驱动EventDriven

    myCom ->open(QIODevice::ReadWrite);

    //以读写方式打开串口

    myCom->setBaudRate(BAUD9600);

    //波特率设置,我们设置为9600

    myCom->setDataBits(DATA_8);

   //数据位设置,我们设置为8位数据位

    myCom->setParity(PAR_NONE);

    //奇偶校验设置,我们设置为无校验

    myCom->setStopBits(STOP_1);

    //停止位设置,我们设置为1位停止位

    myCom->setFlowControl(FLOW_OFF);

    //数据流控制设置,我们设置为无数据流控制

    myCom->setTimeout(500);

    //延时设置,我们设置为延时500ms,这个在Windows下好像不起作用

    connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));

    //信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作



0 0
原创粉丝点击