├── MySerial_Port.exe ├── MySerial_Port.pro ├── MySerial_Port.pro.user ├── README.md ├── disnumthread.cpp ├── disnumthread.h ├── main.cpp ├── myserialport.RC ├── myserialport.ico ├── mywidget.cpp ├── mywidget.h ├── mywidget.ui ├── qcustomplot.cpp ├── qcustomplot.h ├── resource.qrc ├── spcomm.cpp └── spcomm.h /MySerial_Port.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lynnllh/SerialAssistance/22a24961999bec61d4374a1cac87788a322bb6c6/MySerial_Port.exe -------------------------------------------------------------------------------- /MySerial_Port.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-11-18T08:14:33 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | QT += serialport 9 | 10 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport 11 | 12 | TARGET = MySerial_Port 13 | TEMPLATE = app 14 | 15 | 16 | SOURCES += main.cpp\ 17 | mywidget.cpp \ 18 | spcomm.cpp \ 19 | disnumthread.cpp \ 20 | qcustomplot.cpp 21 | 22 | HEADERS += mywidget.h \ 23 | spcomm.h \ 24 | disnumthread.h \ 25 | qcustomplot.h 26 | 27 | FORMS += mywidget.ui 28 | 29 | RC_FILE +=myserialport.rc 30 | 31 | RESOURCES += \ 32 | resource.qrc 33 | -------------------------------------------------------------------------------- /MySerial_Port.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {3ecccb30-ea03-4fd8-b092-5d456eb6024b} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 1 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | false 36 | 80 37 | true 38 | true 39 | 1 40 | true 41 | false 42 | 0 43 | true 44 | 0 45 | 8 46 | true 47 | 1 48 | true 49 | true 50 | true 51 | false 52 | 53 | 54 | 55 | ProjectExplorer.Project.PluginSettings 56 | 57 | 58 | 59 | ProjectExplorer.Project.Target.0 60 | 61 | Desktop Qt 5.4.2 MinGW 32bit 62 | Desktop Qt 5.4.2 MinGW 32bit 63 | qt.54.win32_mingw491_kit 64 | 0 65 | 0 66 | 0 67 | 68 | D:/large software data/QT/PROJECT/SERIALASSISTANT/Serial_Port2016_11_18/build-MySerial_Port-Desktop_Qt_5_4_2_MinGW_32bit-Debug 69 | 70 | 71 | true 72 | qmake 73 | 74 | QtProjectManager.QMakeBuildStep 75 | false 76 | true 77 | 78 | false 79 | false 80 | false 81 | 82 | 83 | true 84 | Make 85 | 86 | Qt4ProjectManager.MakeStep 87 | 88 | false 89 | 90 | 91 | 92 | 2 93 | 构建 94 | 95 | ProjectExplorer.BuildSteps.Build 96 | 97 | 98 | 99 | true 100 | Make 101 | 102 | Qt4ProjectManager.MakeStep 103 | 104 | true 105 | clean 106 | 107 | 108 | 1 109 | 清理 110 | 111 | ProjectExplorer.BuildSteps.Clean 112 | 113 | 2 114 | false 115 | 116 | Debug 117 | 118 | Qt4ProjectManager.Qt4BuildConfiguration 119 | 2 120 | true 121 | 122 | 123 | D:/large software data/QT/PROJECT/SERIALASSISTANT/Serial_Port2016_11_18/build-MySerial_Port-Desktop_Qt_5_4_2_MinGW_32bit-Release 124 | 125 | 126 | true 127 | qmake 128 | 129 | QtProjectManager.QMakeBuildStep 130 | false 131 | true 132 | 133 | false 134 | false 135 | false 136 | 137 | 138 | true 139 | Make 140 | 141 | Qt4ProjectManager.MakeStep 142 | 143 | false 144 | 145 | 146 | 147 | 2 148 | 构建 149 | 150 | ProjectExplorer.BuildSteps.Build 151 | 152 | 153 | 154 | true 155 | Make 156 | 157 | Qt4ProjectManager.MakeStep 158 | 159 | true 160 | clean 161 | 162 | 163 | 1 164 | 清理 165 | 166 | ProjectExplorer.BuildSteps.Clean 167 | 168 | 2 169 | false 170 | 171 | Release 172 | 173 | Qt4ProjectManager.Qt4BuildConfiguration 174 | 0 175 | true 176 | 177 | 2 178 | 179 | 180 | 0 181 | 部署 182 | 183 | ProjectExplorer.BuildSteps.Deploy 184 | 185 | 1 186 | 在本地部署 187 | 188 | ProjectExplorer.DefaultDeployConfiguration 189 | 190 | 1 191 | 192 | 193 | 194 | false 195 | false 196 | false 197 | false 198 | true 199 | 0.01 200 | 10 201 | true 202 | 1 203 | 25 204 | 205 | 1 206 | true 207 | false 208 | true 209 | valgrind 210 | 211 | 0 212 | 1 213 | 2 214 | 3 215 | 4 216 | 5 217 | 6 218 | 7 219 | 8 220 | 9 221 | 10 222 | 11 223 | 12 224 | 13 225 | 14 226 | 227 | 2 228 | 229 | MySerial_Port 230 | 231 | Qt4ProjectManager.Qt4RunConfiguration:D:/large software data/QT/PROJECT/SERIALASSISTANT/Serial_Port2016_11_18/MySerial_Port/MySerial_Port.pro 232 | 233 | MySerial_Port.pro 234 | false 235 | false 236 | 237 | 3768 238 | false 239 | true 240 | false 241 | false 242 | true 243 | 244 | 1 245 | 246 | 247 | 248 | ProjectExplorer.Project.Target.1 249 | 250 | Qt_5.4_MinGw_static 251 | Qt_5.4_MinGw_static 252 | {b24def56-bd69-4016-899f-826c450d6d19} 253 | 1 254 | 0 255 | 0 256 | 257 | D:/large software data/QT/PROJECT/SERIALASSISTANT/Serial_Port2016_11_18/build-MySerial_Port-Qt_5_4_MinGw_static-Debug 258 | 259 | 260 | true 261 | qmake 262 | 263 | QtProjectManager.QMakeBuildStep 264 | false 265 | true 266 | 267 | false 268 | false 269 | false 270 | 271 | 272 | true 273 | Make 274 | 275 | Qt4ProjectManager.MakeStep 276 | 277 | false 278 | 279 | 280 | 281 | 2 282 | 构建 283 | 284 | ProjectExplorer.BuildSteps.Build 285 | 286 | 287 | 288 | true 289 | Make 290 | 291 | Qt4ProjectManager.MakeStep 292 | 293 | true 294 | clean 295 | 296 | 297 | 1 298 | 清理 299 | 300 | ProjectExplorer.BuildSteps.Clean 301 | 302 | 2 303 | false 304 | 305 | Debug 306 | 307 | Qt4ProjectManager.Qt4BuildConfiguration 308 | 2 309 | true 310 | 311 | 312 | D:/large software data/QT/PROJECT/SERIALASSISTANT/Serial_Port2016_11_18/build-MySerial_Port-Qt_5_4_MinGw_static-Release 313 | 314 | 315 | true 316 | qmake 317 | 318 | QtProjectManager.QMakeBuildStep 319 | false 320 | true 321 | 322 | false 323 | false 324 | false 325 | 326 | 327 | true 328 | Make 329 | 330 | Qt4ProjectManager.MakeStep 331 | 332 | false 333 | 334 | 335 | 336 | 2 337 | 构建 338 | 339 | ProjectExplorer.BuildSteps.Build 340 | 341 | 342 | 343 | true 344 | Make 345 | 346 | Qt4ProjectManager.MakeStep 347 | 348 | true 349 | clean 350 | 351 | 352 | 1 353 | 清理 354 | 355 | ProjectExplorer.BuildSteps.Clean 356 | 357 | 2 358 | false 359 | 360 | Release 361 | 362 | Qt4ProjectManager.Qt4BuildConfiguration 363 | 0 364 | true 365 | 366 | 2 367 | 368 | 369 | 0 370 | 部署 371 | 372 | ProjectExplorer.BuildSteps.Deploy 373 | 374 | 1 375 | 在本地部署 376 | 377 | ProjectExplorer.DefaultDeployConfiguration 378 | 379 | 1 380 | 381 | 382 | 383 | false 384 | false 385 | false 386 | false 387 | true 388 | 0.01 389 | 10 390 | true 391 | 1 392 | 25 393 | 394 | 1 395 | true 396 | false 397 | true 398 | valgrind 399 | 400 | 0 401 | 1 402 | 2 403 | 3 404 | 4 405 | 5 406 | 6 407 | 7 408 | 8 409 | 9 410 | 10 411 | 11 412 | 12 413 | 13 414 | 14 415 | 416 | 2 417 | 418 | MySerial_Port 419 | MySerial_Port2 420 | Qt4ProjectManager.Qt4RunConfiguration:D:/large software data/QT/PROJECT/SERIALASSISTANT/Serial_Port_Ver2.2_2016_11_25/MySerial_Port/MySerial_Port.pro 421 | 422 | MySerial_Port.pro 423 | false 424 | false 425 | 426 | 3768 427 | false 428 | true 429 | false 430 | false 431 | true 432 | 433 | 1 434 | 435 | 436 | 437 | ProjectExplorer.Project.TargetCount 438 | 2 439 | 440 | 441 | ProjectExplorer.Project.Updater.FileVersion 442 | 18 443 | 444 | 445 | Version 446 | 18 447 | 448 | 449 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SerialAssistance 2 | 基于Qt开发环境,开发能够实时显示数据曲线的串口助手,实现串口参数的设置、通信协议的制定、串口收发数据的功能,最大8通道的数据曲线实时显示,时间区间的实时调节。 3 | 4 | 操作系统环境:WIN7旗舰版,使用软件版本:QTCreator 5.4.2 MinGW 32bit 5 | 6 | 功能说明: 7 | 8 | 1.接受串口数据并实时显示在显示区 9 | 10 | 2.最多能够同时显示8组数据 11 | 12 | 3.能够保存曲线 13 | 14 | 4.能够保存数据 15 | 16 | 5.拥有写数据功能 17 | 18 | 操作说明: 19 | 20 | 1.填写横坐标范围(时间),纵坐标范围(数据值),点击发送设置参数 21 | 22 | 2.点击搜索串口,选择串口,设置波特率,数据位,停止位,奇偶校验位打开串口 23 | 24 | 3.按照数据的组数点击通过数,有几组数据就点几个通道,点击发送设置参数 25 | 26 | Serial_Port_Ver1.1_2016_11_23更新说明 27 | 28 | 1.修复拔掉串口之后重复提示要关闭串口,导致软件奔溃 29 | 30 | 2.修复关闭窗口之后弹出警告窗口 31 | 32 | 3.新增清除接受之后,重启串口 33 | 34 | Serial_Port_Ver1.2_2016_11_25更新说明 35 | 36 | 1.修复直接点击打开串口x轴会发生变化 37 | 38 | 2.修复可直接重复点击发送设置参数 39 | 40 | 3.实现自动滚屏 41 | 42 | Serial_Port_Ver2.2_2016_11_25更新说明 43 | 44 | 1.增加写功能,只能发送不超过5位的数字,以'\r\n'为结束标识符 45 | 46 | 2.修复因外因串口挂了之后无法重新启动串口 47 | -------------------------------------------------------------------------------- /disnumthread.cpp: -------------------------------------------------------------------------------- 1 | #include "disnumthread.h" 2 | 3 | /*//////////////////////// 4 | * 函数名: DisNumThread::DisNumThread() 5 | * 功能: 构造函数,将线程状态信号置为可开启状态 6 | */ 7 | DisNumThread::DisNumThread() 8 | { 9 | stopped=false; 10 | } 11 | 12 | /*//////////////////////////// 13 | * 函数名: DisNumThread::~DisNumThread() 14 | * 功能: 析构函数 15 | */ 16 | DisNumThread::~DisNumThread() 17 | { 18 | 19 | } 20 | 21 | /*//////////////////////////// 22 | * 函数名: void DisNumThread::run() 23 | * 功能: 线程运行函数,将主线程中传递过来的参数 24 | * 设置串口参数,打开串口发送串口开启状态, 25 | * 将串口中传递过来的单个字符和数据发送给 26 | * 主线程显示 27 | */ 28 | void DisNumThread::run() 29 | { 30 | stopped=false; //防止串口掉了之后无法重新开启串口 31 | //////////////////////////////设置串口参数 32 | Comm.setPortName(PortName); 33 | Comm.setBaudRate(BaudRate); 34 | Comm.setDataBits(DataBits); 35 | switch(Parity) 36 | { 37 | case 1: 38 | Comm.setParity(3);break; 39 | case 2: 40 | Comm.setParity(2);break; 41 | default: 42 | Comm.setParity(0);break; 43 | } 44 | 45 | switch (StopBits) 46 | { 47 | case 1: 48 | Comm.setStopBits(3);break; 49 | case 2: 50 | Comm.setStopBits(2);break; 51 | default: 52 | Comm.setStopBits(1);break; 53 | } 54 | //////////////////////////////// 55 | bool justic; 56 | justic=Comm.open(); //将串口开启的状态发送给主线程,由此来将串口的状态显示给用户 57 | emit checkopen(justic); 58 | //qDebug()< 5 | #include 6 | #include 7 | #include "spcomm.h" 8 | #include 9 | #include 10 | 11 | class DisNumThread : public QThread 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | DisNumThread(); 17 | ~DisNumThread(); 18 | void stop(); //用来控制线程中断 19 | 20 | protected: 21 | void run(); //控制线程开启 22 | 23 | private: 24 | bool stopped; //作为开启或者关断的控制信号,后称为线程状态信号 25 | QMutex mutex; //用来保护易失变量 26 | QString PortName; //用来保存主线程中传递过来的串口名 27 | 28 | 29 | int BaudRate; //用来保存主线程中传递过来的波特率 30 | int DataBits; //用来保存主线程中传递过来的数据位 31 | int StopBits; //用来保存主线程中传递过来的停止位 32 | int Parity; //用来保存主线程中传递过来的奇偶校验位 33 | 34 | 35 | SPComm Comm; //串口类实例化以使用成员函数 36 | char room; //用来保存从串口中传递出来的单个字符 37 | signed int readdatareturn; //串口读数据的返回值,用来显示串口读数据的状态 38 | QString dataNum; //用来保存串口中读出来的数据(不是单个字符,由单个字符组成) 39 | //QString dataStr; 40 | int MiddledataNum; //用来转化的中间变量 41 | 42 | public slots: 43 | void acceptdataslot(QString portname,int baudrate,int databits,int stopbits,int parity); 44 | void availableportdetectslot(); 45 | void SendNumtoportslot(char* data,int i); 46 | 47 | signals: 48 | void checkopen(bool justic); 49 | void SendString(QString PortMessageString); 50 | void SendInt(int PortMessageInt); 51 | void wrongdetectone(); 52 | void wrongdetecttwo(); 53 | void availableportname(QString str); 54 | 55 | 56 | }; 57 | 58 | #endif // DISNUMTHREAD_H 59 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "mywidget.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | MyWidget w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /myserialport.RC: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "myserialport.ico" -------------------------------------------------------------------------------- /myserialport.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lynnllh/SerialAssistance/22a24961999bec61d4374a1cac87788a322bb6c6/myserialport.ico -------------------------------------------------------------------------------- /mywidget.cpp: -------------------------------------------------------------------------------- 1 | #include "mywidget.h" 2 | #include "ui_mywidget.h" 3 | 4 | //注册QString和bool 5 | Q_DECLARE_METATYPE(QString) 6 | Q_DECLARE_METATYPE(bool) 7 | /*//////////////////////// 8 | * 函数名: MyWidget::MyWidget(QWidget *parent) 9 | * 功能: 构造函数,完成初始化并且连接信号和槽 10 | */ 11 | MyWidget::MyWidget(QWidget *parent) : 12 | QWidget(parent), 13 | ui(new Ui::MyWidget) 14 | { 15 | ui->setupUi(this); 16 | //初始化参数 17 | ChangeNum=0; 18 | availportname=""; 19 | portNum=0; 20 | percent=1; 21 | 22 | //注册QString和bool 23 | int id=qRegisterMetaType("QString"); 24 | int od=qRegisterMetaType("bool"); 25 | qDebug()<NumDisplayplainTextEdit->setCenterOnScroll(1); 39 | } 40 | 41 | /*//////////////////////// 42 | * 函数名: MyWidget::~MyWidget() 43 | * 功能: 析构函数停止线程并且等待线程释放 44 | */ 45 | MyWidget::~MyWidget() 46 | { 47 | thread.stop(); 48 | thread.wait(); 49 | delete ui; 50 | } 51 | 52 | /*///////////////////// 53 | * 函数名: void MyWidget::firstplot(QCustomPlot *customplot) 54 | * 功能: 图像的初始化函数,并且设置x个曲线 55 | */ 56 | void MyWidget::portplot(QCustomPlot *customplot) 57 | { 58 | customplot->clearGraphs(); 59 | ////////////////////////////设置xy轴文字,图例文字以及曲线样式 60 | customplot->setNotAntialiasedElements(QCP::aeAll); 61 | QFont font; 62 | font.setStyleStrategy(QFont::NoAntialias); 63 | font.setPointSize(9); 64 | font.setBold(true); 65 | font.setWeight(100); 66 | customplot->xAxis->setTickLabelFont(font); 67 | 68 | customplot->yAxis->setTickLabelFont(font); 69 | 70 | customplot->legend->setFont(font); 71 | 72 | ////////////////////////////增加x个曲线 73 | 74 | int i; 75 | for (i=0;iaddGraph(); //增加一个图层,如果要显示多条曲线可以显示多条曲线 78 | switch (i) //使用switch和for可以重复定义最多8条曲线,设置曲线的颜色和图例的名字 79 | { 80 | case 1: 81 | customplot->graph(1)->setPen(QPen(Qt::red));break; 82 | case 2: 83 | customplot->graph(2)->setPen(QPen(Qt::green));break; 84 | case 3: 85 | customplot->graph(3)->setPen(QPen(Qt::yellow));break; 86 | case 4: 87 | customplot->graph(4)->setPen(QPen(Qt::black));break; 88 | case 5: 89 | customplot->graph(5)->setPen(QPen(Qt::lightGray));break; 90 | case 6: 91 | customplot->graph(6)->setPen(QPen(Qt::darkMagenta));break; 92 | case 7: 93 | customplot->graph(7)->setPen(QPen(Qt::darkGreen));break; 94 | default: 95 | customplot->graph(0)->setPen(QPen(Qt::blue));break; 96 | } 97 | switch (i) 98 | { 99 | case 1: 100 | customplot->graph(1)->setName("Channel two");break; 101 | case 2: 102 | customplot->graph(2)->setName("Channel three");break; 103 | case 3: 104 | customplot->graph(3)->setName("Channel four");break; 105 | case 4: 106 | customplot->graph(4)->setName("Channel five");break; 107 | case 5: 108 | customplot->graph(5)->setName("Channel six");break; 109 | case 6: 110 | customplot->graph(6)->setName("Channel seven");break; 111 | case 7: 112 | customplot->graph(7)->setName("Channel eight");break; 113 | default: 114 | customplot->graph(0)->setName("Channel one");break; 115 | } 116 | } 117 | customplot->xAxis->setTickLabelType(QCPAxis::ltDateTime);//设置x轴的显示样式 118 | customplot->xAxis->setDateTimeFormat("mm:ss"); 119 | 120 | customplot->xAxis->setAutoTickStep(true); 121 | //customplot->xAxis->setTickStep(1); //设置x轴的单位间隔 122 | 123 | customplot->axisRect()->setupFullAxesBox(); 124 | customplot->legend->setVisible(true); //设置图例可见 125 | 126 | double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0; 127 | xAxismax=ui->xAxismaxlineEdit->text().toInt(); 128 | yAxismin=ui->yAxisminlineEdit->text().toInt(); 129 | yAxismax=ui->yAxismaxlineEdit->text().toInt(); 130 | ui->plotwidget->yAxis->setRange(yAxismin,yAxismax); //设置y轴的范围 131 | ui->plotwidget->xAxis->setRange(key+0.25,xAxismax,Qt::AlignRight); //设置x轴的范围 132 | 133 | } 134 | 135 | 136 | /*//////////////////////// 137 | * 函数名: void MyWidget::on_SearchPortpushButton_clicked() 138 | * 功能: 搜索串口,如果没搜到那么弹出错误,如果有那么在 139 | * 串口选择的下拉框中将出现串口名 140 | */ 141 | void MyWidget::on_SearchPortpushButton_clicked() 142 | { 143 | if(1==ui->SelectPortcomboBox->count())//检测串口选择的下拉框中有几个item,如果多于一个则不再往里面加item 144 | { 145 | emit availableportdetect(); 146 | //qDebug()<SelectPortcomboBox->addItem(availportname); 155 | } 156 | } 157 | 158 | } 159 | 160 | /*//////////////////////// 161 | * 函数名: void MyWidget::on_OpenPortpushButton_clicked() 162 | * 功能: 当鼠标点击打开串口按钮时,将combobox中的参数赋 163 | * 给串口类进行初始化并且打开串口,文字变为关闭串口 164 | * 点击关闭串口则关闭串口 165 | */ 166 | void MyWidget::on_OpenPortpushButton_clicked() 167 | { 168 | if (0==ChangeNum) //用来判断有没有关闭串口 169 | { 170 | ChangeNum=1; 171 | count=1; //在打开串口的时候初始化挑选数据的计数信号 172 | //////////////////////将用户输入的串口参数发送给次线程 173 | portname=ui->SelectPortcomboBox->currentText(); 174 | baudrate=ui->BaudRatecomboBox->currentText().toInt(); 175 | databits=ui->DataBitscomboBox->currentText().toInt(); 176 | stopbits=ui->StopBitscomboBox->currentIndex(); 177 | parity=ui->ParitycomboBox->currentIndex(); 178 | emit acceptdata(portname,baudrate,databits,stopbits,parity); 179 | ////////////////////// 180 | MyComm.sleep(200); //留给传递信号一点时间 181 | thread.start(); //开启线程打开串口 182 | //是否需要延时一段时间 183 | MyComm.sleep(200); //等待信号传递过来 184 | 185 | if (Justic==true) //判断串口是否打开,如果打开就把“打开串口”变成“关闭串口”。如果没打开就弹出警告 186 | { 187 | ui->OpenPortpushButton->setText("关闭串口"); 188 | } 189 | else 190 | { 191 | QMessageBox::warning(this,"Error information","the port can't open!"); 192 | } 193 | 194 | //int n; 195 | // n=MyComm.readData(Buffer,Count); 196 | 197 | //for(int i=0;iNumDisplayplainTextEdit->insertPlainText(QString(Buffer[i])); 200 | // } 201 | } 202 | else //如果点击关闭串口则停止线程并将“关闭串口”变成“打开串口” 203 | { 204 | ChangeNum=0; 205 | thread.stop(); 206 | ui->OpenPortpushButton->setText("打开串口"); 207 | } 208 | } 209 | 210 | /*////////////////////////// 211 | * 函数名: void MyWidget::checkopenslot(bool justic) 212 | * 功能: 接受来自次线程的关于串口是否打开的信号 213 | */ 214 | void MyWidget::checkopenslot(bool justic) 215 | { 216 | Justic=justic; 217 | } 218 | 219 | /*///////////////////////// 220 | * 函数名: void MyWidget::SendStringslot(QString PortMessageString) 221 | * 功能: 接受来自次线程的串口输出的单个字符,并把它打印到textedit中 222 | * 并实现自动滚屏 223 | */ 224 | void MyWidget::SendStringslot(QString PortMessageString) 225 | { 226 | 227 | ui->NumDisplayplainTextEdit->insertPlainText(PortMessageString); 228 | ui->NumDisplayplainTextEdit->moveCursor(QTextCursor::EndOfLine); 229 | //QTextCursor cursor=ui->NumDisplayplainTextEdit->textCursor(); 230 | //cursor.movePosition(QTextCursor::End); 231 | //ui->NumDisplayplainTextEdit->appendPlainText(""); 232 | } 233 | 234 | /*///////////////////////////// 235 | * 函数名:void MyWidget::SendIntslot(int PortMessageInt) 236 | * 功能: 接受来自次线程的串口输出的数据,并且把该数据按用户设置输出成曲线 237 | */ 238 | void MyWidget::SendIntslot(int PortMessageInt) 239 | { 240 | if (issendcurvedata) //判断有没有按下发送图像设置按钮,如果没有按下则不显示图像 241 | { 242 | 243 | double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0; 244 | ui->plotwidget->xAxis->setRange(key+0.25,qCeil(xAxismax*percent),Qt::AlignRight); //设置x轴的范围 245 | //qDebug()<ChanneltwocheckBox->isChecked()) //判断channel one的复选框有没有选中,如果选中则显示曲线 252 | { 253 | if (count!=portNum) //判断是否到达最大可显示曲线数目 254 | { 255 | count++; 256 | } 257 | else 258 | { 259 | count=1; 260 | } 261 | ui->plotwidget->graph(1)->addData(key,PortMessageInt); //把数据增加到曲线上 262 | ui->plotwidget->graph(1)->removeDataBefore(key-qCeil(xAxismax*percent)); //清楚前面的数据 263 | 264 | } 265 | else 266 | { 267 | if (count!=portNum) //判断是否到达最大可显示曲线数目 268 | { 269 | count++; 270 | } 271 | else 272 | { 273 | count=1; 274 | } 275 | } 276 | break; 277 | case 3: 278 | if (ui->ChannelthreecheckBox->isChecked()) 279 | { 280 | if (count!=portNum) //判断是否到达最大可显示曲线数目 281 | { 282 | count++; 283 | } 284 | else 285 | { 286 | count=1; 287 | } 288 | ui->plotwidget->graph(2)->addData(key,PortMessageInt); //把数据增加到曲线上 289 | ui->plotwidget->graph(2)->removeDataBefore(key-qCeil(xAxismax*percent)); //清楚前面的数据 290 | 291 | } 292 | else 293 | { 294 | if (count!=portNum) //判断是否到达最大可显示曲线数目 295 | { 296 | count++; 297 | } 298 | else 299 | { 300 | count=1; 301 | } 302 | } 303 | break; 304 | case 4: 305 | if (ui->ChannelfourcheckBox->isChecked()) 306 | { 307 | if (count!=portNum) //判断是否到达最大可显示曲线数目 308 | { 309 | count++; 310 | } 311 | else 312 | { 313 | count=1; 314 | } 315 | ui->plotwidget->graph(3)->addData(key,PortMessageInt); //把数据增加到曲线上 316 | ui->plotwidget->graph(3)->removeDataBefore(key-qCeil(xAxismax*percent)); //清楚前面的数据 317 | } 318 | else 319 | { 320 | if (count!=portNum) //判断是否到达最大可显示曲线数目 321 | { 322 | count++; 323 | } 324 | else 325 | { 326 | count=1; 327 | } 328 | } 329 | break; 330 | 331 | case 5: 332 | if (ui->ChannelfivecheckBox->isChecked()) 333 | { 334 | if (count!=portNum) //判断是否到达最大可显示曲线数目 335 | { 336 | count++; 337 | } 338 | else 339 | { 340 | count=1; 341 | } 342 | ui->plotwidget->graph(4)->addData(key,PortMessageInt); //把数据增加到曲线上 343 | ui->plotwidget->graph(4)->removeDataBefore(key-qCeil(xAxismax*percent)); //清楚前面的数据 344 | } 345 | else 346 | { 347 | if (count!=portNum) //判断是否到达最大可显示曲线数目 348 | { 349 | count++; 350 | } 351 | else 352 | { 353 | count=1; 354 | } 355 | } 356 | break; 357 | case 6: 358 | if (ui->ChannelsixcheckBox->isChecked()) 359 | { 360 | if (count!=portNum) //判断是否到达最大可显示曲线数目 361 | { 362 | count++; 363 | } 364 | else 365 | { 366 | count=1; 367 | } 368 | ui->plotwidget->graph(5)->addData(key,PortMessageInt); //把数据增加到曲线上 369 | ui->plotwidget->graph(5)->removeDataBefore(key-qCeil(xAxismax*percent)); //清楚前面的数据 370 | } 371 | else 372 | { 373 | if (count!=portNum) //判断是否到达最大可显示曲线数目 374 | { 375 | count++; 376 | } 377 | else 378 | { 379 | count=1; 380 | } 381 | } 382 | break; 383 | case 7: 384 | if (ui->ChannelsevencheckBox->isChecked()) 385 | { 386 | if (count!=portNum) //判断是否到达最大可显示曲线数目 387 | { 388 | count++; 389 | } 390 | else 391 | { 392 | count=1; 393 | } 394 | ui->plotwidget->graph(6)->addData(key,PortMessageInt); //把数据增加到曲线上 395 | ui->plotwidget->graph(6)->removeDataBefore(key-qCeil(xAxismax*percent)); //清楚前面的数据 396 | } 397 | else 398 | { 399 | if (count!=portNum) //判断是否到达最大可显示曲线数目 400 | { 401 | count++; 402 | } 403 | else 404 | { 405 | count=1; 406 | } 407 | } 408 | break; 409 | case 8: 410 | if (ui->ChanneleightcheckBox->isChecked()) 411 | { 412 | if (count!=portNum) //判断是否到达最大可显示曲线数目 413 | { 414 | count++; 415 | } 416 | else 417 | { 418 | count=1; 419 | } 420 | ui->plotwidget->graph(7)->addData(key,PortMessageInt); //把数据增加到曲线上 421 | ui->plotwidget->graph(7)->removeDataBefore(key-qCeil(xAxismax*percent)); //清楚前面的数据 422 | } 423 | else 424 | { 425 | if (count!=portNum) //判断是否到达最大可显示曲线数目 426 | { 427 | count++; 428 | } 429 | else 430 | { 431 | count=1; 432 | } 433 | } 434 | break; 435 | default: 436 | if (ui->ChannelonecheckBox->isChecked()) 437 | { 438 | if (count!=portNum) //判断是否到达最大可显示曲线数目 439 | { 440 | count++; 441 | } 442 | else 443 | { 444 | count=1; 445 | } 446 | ui->plotwidget->graph(0)->addData(key,PortMessageInt); //把数据增加到曲线上 447 | ui->plotwidget->graph(0)->removeDataBefore(key-qCeil(xAxismax*percent)); //清楚前面的数据 448 | } 449 | else 450 | { 451 | if (count!=portNum) //判断是否到达最大可显示曲线数目 452 | { 453 | count++; 454 | } 455 | else 456 | { 457 | count=1; 458 | } 459 | } 460 | break; 461 | 462 | } 463 | 464 | ui->plotwidget->replot(); //重绘图案 465 | 466 | } 467 | 468 | } 469 | 470 | 471 | /*/////////////////////// 472 | * 函数名: void MyWidget::wrongdetectoneslot() 473 | * 功能: 用来接收来自次线程的错误信息,并弹出警告,并且关闭串口 474 | */ 475 | void MyWidget::wrongdetectoneslot() 476 | { 477 | QMessageBox::warning(this,"Error information","readdata have some mysterious problems!"); 478 | ChangeNum=0; 479 | thread.stop(); 480 | ui->OpenPortpushButton->setText("打开串口"); 481 | } 482 | 483 | 484 | /*/////////////////////// 485 | * 函数名: void MyWidget::wrongdetecttwoslot() 486 | * 功能: 用来接收来自次线程的错误信息,并弹出警告,并且关闭串口 487 | */ 488 | void MyWidget::wrongdetecttwoslot() 489 | { 490 | QMessageBox::information(this,"prompt information","no data can read!"); 491 | ChangeNum=0; 492 | thread.stop(); 493 | ui->OpenPortpushButton->setText("打开串口"); 494 | } 495 | 496 | 497 | /*/////////////////////// 498 | * 函数名: void MyWidget::availableportnameslot(QString str) 499 | * 功能: 用来接收来自次线程发送的串口名 500 | */ 501 | void MyWidget::availableportnameslot(QString str) 502 | { 503 | availportname=str; 504 | } 505 | 506 | /*/////////////////////// 507 | * 函数名: void MyWidget::on_sendcurvedatapushButton_clicked() 508 | * 功能: 检测输入并且发送图像参数并且初始化 509 | */ 510 | void MyWidget::on_sendcurvedatapushButton_clicked() 511 | { 512 | //初始化图像 513 | //qDebug()<xAxismaxlineEdit->text().isEmpty(); 514 | //判断输入框中有没有输入,如果没有输入则报错,然后再判断有没有修改,然后判断有没有重复按发送参数按钮, 515 | //如果重复按下则没有任何效果 516 | if (!ui->xAxismaxlineEdit->text().isEmpty() && !ui->yAxismaxlineEdit->text().isEmpty() && !ui->yAxisminlineEdit->text().isEmpty()) 517 | { 518 | 519 | if (ui->xAxismaxlineEdit->isModified() || ui->yAxismaxlineEdit->isModified() || ui->yAxisminlineEdit->isModified()) 520 | { 521 | ui->xAxismaxlineEdit->setModified(false); 522 | ui->yAxismaxlineEdit->setModified(false); 523 | ui->yAxisminlineEdit->setModified(false); 524 | 525 | if(0==ChangeNum)//按下之后还要判断是否处于关闭串口的状态,如果串口关闭 526 | { //那么初始化图像,如果串口打开那么关闭串口然后再初始化图像 527 | portNum=ui->ChannelnumcomboBox->currentText().toInt(); 528 | portplot(ui->plotwidget); 529 | //qDebug()<<1; 530 | //qDebug()<xAxismaxlineEdit->isModified()<yAxismaxlineEdit->isModified()<yAxisminlineEdit->isModified(); 531 | 532 | issendcurvedata=1; 533 | ui->plotwidget->replot();return; 534 | } 535 | else if (1==ChangeNum) 536 | { 537 | ChangeNum=0; 538 | thread.stop(); 539 | ui->OpenPortpushButton->setText("打开串口"); 540 | 541 | portNum=ui->ChannelnumcomboBox->currentText().toInt(); 542 | portplot(ui->plotwidget); 543 | //qDebug()<<2; 544 | issendcurvedata=1; 545 | ui->plotwidget->replot();return; 546 | } 547 | } 548 | if(portNum!=ui->ChannelnumcomboBox->currentText().toInt()) 549 | { 550 | 551 | if(0==ChangeNum)//按下之后还要判断是否处于关闭串口的状态,如果串口关闭 552 | { //那么初始化图像,如果串口打开那么关闭串口然后再初始化图像 553 | portNum=ui->ChannelnumcomboBox->currentText().toInt(); 554 | portplot(ui->plotwidget); 555 | //qDebug()<<3; 556 | issendcurvedata=1; 557 | ui->plotwidget->replot();return; 558 | } 559 | else if (1==ChangeNum) 560 | { 561 | ChangeNum=0; 562 | thread.stop(); 563 | ui->OpenPortpushButton->setText("打开串口"); 564 | //qDebug()<<4; 565 | portNum=ui->ChannelnumcomboBox->currentText().toInt(); 566 | portplot(ui->plotwidget); 567 | issendcurvedata=1; 568 | ui->plotwidget->replot();return; 569 | } 570 | 571 | 572 | } 573 | else 574 | { 575 | QMessageBox::warning(this,"Error information","no modified!"); 576 | 577 | } 578 | 579 | } 580 | else 581 | { 582 | QMessageBox::warning(this,"Error information","no input!"); 583 | 584 | } 585 | 586 | } 587 | 588 | /*///////////////////// 589 | * 函数名: void MyWidget::on_xAxisrangehorizontalSlider_sliderMoved(int position) 590 | * 功能:实时监测滑块位置 591 | */ 592 | void MyWidget::on_xAxisrangehorizontalSlider_sliderMoved(int position) 593 | { 594 | qDebug()<xAxisrangehorizontalSlider->value()/100.0; 596 | //qDebug()<plotwidget->savePng(fileName,861,711); 612 | //qDebug()<NumDisplayplainTextEdit->toPlainText(); 634 | text.replace(QString("\n"),QString("\r\n")); 635 | out<NumDisplayplainTextEdit->clear(); 654 | 655 | if (1==ChangeNum) 656 | { 657 | 658 | ChangeNum=0; 659 | thread.stop(); 660 | ui->OpenPortpushButton->setText("打开串口"); 661 | 662 | if (0==ChangeNum) //用来判断有没有关闭串口 663 | { 664 | ChangeNum=1; 665 | count=1; //在打开串口的时候初始化挑选数据的计数信号 666 | //////////////////////将用户输入的串口参数发送给次线程 667 | portname=ui->SelectPortcomboBox->currentText(); 668 | baudrate=ui->BaudRatecomboBox->currentText().toInt(); 669 | databits=ui->DataBitscomboBox->currentText().toInt(); 670 | stopbits=ui->StopBitscomboBox->currentIndex(); 671 | parity=ui->ParitycomboBox->currentIndex(); 672 | emit acceptdata(portname,baudrate,databits,stopbits,parity); 673 | ////////////////////// 674 | MyComm.sleep(200); //留给传递信号一点时间 675 | thread.start(); //开启线程打开串口 676 | //是否需要延时一段时间 677 | MyComm.sleep(200); //等待信号传递过来 678 | 679 | if (Justic==true) //判断串口是否打开,如果打开就把“打开串口”变成“关闭串口”。如果没打开就弹出警告 680 | { 681 | ui->OpenPortpushButton->setText("关闭串口"); 682 | } 683 | else 684 | { 685 | QMessageBox::warning(this,"Error information","the port can't open!"); 686 | } 687 | 688 | //int n; 689 | // n=MyComm.readData(Buffer,Count); 690 | 691 | //for(int i=0;iNumDisplayplainTextEdit->insertPlainText(QString(Buffer[i])); 694 | // } 695 | } 696 | } 697 | 698 | 699 | } 700 | 701 | /*/////////////////////// 702 | * 函数名: void MyWidget::on_ClearSendpushButton_clicked() 703 | * 功能: 清除输入框中数字 704 | */ 705 | void MyWidget::on_ClearSendpushButton_clicked() 706 | { 707 | ui->SendMessagetextEdit->clear(); 708 | } 709 | /*/////////////////////// 710 | * 函数名: void MyWidget::on_SendMessagepushButton_clicked() 711 | * 功能: 向串口中写数据,最大5位数 712 | */ 713 | void MyWidget::on_SendMessagepushButton_clicked() 714 | { 715 | char data[7]; 716 | long num,num2; 717 | int i; 718 | num=ui->SendMessagetextEdit->toPlainText().toInt(); 719 | num2=num; 720 | 721 | for(i=0;num2;i++) //判断有几位数 722 | { 723 | num2=num2/10; 724 | } 725 | 726 | for(int a=0;a 5 | #include "spcomm.h" 6 | #include 7 | #include 8 | #include 9 | #include "disnumthread.h" 10 | #include 11 | #include "qcustomplot.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | //#define Count 500 25 | 26 | namespace Ui { 27 | class MyWidget; 28 | } 29 | 30 | class MyWidget : public QWidget 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | explicit MyWidget(QWidget *parent = 0); 36 | ~MyWidget(); 37 | void portplot(QCustomPlot *customplot); //图像的初始化函数 38 | 39 | private slots: 40 | void on_SearchPortpushButton_clicked(); 41 | 42 | void on_OpenPortpushButton_clicked(); 43 | 44 | void on_sendcurvedatapushButton_clicked(); 45 | 46 | void on_xAxisrangehorizontalSlider_sliderMoved(int position); 47 | 48 | void on_savepicturepushButton_clicked(); 49 | 50 | void on_SaveDatapushButton_clicked(); 51 | 52 | void on_ClearpushButton_clicked(); 53 | 54 | void on_ClearSendpushButton_clicked(); 55 | 56 | void on_SendMessagepushButton_clicked(); 57 | 58 | private: 59 | Ui::MyWidget *ui; 60 | SPComm MyComm; 61 | int ChangeNum; //用来控制开启和关断的信号 62 | //char Buffer[Count]; 63 | QString str; 64 | 65 | QString portname; //用户设置的串口参数 66 | int databits; 67 | int baudrate; 68 | int stopbits; 69 | int parity; //用户设置的串口参数 70 | 71 | bool Justic; //用来存储次线程传递过来的串口开启状态判断信号 72 | DisNumThread thread; //次线程 73 | QString availportname; //用来存储次线程传递过来的串口名 74 | int count; //用来挑选数据的计数信号 75 | int portNum; //用来设置显示的曲线数目 76 | int xAxismax; //x轴的最大值 77 | int yAxismin; //y轴的最小值 78 | int yAxismax; //y轴的最大值 79 | double percent; //滑块的实时位置信号 80 | int issendcurvedata; //是否按下发送图像设置按钮信号 81 | //QTextCursor cursor; //实现自动滚屏 82 | 83 | signals: 84 | void acceptdata(QString portname,int baudrate,int databits,int stopbits,int parity); 85 | void availableportdetect(); 86 | void SendNumtoport(char* data,int i); 87 | 88 | public slots: 89 | void checkopenslot(bool justic); 90 | void SendStringslot(QString PortMessageString); 91 | void SendIntslot(int PortMessageInt); 92 | void wrongdetecttwoslot(); 93 | void wrongdetectoneslot(); 94 | void availableportnameslot(QString str); 95 | 96 | }; 97 | 98 | #endif // MYWIDGET_H 99 | -------------------------------------------------------------------------------- /mywidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MyWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1168 10 | 703 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 0 22 | 0 23 | 24 | 25 | 26 | 27 | 1168 28 | 703 29 | 30 | 31 | 32 | L助手 33 | 34 | 35 | 36 | :/new/prefix1/myserialport.ico:/new/prefix1/myserialport.ico 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 0 46 | 0 47 | 48 | 49 | 50 | 51 | 721 52 | 679 53 | 54 | 55 | 56 | 57 | 721 58 | 679 59 | 60 | 61 | 62 | 实时曲线显示区 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 0 72 | 0 73 | 74 | 75 | 76 | 77 | 600 78 | 480 79 | 80 | 81 | 82 | 83 | 861 84 | 711 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 0 94 | 0 95 | 96 | 97 | 98 | 图像显示设置 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 0 116 | 0 117 | 118 | 119 | 120 | Channel one 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 0 129 | 0 130 | 131 | 132 | 133 | Channel five 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 0 146 | 0 147 | 148 | 149 | 150 | Channel two 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 0 159 | 0 160 | 161 | 162 | 163 | Channel six 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 0 176 | 0 177 | 178 | 179 | 180 | Channel three 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 0 189 | 0 190 | 191 | 192 | 193 | Channel seven 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 0 206 | 0 207 | 208 | 209 | 210 | Channel four 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 0 219 | 0 220 | 221 | 222 | 223 | Channel eight 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 0 240 | 0 241 | 242 | 243 | 244 | 横坐标最小值 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 0 253 | 0 254 | 255 | 256 | 257 | 0 258 | 259 | 260 | true 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 0 273 | 0 274 | 275 | 276 | 277 | 横坐标最大值 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 0 286 | 0 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 0 300 | 0 301 | 302 | 303 | 304 | 纵坐标最小值 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 0 313 | 0 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 0 327 | 0 328 | 329 | 330 | 331 | 纵坐标最大值 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 0 340 | 0 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 0 360 | 0 361 | 362 | 363 | 364 | 需要打开的通道数 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 0 373 | 0 374 | 375 | 376 | 377 | 378 | 1 379 | 380 | 381 | 382 | 383 | 2 384 | 385 | 386 | 387 | 388 | 3 389 | 390 | 391 | 392 | 393 | 4 394 | 395 | 396 | 397 | 398 | 5 399 | 400 | 401 | 402 | 403 | 6 404 | 405 | 406 | 407 | 408 | 7 409 | 410 | 411 | 412 | 413 | 8 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 0 427 | 0 428 | 429 | 430 | 431 | 横坐标实时调节 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 0 440 | 0 441 | 442 | 443 | 444 | 100 445 | 446 | 447 | 100 448 | 449 | 450 | Qt::Horizontal 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 0 467 | 0 468 | 469 | 470 | 471 | 发送设置参数 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 0 480 | 0 481 | 482 | 483 | 484 | 保存图片 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 0 507 | 0 508 | 509 | 510 | 511 | 数据显示区 512 | 513 | 514 | 515 | 516 | 517 | 518 | 300 519 | 100 520 | 521 | 522 | 523 | 524 | 617 525 | 422 526 | 527 | 528 | 529 | false 530 | 531 | 532 | true 533 | 534 | 535 | false 536 | 537 | 538 | false 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 0 550 | 0 551 | 552 | 553 | 554 | 555 | 300 556 | 111 557 | 558 | 559 | 560 | 561 | 641 562 | 111 563 | 564 | 565 | 566 | 串口参数设置区 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 0 578 | 0 579 | 580 | 581 | 582 | 搜索串口 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 0 591 | 0 592 | 593 | 594 | 595 | 波特率 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 0 604 | 0 605 | 606 | 607 | 608 | 609 | 87 610 | 21 611 | 612 | 613 | 614 | 615 | 87 616 | 21 617 | 618 | 619 | 620 | 621 | 115200 622 | 623 | 624 | 625 | 626 | 57600 627 | 628 | 629 | 630 | 631 | 38400 632 | 633 | 634 | 635 | 636 | 19200 637 | 638 | 639 | 640 | 641 | 9600 642 | 643 | 644 | 645 | 646 | 4800 647 | 648 | 649 | 650 | 651 | 2400 652 | 653 | 654 | 655 | 656 | 1200 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 0 666 | 0 667 | 668 | 669 | 670 | 数据位 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 0 679 | 0 680 | 681 | 682 | 683 | 684 | 87 685 | 21 686 | 687 | 688 | 689 | 690 | 87 691 | 21 692 | 693 | 694 | 695 | 696 | 8 697 | 698 | 699 | 700 | 701 | 7 702 | 703 | 704 | 705 | 706 | 6 707 | 708 | 709 | 710 | 711 | 5 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 0 725 | 0 726 | 727 | 728 | 729 | 730 | 串口选择 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 0 740 | 0 741 | 742 | 743 | 744 | 停止位 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 0 753 | 0 754 | 755 | 756 | 757 | 758 | 72 759 | 21 760 | 761 | 762 | 763 | 764 | 87 765 | 21 766 | 767 | 768 | 769 | 770 | 1 771 | 772 | 773 | 774 | 775 | 1.5 776 | 777 | 778 | 779 | 780 | 2 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 0 790 | 0 791 | 792 | 793 | 794 | 奇偶校验 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 0 803 | 0 804 | 805 | 806 | 807 | 808 | 87 809 | 21 810 | 811 | 812 | 813 | 814 | 87 815 | 21 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 奇校验 826 | 827 | 828 | 829 | 830 | 偶校验 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 0 847 | 0 848 | 849 | 850 | 851 | 852 | 420 853 | 200 854 | 855 | 856 | 857 | 交互区 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 0 869 | 0 870 | 871 | 872 | 873 | 打开串口 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 0 882 | 0 883 | 884 | 885 | 886 | 保存数据 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 0 895 | 0 896 | 897 | 898 | 899 | 清除接收 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 0 908 | 0 909 | 910 | 911 | 912 | 16进制 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 0 930 | 0 931 | 932 | 933 | 934 | 935 | 130 936 | 16777215 937 | 938 | 939 | 940 | 发送 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 0 949 | 0 950 | 951 | 952 | 953 | 清除发送 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | QCustomPlot 976 | QWidget 977 |
qcustomplot.h
978 | 1 979 |
980 |
981 | 982 | 983 | 984 | 985 |
986 | -------------------------------------------------------------------------------- /resource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | myserialport.ico 4 | 5 | 6 | -------------------------------------------------------------------------------- /spcomm.cpp: -------------------------------------------------------------------------------- 1 | #include "spcomm.h" 2 | 3 | 4 | 5 | /*///////////////////// 6 | * 函数名:构造函数 7 | * 功能:初始化波特率为115200,串口名为空 8 | * 无奇偶校验位,8位数据位,1位停止位 9 | * 无控制流 10 | */ 11 | SPComm::SPComm() 12 | { 13 | 14 | m_serialPort = new QSerialPort(); 15 | m_serialPortInfo=new QSerialPortInfo(); 16 | 17 | m_baudRate = 115200; 18 | 19 | m_portName = ""; 20 | 21 | m_Parity=0; 22 | 23 | m_DataBits=8; 24 | 25 | m_StopBits=1; 26 | 27 | m_FlowControl=0; 28 | 29 | } 30 | 31 | 32 | /*////////////////////////// 33 | * 函数名: 析构函数 34 | * 功能: delete new 35 | */ 36 | SPComm::~SPComm() 37 | { 38 | 39 | delete m_serialPort; 40 | delete m_serialPortInfo; 41 | } 42 | //************************************************************************* 43 | /*///////////////////////////////// 44 | * 函数名:void SPComm::setPortName(const QString &name) 45 | * 功能:设置串口的名字 46 | */ //window 下用"com1" linux下用"/dev/ttyS0" 47 | void SPComm::setPortName(const QString &name) //这里const的意思是name这个引用变量的值在下面的具体实现中不会被改变 48 | { 49 | 50 | m_portName = name; 51 | 52 | } 53 | 54 | 55 | /*////////////////////////////// 56 | * 函数名:QString SPComm::portName() const 57 | * 功能:用来获取串口的名字 58 | */ 59 | QString SPComm::portName() const //const成员函数 60 | { 61 | 62 | return m_portName; 63 | 64 | } 65 | 66 | //************************************************************************* 67 | /*//////////////////////////////// 68 | * 函数名:static QSerialPort::BaudRate getBaudRate(int baudRate) 69 | * 功能:这个函数用来设置波特率,打开串口的时候用到 70 | * 输入一个int型的波特率数值,返回一个相应的 71 | * 波特率枚举数 72 | */ 73 | QSerialPort::BaudRate SPComm::getBaudRate(int baudRate) //BaudRate是一个枚举量,在作用域QSerialPort中 74 | { 75 | switch (baudRate) 76 | { 77 | case 1200: 78 | return QSerialPort::Baud1200; 79 | case 2400: 80 | return QSerialPort::Baud2400; 81 | case 4800: 82 | return QSerialPort::Baud4800; 83 | case 9600: 84 | return QSerialPort::Baud9600; 85 | case 19200: 86 | return QSerialPort::Baud19200; 87 | case 38400: 88 | return QSerialPort::Baud38400; 89 | case 57600: 90 | return QSerialPort::Baud57600; 91 | case 115200: 92 | return QSerialPort::Baud115200; 93 | default: 94 | return QSerialPort::UnknownBaud; 95 | 96 | } 97 | 98 | } 99 | 100 | /*//////////////////////////////// 101 | * 函数名:void SPComm::setBaudRate(int baudRate) 102 | * 功能:设置波特率 9600 19200 38400 103 | */ 104 | void SPComm::setBaudRate(int baudRate) 105 | { 106 | 107 | m_baudRate = baudRate; 108 | 109 | } 110 | 111 | /*/////////////////////////////// 112 | * 函数名:int SPComm::baudRate() const 113 | * 功能: 获取波特率值 114 | */ 115 | 116 | int SPComm::baudRate() const 117 | { 118 | return m_baudRate; 119 | } 120 | 121 | //************************************************************************* 122 | /*///////////////////////////////// 123 | * 函数名:QSerialPort::Parity SPComm::getParity(int Parity) 124 | * 功能:将输入的奇偶校验位数转化为Qt内的表示 125 | * 奇偶校验位的枚举类值 126 | */ 127 | QSerialPort::Parity SPComm::getParity(int Parity) 128 | { 129 | switch(Parity) 130 | { 131 | case 0: 132 | return QSerialPort::NoParity; 133 | case 2: 134 | return QSerialPort::EvenParity; 135 | case 3: 136 | return QSerialPort::OddParity; 137 | case 4: 138 | return QSerialPort::SpaceParity; 139 | case 5: 140 | return QSerialPort::MarkParity; 141 | default: 142 | return QSerialPort::UnknownParity; 143 | } 144 | } 145 | 146 | /*//////////////////////////// 147 | * 函数名: void SPComm::setParity(int Parity) 148 | * 功能: 设置奇偶校验位 149 | */ 150 | void SPComm::setParity(int Parity) 151 | { 152 | m_Parity=Parity; 153 | } 154 | 155 | 156 | /*/////////////////////////// 157 | * 函数名: int SPComm::Parity() const 158 | * 功能: 返回奇偶校验位 159 | */ 160 | int SPComm::Parity() const 161 | { 162 | return m_Parity; 163 | } 164 | 165 | 166 | //************************************************************************ 167 | /*////////////////////////////// 168 | *函数名: QSerialPort::DataBits SPComm::getDataBits(int DataBits) 169 | *功能: 将输入的数据位值转化为Qt内的表示 170 | * 数据位的枚举类值 171 | */ 172 | QSerialPort::DataBits SPComm::getDataBits(int DataBits) 173 | { 174 | switch(DataBits) 175 | { 176 | case 5: 177 | return QSerialPort::Data5; 178 | case 6: 179 | return QSerialPort::Data6; 180 | case 7: 181 | return QSerialPort::Data7; 182 | case 8: 183 | return QSerialPort::Data8; 184 | default: 185 | return QSerialPort::UnknownDataBits; 186 | } 187 | } 188 | 189 | /*//////////////////////// 190 | * 函数名: void SPComm::setDataBits(int DataBits) 191 | * 功能: 设置数据位 192 | */ 193 | void SPComm::setDataBits(int DataBits) 194 | { 195 | m_DataBits=DataBits; 196 | } 197 | 198 | /*////////////////////////// 199 | *函数名: int SPComm::DataBits() const 200 | *功能: 返回数据位值 201 | */ 202 | int SPComm::DataBits() const 203 | { 204 | return m_DataBits; 205 | } 206 | 207 | //************************************************************************ 208 | /*//////////////////////////////// 209 | *函数名: QSerialPort::StopBits SPComm::getStopBits(int StopBits) 210 | *功能: 将输入的停止位值转化为Qt内的表示 211 | * 停止位值的枚举类值 212 | */ 213 | QSerialPort::StopBits SPComm::getStopBits(int StopBits) 214 | { 215 | switch(StopBits) 216 | { 217 | case 1: 218 | return QSerialPort::OneStop; 219 | case 3: 220 | return QSerialPort::OneAndHalfStop; 221 | case 2: 222 | return QSerialPort::TwoStop; 223 | default: 224 | return QSerialPort::UnknownStopBits; 225 | } 226 | } 227 | /*///////////////////////////// 228 | * 函数名:void SPComm::setStopBits(int StopBits) 229 | * 功能: 设置停止位 230 | */ 231 | void SPComm::setStopBits(int StopBits) 232 | { 233 | m_StopBits=StopBits; 234 | } 235 | 236 | /*/////////////////////////// 237 | * 函数名: int SPComm::StopBits() const 238 | * 功能: 返回停止位 239 | */ 240 | int SPComm::StopBits() const 241 | { 242 | return m_StopBits; 243 | } 244 | 245 | //************************************************************************* 246 | /*函数名:QSerialPort::FlowControl SPComm::getFlowControl(int FlowControl) 247 | * 功能: 将输入的控制流值转化为Qt内的表示 248 | * 控制流的枚举类值 249 | */ 250 | QSerialPort::FlowControl SPComm::getFlowControl(int FlowControl) 251 | { 252 | switch(FlowControl) 253 | { 254 | case 0: 255 | return QSerialPort::NoFlowControl; 256 | case 1: 257 | return QSerialPort::HardwareControl; 258 | case 2: 259 | return QSerialPort::SoftwareControl; 260 | default: 261 | return QSerialPort::UnknownFlowControl; 262 | } 263 | } 264 | 265 | /*/////////////////////////////////// 266 | *函数名: void SetFlowControl(int FlowControl) 267 | *功能: 设置控制流 268 | */ 269 | void SPComm::SetFlowControl(int FlowControl) 270 | { 271 | m_FlowControl=FlowControl; 272 | } 273 | 274 | /*////////////////////////////////// 275 | * 函数名: int SPComm::FlowControl() const 276 | * 功能: 返回控制流值 277 | */ 278 | int SPComm::FlowControl() const 279 | { 280 | return m_FlowControl; 281 | } 282 | 283 | 284 | //************************************************************************* 285 | /*/////////////////////////////// 286 | * 函数名: bool SPComm::isOpen() const 287 | * 功能: 检测是否打开串口 288 | */ 289 | bool SPComm::isOpen() const 290 | { 291 | return m_serialPort->isOpen(); 292 | } 293 | 294 | /*/////////////////////////////// 295 | *函数名: QList SPComm::getavailablePost() const 296 | *功能: 获取串口信息,如果检测到串口那么返回串口名,如果没有 297 | * 则返回空字符串 298 | */ 299 | QString SPComm::getavailablePort() const 300 | { 301 | 302 | foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) 303 | { 304 | qDebug() << "Name : " << info.portName(); 305 | qDebug() << "Description : " << info.description(); 306 | qDebug() << "Manufacturer: " << info.manufacturer(); 307 | qDebug() << "Serial Number: " << info.serialNumber(); 308 | qDebug() << "System Location: " << info.systemLocation(); 309 | return info.portName(); 310 | } 311 | return ""; 312 | 313 | } 314 | 315 | /*////////////////////////////// 316 | * 函数名:bool SPComm::open() 317 | * 功能:用来打开串口,调用前,先设置串口名字和波特率 318 | * 数据位,停止位,奇偶校验率。默认无控制流,如果 319 | * 以后要改直接把QSerialPort::NoFlowControl 320 | * 改成getFlowControl(m_FlowControl)就行了 321 | * 默认读缓存大小1024字节,默认双向打开即可读可写 322 | */ 323 | bool SPComm::open() 324 | { 325 | if (m_serialPort->isOpen()) //先判断是否已经打开了串口 326 | { 327 | return true; 328 | } 329 | m_serialPort->setPortName(m_portName); 330 | m_serialPort->setBaudRate(getBaudRate(m_baudRate)); 331 | m_serialPort->setParity(getParity(m_Parity)); 332 | m_serialPort->setDataBits(getDataBits(m_DataBits)); 333 | m_serialPort->setStopBits(getStopBits(m_StopBits)); 334 | m_serialPort->setFlowControl(QSerialPort::NoFlowControl); 335 | m_serialPort->setReadBufferSize(1024); 336 | return m_serialPort->open(QIODevice::ReadWrite); 337 | 338 | } 339 | 340 | 341 | /*///////////////////////// 342 | * 函数名: void SPComm::close() 343 | * 功能: 关闭串口 344 | */ 345 | void SPComm::close() 346 | 347 | { 348 | if (m_serialPort->isOpen()) 349 | { 350 | 351 | m_serialPort->close(); 352 | 353 | } 354 | } 355 | 356 | 357 | /*////////////////////////// 358 | * 函数名: bool SPComm::clear() 359 | * 功能: 重启串口,清楚数据 360 | */ 361 | bool SPComm::clear() 362 | 363 | { 364 | if (m_serialPort->isOpen()) 365 | { 366 | m_serialPort->clear(); 367 | 368 | this->close(); 369 | 370 | return this->open(); 371 | } 372 | return false; 373 | } 374 | 375 | 376 | /*/////////////////////////// 377 | * 函数名:int SPComm::readData(char *buffer, int count, int timeout) 378 | * 功能: 读数据,将数据存在buffer数组中,最大 379 | * 读count个数据 380 | */ 381 | int SPComm::readData(char *buffer, int count, int timeout) 382 | { 383 | int len = 0; 384 | 385 | forever //无限循环 386 | { 387 | /* 返回read到的数据个数,从buffer[0] 388 | 开始存储,如果len不等于0,那就从后面空的空间 389 | 开始存储,count是最大的存储长度,如果超过这个 390 | * 长度那就不读了,如果没有超过这个长度那就接在后面继续读 391 | */ 392 | int n = m_serialPort->read(&buffer[len], count - len); 393 | if (n == -1) 394 | { 395 | return -1; 396 | } 397 | else if (n == 0 && !m_serialPort->waitForReadyRead(timeout))//返回0说明没有数据,waitforreadyread是一个读写延迟,如果在timeout的时间内没有数据可读,那么返回假,如果有数据可读那么返回真 398 | { 399 | return -2; 400 | } 401 | else 402 | { 403 | len += n; //检测buffer中的空间有没有被塞满 404 | 405 | if (count == len) 406 | 407 | break; 408 | } 409 | } 410 | return len; 411 | } 412 | 413 | 414 | /*//////////////////////////// 415 | * 函数名: int SPComm::writeData(char *data, int size) 416 | * 功能: 发送数据到串口 比如发送协议 417 | */ 418 | int SPComm::writeData(char *data, int size) 419 | { 420 | 421 | int len = 0; 422 | 423 | forever 424 | { 425 | 426 | int n = m_serialPort->write(data, size - len); 427 | 428 | if (n == -1) 429 | { 430 | 431 | return -1; 432 | 433 | } 434 | else 435 | { 436 | 437 | len += n; 438 | if (size == len) 439 | break; 440 | } 441 | } 442 | 443 | return len; 444 | 445 | } 446 | 447 | 448 | 449 | //******************************************************************************* 450 | /*////////////////////// 451 | *函数: sleep() 452 | *功能:延时一段时间 453 | *////////////////////// 454 | void SPComm::sleep(unsigned int msec) 455 | { 456 | QTime dieTime = QTime::currentTime().addMSecs(msec); 457 | while( QTime::currentTime() < dieTime ) 458 | QCoreApplication::processEvents(QEventLoop::AllEvents, 100); 459 | } 460 | -------------------------------------------------------------------------------- /spcomm.h: -------------------------------------------------------------------------------- 1 | #ifndef SPCOMM_H 2 | #define SPCOMM_H 3 | /*///////////////////////// 4 | * 类名:SPComm 5 | * 功能:提供一个支持串口操作的类,可以基于这个类进行后续的开发。 6 | * 调用前,需要先调用相应的函数来设置串口名字和波特率,数据位,停止位,奇偶校验率。默认 7 | * 无控制流默认读缓存大小1024字节,默认双向打开即可读可写。必须先设置串口名才能打开串 8 | * 口。 9 | * 调用open函数时返回true则说明串口打开成功,返回false则说明打开失败 10 | * 调用clear函数时返回true则说明重启清除数据成功,返回false说明串口未打开或打开失败 11 | * 调用readData函数时返回-1说明有错误发生,比如读只写的文件,返回-2说明没有数据可读 12 | * 或者说数据已经读完,如果数组中有数据那么说明数据已经读完,如果是 13 | * 空数组说明串口中没有数据。返回一个非零的正数说明读成功,返回的是 14 | * 最大可读个数,说明之后可能还有数据未读。 15 | * 调用writeData函数时返回-1说明写错误。如果返回其他数说明写未完成,如果返回数组的最 16 | * 大数则说明写完成。 17 | * 调用getavailablePort函数如果检测到串口那么返回串口名,如果没有则返回空字符串 18 | * 19 | * 函数名-------------形参以及返回值-------------作用 20 | *参数设置函数 setPortName QString &name;无 设置需要打开的串口 21 | * setBaudRate int baudRate;无 设置波特率 22 | * setParity int Parity;无 设置奇偶校验性 23 | * setDataBits int DataBits;无 设置数据位 24 | * setStopBits int StopBits;无 设置停止位 25 | * ----------------------------------------------------------- 26 | * 波特率,奇偶校验位,数据位,停止位的值请查看QSerialPort中相应的枚举值 27 | * ----------------------------------------------------------- 28 | *功能函数 isOpen 无;bool 检测串口是否打开 29 | * getavailablePost 无;QList 获取可使用的串口信息 30 | * portName 无;QString 获取使用的串口名 31 | * baudRate 无;int 获取使用的波特率 32 | * Parity 无;int 获取使用的奇偶校验位 33 | * DataBits 无;int 获取使用的数据位 34 | * StopBits 无;int 获取使用的停止位 35 | * open 无;bool 打开使用的串口 36 | * close 无;无 关闭使用中的串口 37 | * clear 无;bool 重启串口,清除数据 38 | * readData char *buffer, int count, int timeout;int 39 | * 把数据读到buffer这 40 | * 个数组中,count指最大的读取个数,timeout指扫描 41 | * 检测串口中有没有数据传过来的时间,相当于是读延迟 42 | * 43 | * writeData char *data, int size 把最大size大小的数 44 | * 据从data这个数组中写到串口里 45 | * ------------------------------------------------------------ 46 | * sleep unsigned int msec;无 延时msec毫秒 47 | */ 48 | 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | class SPComm 58 | { 59 | 60 | 61 | public: 62 | SPComm(); //构造函数 63 | ~SPComm(); 64 | 65 | bool isOpen() const; //检测串口是否打开 66 | QString getavailablePort() const; //获取串口信息 67 | void setPortName(const QString &name); //设置串口名 68 | QString portName() const; //获得串口名 69 | 70 | void setBaudRate(int baudRate); //设置波特率 71 | int baudRate() const; //返回波特率 72 | 73 | void setParity(int Parity); //设置奇偶检验 74 | int Parity() const; //返回奇偶校验 75 | 76 | void setDataBits(int DataBits); //设置数据位 77 | int DataBits() const; //返回数据位 78 | 79 | void setStopBits(int StopBits); //设置停止位 80 | int StopBits() const; //返回停止位 81 | 82 | void SetFlowControl(int FlowControl); //设置控制流 83 | int FlowControl() const; //返回控制流 84 | 85 | virtual bool open(); //打开串口 86 | virtual void close(); //关闭串口 87 | virtual bool clear(); //重启串口,清除数据 88 | 89 | int readData(char *buffer, int count, int timeout = 1000); //读数据 90 | int writeData(char *data, int size); //写数据 91 | //int write(char ch); 92 | 93 | 94 | //静态成员函数 95 | static QSerialPort::BaudRate getBaudRate(int baudRate); 96 | static QSerialPort::Parity getParity(int Parity); 97 | static QSerialPort::DataBits getDataBits(int DataBits); 98 | static QSerialPort::StopBits getStopBits(int StopBits); 99 | static QSerialPort::FlowControl getFlowControl(int FlowControl); 100 | 101 | //************************************************************************* 102 | void sleep(unsigned int msec); 103 | //************************************************************************* 104 | 105 | protected: 106 | QString m_portName; 107 | int m_baudRate; 108 | int m_Parity; 109 | int m_DataBits; 110 | int m_StopBits; 111 | int m_FlowControl; 112 | 113 | QSerialPort *m_serialPort; 114 | QSerialPortInfo *m_serialPortInfo; 115 | }; 116 | 117 | #endif // SPCOMM_H 118 | --------------------------------------------------------------------------------