首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > QT开发 >

Qt串口持续输入数据,上位机接收端未响应有关问题

2012-04-23 
Qt串口持续输入数据,上位机接收端未响应问题同时发帖在个人博客里面:http://blog.csdn.net/jjzhoujun2010/

Qt串口持续输入数据,上位机接收端未响应问题
同时发帖在个人博客里面:http://blog.csdn.net/jjzhoujun2010/article/details/7463344

此Qt串口接收程序需要做的工作是:从开发板上不断地传输过来带有“Star”帧头的数据帧,数据是浮点型数据。要求显示的时候也是将浮点数显示出来。我采用的是Polling查询机制,不是EventDriven机制,在textBrowser里面想先显示出除了”Star”帧的数据,先是用十六进制数表示出来。

现在我遇到的问题是:

当我打开上位机串口,并且开启开发板的电源,进行串口数据传输时候,Qt程序会出现未响应,只能把开发板电源关掉等待一会,textBrowser上面就会出现数据,此时的数据只是能看出第一次发送的时候会把“Star”去掉只显示出后面的数据,如图一所示。


需要帮忙解决的问题是:

1.用Qt写串口程序时候,在利用Polling机制时,面对不断读取的串口数据,如何让textBrowser一直输出数据而不出现程序未响应的情况?

2.接图一,除了第一个程序能够去掉“Star”帧头外,如何让以后的帧传过来时候都可以去掉“Star”帧头,从而只是显示后面的数据。

 

另附上我的主要实现代码:

[cpp] view plaincopy
//**************mainwindow.h*********************//  
#ifndefMAINWINDOW_H  
#defineMAINWINDOW_H  
#include<QMainWindow>  
#include<QString>  
#include<QStandardItemModel>  
#include"win_qextserialport.h"  
namespaceUi{  
  classMainWindow;  
}  
classMainWindow:publicQMainWindow  
{  
  Q_OBJECT  
public:  
  explicitMainWindow(QWidget*parent=0);  
  ~MainWindow();  
private:  
  Ui::MainWindow*ui;  
  Win_QextSerialPort*myCom;  
  QTimer*myReadTimer; //采用polling查询的方式进行  
privateslots:  
  voidreadMyCom();  
  voidon_openMyComBtn_clicked();  
  voidon_closeMyComBtn_clicked();  
};  
#endif//MAINWINDOW_H  
   
 

[cpp] view plaincopy
//***********mainwindow.cpp***************//  
#include"mainwindow.h"  
#include"ui_mainwindow.h"  
#include<QMessageBox>  
MainWindow::MainWindow(QWidget*parent):  
  QMainWindow(parent),  
  ui(newUi::MainWindow)  
{  
  ui->setupUi(this);  
  ui->closeMyComBtn->setEnabled(false);  
  setWindowTitle(tr("串口调试主界面_P1"));  
   
}  
   
MainWindow::~MainWindow()  
{  
  deleteui;  
}  
   
   
voidMainWindow::readMyCom()  
{  
  //个人想法:先让其在文本框中全部输出字符串下,串口传的是标准ASCII值,然后如果直接显示的时候,又把它转成字符串形式  
  //由于有的ASCII值转换成字符串后不能在屏幕上直接显示,所以会出现卡死程序情况,停止传输后就只输出Star字符  
  //因此需要先把串口里面的ASCII值转换成十六进制数,然后再将其转换成浮点数,分别显示在表格里面 --CommentByDream_Fly  
  QStringtemp='\0';  
  QStringstrHex;//16进制数据  
  QByteArraydataAll=myCom->readAll();  
  intrflag=0;  
  if(!dataAll.isEmpty())  
  {  
  QDataStreamout(&dataAll,QIODevice::ReadWrite);  
  //下面是判断帧头“Star”,不知道如何直接读入4个字节的字符串Star,然后直接判断??  
  if(!out.atEnd())  
  {  
  qint8judge1=0;  
  out>>judge1;  
  if(judge1==83)  
  {  
  qint8judge2=0;  
  out>>judge2;  
  if(judge2==116)  
  {  
  qint8judge3=0;  
  out>>judge3;  
  if(judge3==97)  
  {  
  qint8judge4=0;  
  out>>judge4;  
  if(judge4==114)  
  rflag=1;  
  }  


  }  
  }  
  else  
  rflag=0;  
  if(rflag)  
  {  
  while(!out.atEnd())  
  {  
  qint8outChar=0;  
  out>>outChar;  
  QStringstr1=QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));//转换成十六进制数_Dream_Fly  
  if(str1.length()>1)  
  {  
  strHex+=str1+"";  
  }  
  else  
  {  
  strHex+="0"+str1+"";  
  }  
  }  
  }  
  }  
  ui->textBrowser->append(strHex.toUpper());  
  }  
}  
   
