串口接收不定长数据的各种不合格版本
#include "mainwindow.h"#include "ui_mainwindow.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include <Qapplication>#include <QTime>#include <QDateTime>#include <QIODevice>#include <QDir>#include <QImage>#ifdef __cplusplusextern "C"{#endif /* __cplusplus */extern FILE * fopen(const char * path,const char * mode);extern int fclose( FILE *fp );extern size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;extern size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);#ifdef __cplusplus}#endif /* __cplusplus */MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ cnt_read = 0; cnt_need = 0; photo_state = BEGIN; serial_state = READ_HDR; data_need = 0; node_id = 0; node_type = 0; cnt = 0; seqnb = 0; ui->setupUi(this); initSeialPort();}MainWindow::~MainWindow(){ serial.close(); delete ui;}void MainWindow::on_serialSelect_currentIndexChanged(const QString &arg1){ QSerialPortInfo info; QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts(); int i = 0; foreach (info, infos) { if(info.portName() == arg1) break; i++; } if(i != infos.size ()){//can find ui->label->setText("[已开启]"); serial.close(); serial.setPort(info); serial.open(QIODevice::ReadWrite); //读写打开 serial.setBaudRate(QSerialPort::Baud115200); //波特率 serial.setDataBits(QSerialPort::Data8); //数据位 serial.setParity(QSerialPort::NoParity); //无奇偶校验 serial.setStopBits(QSerialPort::OneStop); //停止位 serial.setFlowControl(QSerialPort::NoFlowControl); //无控制 } else { serial.close(); ui->label->setText("[出错]"); }}#if 1void MainWindow::serialRead(){ QByteArray temp = serial.readAll(); if(!temp.isEmpty()) { my_stream.append(temp); if(my_stream.contains("end")) { qDebug()<<my_stream.length(); QByteArray array=my_stream.left(my_stream.indexOf("end")); //QImage image; //bool flag=image.loadFromData((const uchar *)array.data(),array.size()); if (1) { QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间 //设置显示格式,注意QFile的文件名不能有:(冒号)等特殊字符 QString str = time.toString("yyyy-MM-dd-hh-mm-ss"); str += ".jpg"; qDebug()<<str; //image.save(str); dst.setFileName(str);//将时间作为文件名 //QDir::currentPath() bool isOK = dst.open(QIODevice::WriteOnly|QIODevice::Append); if(isOK == false) { qDebug()<<"dst.open err"; this->close(); } dst.write(array); dst.close(); //QPixmap pixmap=QPixmap::fromImage(image); //ui->labelImage->setPixmap(pixmap); } my_stream.clear(); //my_stream = my_stream.right(my_stream.length()-my_stream.indexOf("end")-3); } }}#endif#if 0bytesToInt(QByteArray bytes) { int addr = bytes[0] & 0x000000FF; addr |= ((bytes[1] << 8) & 0x0000FF00); addr |= ((bytes[2] << 16) & 0x00FF0000); addr |= ((bytes[3] << 24) & 0xFF000000); return addr;}void MainWindow::serialRead(){ int cnt_tmp; static unsigned int seq_old = 0; //static unsigned int seq_new = 0; static unsigned int pkt_cnt = 0; bool FAIL_FLAG = false; QByteArray tmp_data; char ACK[1] = {1}; if(serial.bytesAvailable() >= 8) { switch(serial_state) { case READ_HDR: cnt_need = HDR_LEN - cnt_read; tmp_data = serial.read(cnt_need); if(tmp_data.isEmpty()) return ; cnt_tmp = tmp_data.length(); qDebug()<<"0:"<<cnt_tmp; cnt_read += cnt_tmp; read_data += tmp_data; if(HDR_LEN == cnt_read) { cnt_read = 0; cnt_need = 0; serial_state = READ_DATA; node_type = bytesToInt(read_data.mid(0,1)); node_id = bytesToInt(read_data.mid(1,1)); data_need = bytesToInt(read_data.mid(7,1)); seqnb = bytesToInt(read_data.mid(6,1))*256 + bytesToInt(read_data.mid(5,1)); if(seqnb == seq_old) FAIL_FLAG = true; seq_old = seqnb; //qDebug()<<"1:"<<data_need; //操作头部数据 QString str_display; QString str = read_data.toHex().data(); str = str.toUpper(); str_display.clear(); for(int i = 0;i < str.length();i+= 2) { QString st = str.mid(i,2); str_display += st; str_display += " "; } //显示数据 ui->textEdit->insertPlainText(str_display); read_data.clear(); } break; case READ_DATA: if(node_type == 1) { cnt_need = data_need - cnt_read; qDebug()<<"2:"<<cnt_need; tmp_data = serial.read(cnt_need); if(tmp_data.isEmpty()) return ; cnt_tmp = tmp_data.length(); cnt_read += cnt_tmp; read_data += tmp_data; //qDebug()<<"3:"<<cnt_read; cnt += cnt_tmp; if(data_need == cnt_read) { cnt_read = 0; cnt_need = 0; serial_state = READ_HDR; //操作有效数据 my_stream.append(read_data); if(my_stream.contains("end")) { qDebug()<<my_stream.length(); QByteArray array=my_stream.left(my_stream.indexOf("end")); //QImage image; //bool flag=image.loadFromData((const uchar *)array.data(),array.size()); if (1) { QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间 //设置显示格式,注意QFile的文件名不能有:(冒号)等特殊字符 QString str = time.toString("yyyy-MM-dd-hh-mm-ss"); str += ".jpg"; qDebug()<<str; //image.save(str); dst.setFileName(str);//将时间作为文件名 //QDir::currentPath() bool isOK = dst.open(QIODevice::WriteOnly|QIODevice::Append); if(isOK == false) { qDebug()<<"dst.open err"; this->close(); } dst.write(array); dst.close(); //QPixmap pixmap=QPixmap::fromImage(image); //ui->labelImage->setPixmap(pixmap); } my_stream.clear(); //my_stream = my_stream.right(my_stream.length()-my_stream.indexOf("end")-3); }#if 0 //if(photo_state == END && strcmp("end/r/n",str_tmp) == 0) //if(strcmp("end",str_tmp) == 0) if(read_data.contains("end")) { dst.close(); qDebug()<<"end"; qDebug()<<cnt; read_data.clear(); my_stream.clear(); photo_state = BEGIN; serial.write(ACK); return ; } //if(photo_state == BEGIN && strcmp("begin/r/n",str_tmp) == 0) //if(strcmp("begin/r/n",str_tmp) == 0) if(read_data.contains("begin")) { QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间 //设置显示格式,注意QFile的文件名不能有:(冒号)等特殊字符 QString str = time.toString("yyyy-MM-dd-hh-mm-ss"); str += ".jpg"; qDebug()<<str; dst.setFileName(str);//将时间作为文件名 //QDir::currentPath() bool isOK = dst.open(QIODevice::WriteOnly|QIODevice::Append); if(isOK == false) { qDebug()<<"dst.open err"; this->close(); } //my_stream.setDevice(&dst); read_data.clear(); photo_state = READING; serial.write(ACK); return ; } //if(photo_state == READING) { if(FAIL_FLAG == true) { serial.write(ACK); read_data.clear(); return; } qDebug()<<"==========>"<<seqnb; pkt_cnt++; my_stream += read_data; if(data_need < REAL_LEN) { photo_state = END; dst.write(my_stream); my_stream.clear(); } if(pkt_cnt == 32) { pkt_cnt = 0; dst.write(my_stream); my_stream.clear(); } //dst.write(read_data); //my_stream<<read_data; serial.write(ACK); read_data.clear(); } data_need = 0;#endif#if 0 switch(photo_state) { //判断是不是一张新的图片 //如果是beigin开头,新建文件 case BEGIN: if(strcmp("begin/r/n",str_tmp) == 0) { QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间 //设置显示格式,注意QFile的文件名不能有:(冒号)等特殊字符 QString str = time.toString("yyyy-MM-dd-hh-mm-ss"); str += ".jpg"; qDebug()<<str; dst.setFileName(str);//将时间作为文件名 //QDir::currentPath() bool isOK = dst.open(QIODevice::WriteOnly|QIODevice::Append); if(isOK == false) { qDebug()<<"dst.open err"; this->close(); } //my_stream.setDevice(&dst); read_data.clear(); photo_state = READING; serial.write(ACK); return ; } break; //如果不是begin开头,将数据插入原来打开文件的末尾 case READING: dst.write(read_data); //my_stream.clear(); if(data_need < REAL_LEN) photo_state = END; //my_stream<<read_data; serial.write(ACK); read_data.clear(); break; //判断图片是否传送完毕--接收到的是否是end case END: if(strcmp("end/r/n",str_tmp) == 0) { dst.close(); qDebug()<<"end"; qDebug()<<cnt; read_data.clear(); photo_state = BEGIN; serial.write(ACK); return ; } break; } data_need = 0;#endif } } break; default: break; } }}#endif#if 0#define MAX_BUF 80#define SRC "D:/1.jpg"#define DST "D:/2.jpg"void MainWindow::serialRead(){ static unsigned int length = 0; if(serial.bytesAvailable() >=13 ) { //读串口数据 QByteArray serial_data = serial.read(72); char *str_tmp=serial_data.data(); unsigned int low = (unsigned int)str_tmp[5]; unsigned int high = (unsigned int)str_tmp[6]; unsigned int seqnb = high*256+low; qDebug()<<serial_data.length()<<seqnb; //判断图片是否传送完毕--接收到的是否是end if(strcmp("end/r/n",str_tmp+8) == 0) { dst.close(); qDebug()<<"end"; qDebug()<<length; return ; } //判断是不是一张新的图片 //如果是beigin开头,新建文件 if(strcmp("begin/r/n",str_tmp+8) == 0) { QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间 //设置显示格式,注意QFile的文件名不能有:(冒号)等特殊字符 QString str = time.toString("yyyy-MM-dd-hh-mm-ss"); str += ".jpg"; qDebug()<<str; dst.setFileName(str);//将时间作为文件名 //QDir::currentPath() bool isOK = dst.open(QIODevice::WriteOnly|QIODevice::Append); if(isOK == false) { qDebug()<<"dst.open err"; this->close(); } return ; } //如果不是begin开头,将数据插入原来打开文件的末尾 dst.write(serial_data); length += (serial_data.length()-8); //将数据格式化 QString str_display; QString str = serial_data.toHex().data(); str = str.toUpper(); str_display.clear(); for(int i = 0;i < str.length();i+= 2) { QString st = str.mid(i,2); str_display += st; str_display += " "; } //显示数据 ui->textEdit->insertPlainText(str_display); }}#endif#if 0void MainWindow::serialRead(){ QByteArray tmp_buf = serial.readAll(); static QByteArray buf; static FILE* dst = NULL; static bool OPEN_FLAG = false; static int flag = 0; static int cnt_update = 0; static int all_cnt = 0; static int tmp_cnt = 0; int off_cnt = 0; QByteArray remain_buf; char *remain_str=NULL; if(cnt_update == 0) { all_cnt = *(tmp_buf.data()); qDebug()<<"cnt_update == 0:/t"<<all_cnt<<endl; cnt_update = 2; } //qDebug()<<"tmp_buf:"<<tmp_buf<<endl;#if 0 remain_str = tmp_buf.data()+2; qDebug()<<"remain_str:"<<remain_str<<endl; remain_buf = QByteArray(remain_str); qDebug()<<"remain_buf:"<<remain_buf<<endl; tmp_buf.resize(tmp_buf.size()-2); qDebug()<<"new tmp_buf:"<<tmp_buf<<endl;#endif#if 1 tmp_cnt += tmp_buf.size(); //qDebug()<<"tmp_buf.size:"<<tmp_buf.size()<<endl; //qDebug()<<"tmp_cnt:"<<tmp_cnt<<endl; if(tmp_cnt < all_cnt) { buf += tmp_buf; qDebug()<<"tmp_cnt <<<<<<<<<<<<<<<<<<<< all_cnt/t"<<endl;//(tmp_buf)<<"/ttmp_size:"<<tmp_buf.size()<<"/ttmpcnt:"<<tmp_cnt<<endl; //qDebug()<<"buf:"<<buf<<endl; return ; }else if (tmp_cnt > all_cnt){ off_cnt = tmp_cnt - all_cnt; remain_str = tmp_buf.data()+(tmp_buf.size()-off_cnt); remain_buf = QByteArray(remain_str); //qDebug()<<"tmp_buf:"<<tmp_buf<<endl; //qDebug()<<"remain_buf:"<<remain_buf<<endl; tmp_buf.resize(tmp_buf.size()-off_cnt); //qDebug()<<"tmp_cnt >>>>>>>>>>> all_cnt"<<endl;//(tmp_buf)<<"/ttmp_size:"<<tmp_buf.size()<<"/ttmpcnt:"<<tmp_cnt<<endl; buf += tmp_buf; //qDebug()<<"buf:"<<buf<<endl; cnt_update = 1; } else { buf += tmp_buf; //qDebug()<<"tmp_cnt================ all_cnt"<<endl;//(tmp_buf)<<"/ttmp_size:"<<tmp_buf.size()<<"/ttmpcnt:"<<tmp_cnt<<endl; //qDebug()<<"buf:"<<buf<<endl; cnt_update = 0; } //ui->textEdit->append(buf);#if 1 if((all_cnt == 7)&& (strcmp((buf.data()+1),"begin")==0) ) { dst = fopen(DST,"wb+"); OPEN_FLAG = true; flag = 1; } else if((all_cnt == 5)&& (strcmp((buf.data()+1),"end")==0) ) { fclose(dst); OPEN_FLAG = false; flag = 2; }else{ dst = fopen(DST,"ab+"); OPEN_FLAG = true; flag = 3; } if(NULL == dst) { qDebug()<<"dst"<<" error!/n"; OPEN_FLAG = false; } if( (OPEN_FLAG == true) && ( flag == 3) ) { char * str = buf.data(); //qDebug()<<all_cnt<<endl; fwrite(&(str[1]),1,all_cnt-1,dst); } fclose(dst);#endif //qDebug()<<buf<<(int)all_cnt<<endl; ui->textEdit->append(buf); tmp_cnt = 0; //qDebug()<<all_cnt<<endl; buf.clear(); all_cnt = 0; if(cnt_update == 1) { all_cnt = *(remain_buf.data()); cnt_update = 2; qDebug()<<"cnt_update == 1:/t"<<all_cnt<<endl; buf += remain_buf; tmp_cnt += remain_buf.size(); //qDebug()<<"tmp_cnt:"<<tmp_cnt<<endl; }#endif}#endifvoid MainWindow::on_sendButton_clicked(){ if(ui->lineEdit->text().isEmpty()) return; serial.write(ui->lineEdit->text().toLatin1());}void MainWindow::sendPhoto(){#if 0 FILE* src = NULL; FILE* dst = NULL; unsigned char tmp_cnt = 0; char buf[MAX_BUF+1]={0}; src = fopen(SRC,"rb"); if(NULL == src) { qDebug()<<"src"<<" error!/n"; } dst = fopen(DST,"wb+"); if(NULL == dst) { qDebug()<<"dst"<<" error!/n"; } while((tmp_cnt = fread(&(buf[1]),1,MAX_BUF,src)) >= MAX_BUF) { fwrite(&(buf[1]),1,MAX_BUF,dst); //write(fd,buf,MAX_BUF); buf[0] = tmp_cnt+1; qDebug()<<buf[0]<<endl; serial.write(buf,buf[0]); QTime reachTime = QTime::currentTime().addMSecs(100); while(QTime::currentTime() < reachTime) { QCoreApplication::PRocessEvents(QEventLoop::AllEvents,100); } } fwrite(&(buf[1]),1,tmp_cnt,dst); //write(fd,buf,tmp_cnt); buf[0] = tmp_cnt+1; serial.write(buf,buf[0]); fclose(src); fclose(dst);#endif}void MainWindow::initSeialPort(){ connect(&serial,SIGNAL(readyRead()),this,SLOT(serialRead())); //连接槽 //get name for choose QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts(); if(infos.isEmpty()) { ui->serialSelect->addItem("无效"); return; } ui->serialSelect->addItem("串口"); foreach (QSerialPortInfo info, infos) { ui->serialSelect->addItem(info.portName()); }}void MainWindow::on_sendPhoto_button_clicked(){ //sendPhoto();}新闻热点
疑难解答