//打开串口的信号与槽自动关联函数  
voidMainWindow::on_openMyComBtn_clicked()  
{  
  QStringportName=ui->portNameComboBox->currentText();//获取串口名  
  myCom=newWin_QextSerialPort(portName,QextSerialBase::Polling);  
  //定义串口对象,并传递参数,在构造函数里对其进行初始化  
  myCom->open(QIODevice::ReadWrite); //注意:得要先打开串口,然后再设置串口的参数,不然设置无效!!!  
  myCom->flush();//存入缓冲区内待读取  
  //设置波特率  
  if(ui->baudRateComboBox->currentText()==tr("9600")) //根据组合框内容对串口进行设置  
  myCom->setBaudRate(BAUD9600);  
  elseif(ui->baudRateComboBox->currentText()==tr("115200"))  
  myCom->setBaudRate(BAUD115200);  
  //设置数据位  
  if(ui->dataBitsComboBox->currentText()==tr("8"))  
  myCom->setDataBits(DATA_8);  
  elseif(ui->dataBitsComboBox->currentText()==tr("7"))  
  myCom->setDataBits(DATA_7);  
  //设置奇偶校验  
  if(ui->parityComboBox->currentText()==tr("无"))  
  myCom->setParity(PAR_NONE);  
  elseif(ui->parityComboBox->currentText()==tr("奇校验"))  
  myCom->setParity(PAR_ODD);  
  elseif(ui->parityComboBox->currentText()==tr("偶校验"))  
  myCom->setParity(PAR_EVEN);  
  //设置停止位  
  if(ui->stopBitsComboBox->currentText()==tr("1"))  
  myCom->setStopBits(STOP_1);  
  elseif(ui->stopBitsComboBox->currentText()==tr("2"))  
  myCom->setStopBits(STOP_2);  
  myCom->setFlowControl(FLOW_OFF);//设置数据流控制,我们使用无数据流的默认设置  
  myCom->setTimeout(10);//设置延时 --Modify改小点  
  myReadTimer=newQTimer(this);  
  myReadTimer->setInterval(200);  
  connect(myReadTimer,SIGNAL(timeout()),this,SLOT(readMyCom()));  
  this->myReadTimer->start(); //开始poll查询操作  
  //connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom())); //不采用事件Event的方式,采用Polling方式  
  ui->openMyComBtn->setEnabled(false);  
  ui->closeMyComBtn->setEnabled(true);  
  ui->helpBtn->setEnabled(true);  
  ui->portNameComboBox->setEnabled(false);  
  ui->baudRateComboBox->setEnabled(false);  
  ui->dataBitsComboBox->setEnabled(false);  


  ui->stopBitsComboBox->setEnabled(false);  
  ui->parityComboBox->setEnabled(false);  
  ui->displayBtn->setEnabled(true);  
  ui->debugBtn->setEnabled(true);  
}  
voidMainWindow::on_closeMyComBtn_clicked()  
{  
  myCom->close();  
  this->myReadTimer->stop(); //关闭poll操作  
  ui->openMyComBtn->setEnabled(true);  
  ui->helpBtn->setEnabled(true);  
  ui->portNameComboBox->setEnabled(true);  
  ui->baudRateComboBox->setEnabled(true);  
  ui->dataBitsComboBox->setEnabled(true);  
  ui->stopBitsComboBox->setEnabled(true);  
  ui->parityComboBox->setEnabled(true);  
}  
voidMainWindow::on_helpBtn_clicked()  
{  
  QMessageBox::about(this,tr("帮助信息"),tr("1.选定好具体串口设置,点击打开串口即可收到信息"));  
}  
   
   

[cpp] view plaincopy
//***************main.cpp************//  
#include<QtGui/QApplication>  
#include<QTextCodec> //加入头文件  
#include"mainwindow.h"  
intmain(intargc,char*argv[])  
{  
  QApplicationa(argc,argv);  
  QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); //使程序可处理中文  
  MainWindoww;  
  w.show();  
  returna.exec();  
}  
   


Qt串口数据这里的问题困扰我几天了,希望能够帮忙解决下,不胜感激。

[解决办法]
this->myReadTimer->start(); //开始poll查询操作 是不是得有个时间呢?比如
this->myReadTimer->start(1000); //开始poll查询操作
[解决办法]
while(!out.atEnd())
{
qint8outChar=0;
out>>outChar;
QStringstr1=QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));//转换成十六进制数
………………
楼主应该是程序卡在while循环里了。 这时候qt是不会响应定时器的。会一直在while中。
不知道楼主的一帧数据的长度是否是固定的。 如果不是固定的可以在一帧数据中加一个表示长度的字节。 靠接收的字节长度来区分一帧数据。( 而不是像上面用while()来判断缓冲区里的数据是否读完。) 然后接收完一帧后马上处理要处理的数据。 如果非用while的话,只有用多线成了来处理数据。

热点排行