北斗短报文一体机-Qt版-适用于Ubuntu和Windows

本人有些原著作品是之前所写,由于当时没有做好记录,所以有些数据和图片都是最近补上的,同时有些结果都是当时所测的,现在有些都可能记不太清了,而且现在条件都不一样了,可能有些结果都发生了变化,所以如有表述不准确的地方,还请批评指正。

1.说明

2017年8-9月左右,买了两个车载端北斗短报文一体机,由于项目需求需要在Ubuntu下进行开发使用(当时只有通信协议与Windows版的可执行文件),没办法只能自己按照通信协议进行开发了,刚好自己还会些,所以就试着用Qt做了下。

首先对于北斗通信协议的介绍,就不详细介绍了,大家可参考北斗通信定位终端一体机接口协议

关于北斗通信协议的解析部分,大部分是参考博主xumin330774233的北斗短报文通信实现源码和另一博主的文章(忘记了,目前还没找到)

开发环境:

  • Ubuntu14.04
  • Qt5.2.1/Qt5.9.0

2.程序介绍

  • UI

首先上图,下面就是自己用Qt开发的程序截图

界面UI设计,自己懒得设计,就仿照Windows下提供的程序进行排版

  • 源码

下图是该项目所包含文件

因该项目使用了Qt的串口部分,所以需要在pro文件中添加串口模块

QT       += serialport

beidou.cpp主要是用于北斗通信协议的解析进行收发

/*********************定义数据协议固定长度****************************/
#define ICJC_FIRM_SIZE 12
#define XTZJ_FIRM_SIZE 13
#define TXSQ_FIRM_SIZE 18
#define SJSC_FIRM_SIZE 13
#define GLJC_FIRM_SIZE 12
#define BBDQ_FIRM_SIZE 11
#define DWSQ_FIRM_SIZE 22#define TXSQ_PAYLOAD_CHINESE 0b01000100
#define TXSQ_PAYLOAD_BCD 0b01000110....../***************************读取串口端缓存数据**********************************/
void BeiDou::readCOMData()
{if (m_serialport->bytesAvailable() <= 0) {return;}//myHelper::sleep(sleepTime);QByteArray data = m_serialport->readAll();int dataLen = data.length();if (dataLen <= 0) {return;}QString buffer;m_bytearray.append(data);if(m_bytearray.contains('$')){QByteArray first_bytearray='$'+m_bytearray.split('$').at(0);m_bytearray=m_bytearray.right(m_bytearray.length()-m_bytearray.indexOf('$')-1);if(first_bytearray.length()<=1)return;buffer =parse_data(first_bytearray);if(!isGPSdata){append(1, buffer);}else{if(ui->ShowGPS_CB->isChecked()){append(1, buffer);}}}
}void BeiDou::on_ICBtn_clicked()
{if(portIsOpen){append(0,"IC检测");send_icjc();}}void BeiDou::on_XTZJBtn_clicked()
{if(portIsOpen){append(0,"系统自检");send_xtzj();}void BeiDou::on_SendBtn_clicked()
{if(portIsOpen){char* payload;QString str=ui->SendtextEdit->toPlainText();QByteArray ba = StrToInterCode(str);//字符串转机内码//QByteArray ba=StrToUniCode(str);//字符串转Unicode码qDebug()<<"ba.length:"<<ba.length();payload=ba.data();int payload_len = strlen((char const *)payload);for(int i=0;i<payload_len;i++){qDebug()<<"payload[]:"<<payload[i];}qDebug()<<"payload_len"<<payload_len;if(payload_len>210)//电文最大长度1680bits/210bytes{QMessageBox::warning(this,"发送失败!",QString("电文长度%1bits大于最大长度%2bits").arg(QString::number(payload_len*8),QString::number(1680)),QMessageBox::Cancel);return;}long src_user_addr=SRC_USER_ADDRESS;long dst_user_addr=ui->Addr_lineEdit->text().toLong();int transfer_format=ui->TranType_CB->currentIndex();DST_USER_ADDRESS=dst_user_addr;send_txsq(src_user_addr,dst_user_addr,transfer_format,payload,payload_len);ui->Send_lineEdit->setText(QString::number(ui->Send_lineEdit->text().toInt()+payload_len));append(0,QString("From %1 To %2:"+str).arg(QString::number(SRC_USER_ADDRESS),QString::number(DST_USER_ADDRESS)));}}void BeiDou::on_Single_DW_Btn_clicked()
{if(portIsOpen){append(0,"定位申请");send_dwsq();}
}void BeiDou::on_TimeBtn_clicked()
{if(portIsOpen){append(0,"时间输出");send_sjsc();}
}void BeiDou::on_GongLvBtn_clicked()
{if(portIsOpen){append(0,"功率检测");send_gljc();}
}void BeiDou::on_ClearBtn_clicked()
{ui->RevtextEdit->clear();
}void BeiDou::on_RecountBtn_clicked()
{ui->Rev_lineEdit->setText("0");ui->Send_lineEdit->setText("0");}void BeiDou::on_CleanBtn_clicked()
{ui->SendtextEdit->clear();}void BeiDou::on_Con_Send_Btn_clicked()
{if(m_continue_send_timer->isActive()){m_continue_send_timer->stop();ui->Con_Send_Btn->setText("连续发送");}else{m_continue_send_timer->setInterval(ui->Con_Send_Time_SB->value()*1000);m_continue_send_timer->start();emit ui->SendBtn->clicked();ui->Con_Send_Btn->setText("停止连续发送");}
}/****************************异或校验和算法******************************/
char BeiDou::xor_checksum( char *buf,  int len)
{int i;char checksum = 0;for (i = 0; i < len; ++i){checksum ^= *(buf++);}return checksum;
}/*****************************************************************************************发送协议指令*************************** **************************************************************/
/*1、IC检测协议内容:icjc:24 49 43 4A 43 00 0C 00 00 00 00 2Bicxx:24 49 43 58 58 00 16 02 AD F7 00 00 00 0B 06 00 3C 03 00 00 00 52*/
void BeiDou::send_icjc()
{char send_icjc_data[ICJC_FIRM_SIZE];/* 1、IC检测指令初始化*/send_icjc_data[0] = '$';send_icjc_data[1] = 'I';send_icjc_data[2] = 'C';send_icjc_data[3] = 'J';send_icjc_data[4] = 'C';/* 2、长度*/send_icjc_data[5] = ICJC_FIRM_SIZE / 256;  //先传高位send_icjc_data[6] = ICJC_FIRM_SIZE% 256; //再传低位/* 3、用户地址-当外设获取本机用户信息时, “用户地址”填全“0”*/send_icjc_data[7] = 0x00;send_icjc_data[8] = 0x00;send_icjc_data[9] = 0x00;/* 4、信息内容-帧号(固定填0)*/send_icjc_data[10] = 0x00;/* 5、校验和 */send_icjc_data[11] = xor_checksum(send_icjc_data, ICJC_FIRM_SIZE - 1);m_serialport->write(send_icjc_data,ICJC_FIRM_SIZE);}
/*1、XTZJ协议内容:xtzj:24  58 54 5A 4A 00 0D 02 AD FB 00 00 61zjxx:24 5a 4a 58 58 00 15 02 AD FB 01 00 64 02 00 00 03 00 02 00 13*/
void BeiDou::send_xtzj()
{int frequency=0;char send_xtzj_data[XTZJ_FIRM_SIZE];/* 1、系统自检指令初始化*/send_xtzj_data[0] = '$';send_xtzj_data[1] = 'X';send_xtzj_data[2] = 'T';send_xtzj_data[3] = 'Z';send_xtzj_data[4] = 'J';/* 2、长度*/send_xtzj_data[5] = XTZJ_FIRM_SIZE / 256; //先传高位send_xtzj_data[6] = XTZJ_FIRM_SIZE % 256; //再传低位/* 3、用户地址*/send_xtzj_data[7] = SRC_USER_ADDRESS/ 65536;send_xtzj_data[8] = ( SRC_USER_ADDRESS % 65536) / 256;send_xtzj_data[9] = ( SRC_USER_ADDRESS % 65536) % 256;/* 4、信息内容- 自检频度*/send_xtzj_data[10] = frequency / 256;send_xtzj_data[11] = frequency % 256;/* 5、校验和 */send_xtzj_data[12] = xor_checksum(send_xtzj_data, XTZJ_FIRM_SIZE-1);m_serialport->write(send_xtzj_data,XTZJ_FIRM_SIZE);}/******************************TXSQ协议***********************************/
void BeiDou::send_txsq(long src_user_addr, long dst_user_addr, int transfer_format,  char *payload,  int payload_len)
{char send_txsq_data[TXSQ_FIRM_SIZE+payload_len];/* 1、通信申请指令初始化,不采用memcpy等库函数,提高指令执行效率,只有涉及到大量数据赋值拷贝时才考虑用库函数 */send_txsq_data[0] = '$';send_txsq_data[1] = 'T';send_txsq_data[2] = 'X';send_txsq_data[3] = 'S';send_txsq_data[4] = 'Q';/* 2、包长度,先传高位,再传低位 */send_txsq_data[5] = (TXSQ_FIRM_SIZE +  payload_len) / 256;send_txsq_data[6] = (TXSQ_FIRM_SIZE +  payload_len) % 256;/* 3、源用户地址 */send_txsq_data[7] =src_user_addr/ 65536;send_txsq_data[8] = (src_user_addr% 65536) / 256;send_txsq_data[9] =(src_user_addr% 65536) % 256;/* 4.1、信息-信息类别 */if (transfer_format == 0) //汉字{send_txsq_data[10] = TXSQ_PAYLOAD_CHINESE;//0b01000100;}else //代码/混发{send_txsq_data[10] = TXSQ_PAYLOAD_BCD;//0b01000110}/* 4.2、信息-目的用户地址 */send_txsq_data[11] =dst_user_addr/ 65536;send_txsq_data[12] =(dst_user_addr% 65536) / 256;send_txsq_data[13] =(dst_user_addr% 65536) % 256;/* 4.3、信息-电文净荷长度-单位是bit */send_txsq_data[14] = (payload_len * 8) / 256;send_txsq_data[15]  = (payload_len * 8) % 256;/* 4.4、信息-是否应答 */send_txsq_data[16]  = 0;/* 4.5、信息-电文内容 */memcpy(&send_txsq_data[17] , payload, payload_len);/* 5、校验和 */send_txsq_data[TXSQ_FIRM_SIZE + payload_len -1] = xor_checksum(send_txsq_data, (TXSQ_FIRM_SIZE +  payload_len -1));m_serialport->write(send_txsq_data,TXSQ_FIRM_SIZE +  payload_len);}/******************************DWSQ协议***********************************/
void BeiDou::send_dwsq()
{char send_dwsq_data[DWSQ_FIRM_SIZE];/* 1、定位申请指令初始化*/    /* 2、长度*/  /* 3、用户地址*/     /* 4.1、信息内容- 信息类别*/      /* 5、校验和 */send_dwsq_data[0] = '$';send_dwsq_data[1] = 'D';send_dwsq_data[2] = 'W';send_dwsq_data[3] = 'S';send_dwsq_data[4] = 'Q';/* 2、长度*/send_dwsq_data[5] = DWSQ_FIRM_SIZE/ 256;  //先传高位send_dwsq_data[6] = DWSQ_FIRM_SIZE% 256; //再传低位/* 3、用户地址*/send_dwsq_data[7] = SRC_USER_ADDRESS/ 65536;send_dwsq_data[8] = ( SRC_USER_ADDRESS % 65536) / 256;send_dwsq_data[9] = ( SRC_USER_ADDRESS % 65536) % 256;/* 4.1、信息内容- 信息类别*/send_dwsq_data[10] = 0x00;/* 4.2、信息内容- 高程数据和天线高*/send_dwsq_data[11] = 0x00;send_dwsq_data[12] = 0x00;send_dwsq_data[13] = 0x00;send_dwsq_data[14] = 0x00;/* 4.3、信息内容- 气压数据*/send_dwsq_data[15] = 0x00;send_dwsq_data[16] = 0x00;send_dwsq_data[17] = 0x00;send_dwsq_data[18] = 0x00;/* 4.4、信息内容- 入站频度*/send_dwsq_data[19] = 0x00;send_dwsq_data[20] = 0x00;/* 5、校验和 */send_dwsq_data[21] = xor_checksum(send_dwsq_data, DWSQ_FIRM_SIZE- 1);m_serialport->write(send_dwsq_data,DWSQ_FIRM_SIZE);
}/******************************SJSC协议***********************************/
void BeiDou::send_sjsc()
{char send_sjsc_data[SJSC_FIRM_SIZE];/* 1、时间输出指令初始化*/send_sjsc_data[0] = '$';send_sjsc_data[1] = 'S';send_sjsc_data[2] = 'J';send_sjsc_data[3] = 'S';send_sjsc_data[4] = 'C';/* 2、长度*/send_sjsc_data[5] = SJSC_FIRM_SIZE / 256;  //先传高位send_sjsc_data[6] = SJSC_FIRM_SIZE% 256; //再传低位/* 3、用户地址*/send_sjsc_data[7] = SRC_USER_ADDRESS/ 65536;send_sjsc_data[8] = ( SRC_USER_ADDRESS % 65536) / 256;send_sjsc_data[9] = ( SRC_USER_ADDRESS % 65536) % 256;/* 4、信息内容-输出频度-单次*/send_sjsc_data[10] = 0x00;send_sjsc_data[11] = 0x00;/* 5、校验和 */send_sjsc_data[12] = xor_checksum(send_sjsc_data, SJSC_FIRM_SIZE - 1);m_serialport->write(send_sjsc_data,SJSC_FIRM_SIZE);}/******************************GLJC协议***********************************/
void BeiDou::send_gljc()
{char send_gljc_data[GLJC_FIRM_SIZE];/* 1、功率检测指令初始化*/send_gljc_data[0] = '$';send_gljc_data[1] = 'G';send_gljc_data[2] = 'L';send_gljc_data[3] = 'J';send_gljc_data[4] = 'C';/* 2、长度*/send_gljc_data[5] = GLJC_FIRM_SIZE / 256;  //先传高位send_gljc_data[6] = GLJC_FIRM_SIZE% 256; //再传低位/* 3、用户地址*/send_gljc_data[7] = SRC_USER_ADDRESS/ 65536;send_gljc_data[8] = ( SRC_USER_ADDRESS % 65536) / 256;send_gljc_data[9] = ( SRC_USER_ADDRESS % 65536) % 256;/* 4、信息内容-输出频度-单次*/send_gljc_data[10] = 0x00;/* 5、校验和 */send_gljc_data[11] = xor_checksum(send_gljc_data, GLJC_FIRM_SIZE - 1);m_serialport->write(send_gljc_data,GLJC_FIRM_SIZE);}/******************************BBDQ协议***********************************/
void BeiDou::send_bbdq()
{char send_bbdq_data[BBDQ_FIRM_SIZE];/* 1、版本读取指令初始化*/send_bbdq_data[0] = '$';send_bbdq_data[1] = 'B';send_bbdq_data[2] = 'B';send_bbdq_data[3] = 'D';send_bbdq_data[4] = 'Q';/* 2、长度*/send_bbdq_data[5] = BBDQ_FIRM_SIZE / 256;  //先传高位send_bbdq_data[6] = BBDQ_FIRM_SIZE% 256; //再传低位/* 3、用户地址*/send_bbdq_data[7] = SRC_USER_ADDRESS/ 65536;send_bbdq_data[8] = ( SRC_USER_ADDRESS % 65536) / 256;send_bbdq_data[9] = ( SRC_USER_ADDRESS % 65536) % 256;/* 4、校验和 */send_bbdq_data[10] = xor_checksum(send_bbdq_data, BBDQ_FIRM_SIZE - 1);m_serialport->write(send_bbdq_data,BBDQ_FIRM_SIZE);}/*****************************************************************************************解析协议数据*****************************************************************************************/
/**************************解析数据*********************************/
QString BeiDou::parse_data(QByteArray data)
{if(data.isEmpty())return "";if(data.at(1)=='I'&&data.at(2)=='C'){isGPSdata=false;return parse_ICXX(data);}else if(data.at(1)=='Z'&&data.at(2)=='J'){isGPSdata=false;return parse_ZJXX(data);}else if(data.at(1)=='T'&&data.at(2)=='X'){isGPSdata=false;return parse_TXXX(data);}else if(data.at(1)=='F'&&data.at(2)=='K'){isGPSdata=false;return parse_FKXX(data);}else if(data.at(1)=='D'&&data.at(2)=='W'){isGPSdata=false;return parse_DWXX(data);}else if(data.at(1)=='S'&&data.at(2)=='J'){isGPSdata=false;return parse_SJXX(data);}else if(data.at(1)=='G'&&data.at(2)=='L'){isGPSdata=false;return parse_GLXX(data);}else if(data.at(1)=='B'&&data.at(2)=='B'){isGPSdata=false;return parse_BBXX(data);}else{isGPSdata=true;return parse_GPS(data);}
}/**************************解析ICXX数据*********************************/
QString BeiDou::parse_ICXX(QByteArray ICXX_data)
{long ICXX_address=(unsigned char)ICXX_data[7]*65536+(unsigned char)ICXX_data[8]*256+(unsigned char)ICXX_data[9];int ICXX_serveFrequency=(unsigned char)ICXX_data[15]*256+(unsigned char)ICXX_data[16];int ICXX_tongboID=(unsigned char)ICXX_data[11]*65536+(unsigned char)ICXX_data[12]*256+(unsigned char)ICXX_data[13];int ICXX_level=ICXX_data[17];int ICXX_jiami=ICXX_data[18];QString ICXX_jiami_biaozhi;if(ICXX_jiami==0)ICXX_jiami_biaozhi="非密用户";elseICXX_jiami_biaozhi="保密用户";SRC_USER_ADDRESS=ICXX_address;ui->User_Addr_lineEdit->setText(QString::number(ICXX_address));ui->Freq_lineEdit->setText(QString::number(ICXX_serveFrequency)+"s");ui->Tongbo_lineEdit->setText(QString::number(ICXX_tongboID));ui->Level_lineEdit->setText(QString::number(ICXX_level));return "ID:"+QString::number(ICXX_address)+" 通播:"+QString::number(ICXX_tongboID)+" 频度:"+QString::number(ICXX_serveFrequency)+"s"+" 等级:"+QString::number(ICXX_level)+" 保密:"+ICXX_jiami_biaozhi;}/**************************解析ZJXX数据*********************************/
QString BeiDou::parse_ZJXX(QByteArray ZJXX_data)
{QString ZJXX_IC,ZJXX_hardware,ZJXX_dianliang,ZJXX_ruzhan,ZJXX_yizhi;if((unsigned char)ZJXX_data[10]==0x00)ZJXX_IC="0";elseZJXX_IC="error";if((unsigned char)ZJXX_data[11]==0x00)ZJXX_hardware="0";elseZJXX_hardware="error";if((unsigned char)ZJXX_data[12]==0x00)ZJXX_dianliang="0";else{int ZJXX_remain=(unsigned char)ZJXX_data[12];ZJXX_dianliang=QString("剩余1/%1").arg(QString::number(ZJXX_remain));}if((ZJXX_data[13]&0x02)==0x02)//(ZJXX_data[13]&0x02)==0x02需加括号先进行括号内的按位与运算再进行判断,否则若为ZJXX_data[13]&0x02==0x02会先进行右边的判断再进行按位与运算ZJXX_ruzhan="可以入站" ;elseZJXX_ruzhan="不可以入站";if((ZJXX_data[13]&0x01)==0x01)ZJXX_yizhi="抑制";elseZJXX_yizhi="非抑制";int ZJXX_GL_1=ZJXX_data[14];int ZJXX_GL_2=ZJXX_data[15];int ZJXX_GL_3=ZJXX_data[16];int ZJXX_GL_4=ZJXX_data[17];int ZJXX_GL_5=ZJXX_data[18];int ZJXX_GL_6=ZJXX_data[19];QString ZJXX_GL=QString::number(ZJXX_GL_1)+"-"+QString::number(ZJXX_GL_2)+"-"+QString::number(ZJXX_GL_3)+"-"+QString::number(ZJXX_GL_4)+"-"+QString::number(ZJXX_GL_5)+"-"+QString::number(ZJXX_GL_6);ui->GLZK_lineEdit->setText(ZJXX_GL);return "IC卡状态:"+ZJXX_IC+" 硬件状态:"+ZJXX_hardware+" 电池电量:"+ZJXX_dianliang+" 入站状态:"+ZJXX_ruzhan+" "+ZJXX_yizhi+" 功率状况:"+ZJXX_GL;}/**************************解析FKXX数据*********************************/
QString BeiDou::parse_FKXX(QByteArray FKXX_data)
{unsigned int FKXX_fk=FKXX_data[10];QString FKXX_str;if(FKXX_fk==0x00){for(int i=11;i<15;i++){FKXX_str+=FKXX_data[i];}FKXX_str+=":成功";//失败  信号未锁定  电量不足 发射频度未到 加解密错误 CRC错误}else if(FKXX_fk==0x01){for(int i=11;i<15;i++){FKXX_str+=FKXX_data[i];}FKXX_str+=":失败";}else if(FKXX_fk==0x02){FKXX_str="信号未锁定";}else if(FKXX_fk==0x03){FKXX_str="电量不足";}else if(FKXX_fk==0x04){int wait_time=FKXX_data[11];FKXX_str="发射频度未到,需要等待"+QString::number(wait_time)+"s";}else if(FKXX_fk==0x05){FKXX_str="加解密错误";}else if(FKXX_fk==0x06){for(int i=11;i<15;i++){FKXX_str+=FKXX_data[i];}FKXX_str+=":CRC错误";}else{FKXX_str="unknown error";}return FKXX_str;
}/**************************解析GPS数据*********************************/
QString BeiDou::parse_GPS(QByteArray GPS_data)
{QString GPS_str=myHelper::byteArrayToAsciiStr(GPS_data);return GPS_str;}/**************************解析TXXX数据*********************************/
QString BeiDou::parse_TXXX(QByteArray TXXX_data)
{int TXXX_length=(unsigned char)TXXX_data[5]*256+(unsigned char)TXXX_data[6];long TXXX_sender_address=(unsigned char)TXXX_data[11]*65536+(unsigned char)TXXX_data[12]*256+(unsigned char)TXXX_data[13];unsigned char TXXX_type=TXXX_data[10];qDebug()<<"TXXX_length:"<<TXXX_length;qDebug()<<"(unsigned char)17:"<<(unsigned char)TXXX_data[17];unsigned char date_16=TXXX_data[16];//必须使用unsigned char 否则会出现-128-127的值unsigned char date_17=TXXX_data[17];//必须使用unsigned char 否则会出现-128-127的值int TXXX_length_bits=date_16*256+date_17;//此时单位为bitint TXXX_length_byte=TXXX_length_bits/8;//此时单位为byteqDebug()<<"TXXX_length_byte:"<<TXXX_length_byte;QByteArray TXXX_temp;for(int i=18;i<18+TXXX_length_byte;i++){qDebug()<<QString("TXXX_data[%1]:").arg(QString::number(i))<<TXXX_data[i];TXXX_temp.append(TXXX_data[i]);}QString TXXX_str;if(TXXX_type==0b01000000){TXXX_str="(汉字)"+TXXX_temp;}else if(TXXX_type==0b01100000){TXXX_str="(BCD)"+TXXX_temp;}ui->Rev_lineEdit->setText(QString::number(ui->Rev_lineEdit->text().toInt()+TXXX_length_byte));return "From "+QString::number(TXXX_sender_address)+" To "+QString::number(SRC_USER_ADDRESS)+":"+TXXX_str;
}/**************************解析BBXX数据*********************************/
QString BeiDou::parse_BBXX(QByteArray BBXX_data)
{int BBXX_length=(unsigned char)BBXX_data[5]*256+(unsigned char)BBXX_data[6];QString BBXX_str;for(int i=10;i<10+BBXX_length-BBDQ_FIRM_SIZE;i++){BBXX_str+=BBXX_data[i];}return BBXX_str;}/**************************解析DWXX数据*********************************/
QString BeiDou::parse_DWXX(QByteArray DWXX_data)
{int DWXX_user_addr=(unsigned char)DWXX_data[7]*65536+(unsigned char)DWXX_data[8]*256+(unsigned char)DWXX_data[9];int DWXX_query_addr=(unsigned char)DWXX_data[11]*65536+(unsigned char)DWXX_data[12]*256+(unsigned char)DWXX_data[13];int DWXX_time_hour=DWXX_data[14];int DWXX_time_minute=DWXX_data[15];float DWXX_time_second=(unsigned char)DWXX_data[16]+0.01*(unsigned char)DWXX_data[17];//大地经度int DWXX_L_degree=DWXX_data[18];int DWXX_L_minute=DWXX_data[19];float DWXX_L_second=(unsigned char)DWXX_data[20]+0.01*(unsigned char)DWXX_data[21];//大地纬度int DWXX_B_degree=DWXX_data[22];int DWXX_B_minute=DWXX_data[23];float DWXX_B_second=(unsigned char)DWXX_data[24]+0.01*(unsigned char)DWXX_data[25];int a=DWXX_data[26];int b=DWXX_data[27];qDebug()<<"a:"<<a;qDebug()<<"b:"<<b;unsigned char DWXX_height_high=DWXX_data[26];unsigned char DWXX_height_low=DWXX_data[27];unsigned char DWXX_height_high_low6=DWXX_height_high&0x3f;int DWXX_height=DWXX_height_high_low6*256+DWXX_height_low;//判断DWXX_height-高度的符号if((DWXX_height_high&0xc0)==0x40)    //需加括号先进行括号内的按位与运算再进行判断,否则若会先进行右边的判断再进行按位与运算{DWXX_height*=-1;}unsigned char DWXX_Herror_high=DWXX_data[28];unsigned char DWXX_Herror_low=DWXX_data[29];int DWXX_Herror=DWXX_Herror_low;//判断DWXX_Herror-误差高度的符号if(DWXX_Herror_high==0x01){DWXX_Herror*=-1;}QString DWXX_str=QString("用户地址:%1 查询地址:%2 %3时%4分%5秒").arg(QString::number(DWXX_user_addr),QString::number(DWXX_query_addr),QString::number(DWXX_time_hour),QString::number(DWXX_time_minute), QString::number(DWXX_time_second))+QString(" 经度:%1度%2分%3秒 纬度:%4度%5分%6秒 高度:%7 高度异常:%8").arg(QString::number(DWXX_L_degree),QString::number(DWXX_L_minute),QString::number(DWXX_L_second), QString::number(DWXX_B_degree),QString::number(DWXX_B_minute),QString::number(DWXX_B_second),QString::number(DWXX_height),QString::number(DWXX_Herror));return DWXX_str;
}/**************************解析SJXX数据*********************************/
QString BeiDou::parse_SJXX(QByteArray SJXX_data)
{int SIXX_year=(unsigned char)SJXX_data[10]*256+(unsigned char)SJXX_data[11];int SIXX_month=(unsigned char)SJXX_data[12];int SIXX_day=(unsigned char)SJXX_data[13];int SIXX_hour=(unsigned char)SJXX_data[14];int SIXX_minute=(unsigned char)SJXX_data[15];int SIXX_second=(unsigned char)SJXX_data[16];return QString("时间信息:%1/%2/%3 %4:%5:%6").arg(QString::number(SIXX_year),QString::number(SIXX_month),QString::number(SIXX_day),QString::number(SIXX_hour),QString::number(SIXX_minute),QString::number(SIXX_second));
}/**************************解析GLXX数据*********************************/
QString BeiDou::parse_GLXX(QByteArray GLXX_data)
{int GLXX_1=GLXX_data[10];int GLXX_2=GLXX_data[11];int GLXX_3=GLXX_data[12];int GLXX_4=GLXX_data[13];int GLXX_5=GLXX_data[14];int GLXX_6=GLXX_data[15];QString GLXX_GL= QString("%1-%2-%3-%4-%5-%6").arg(QString::number(GLXX_1),QString::number(GLXX_2),QString::number(GLXX_3),QString::number(GLXX_4),QString::number(GLXX_5),QString::number(GLXX_6));ui->GLZK_lineEdit->setText(GLXX_GL);return "功率状况:"+GLXX_GL;
}
......

bd_serialportset.cpp主要是对于串口的查找与设置


......//检查是否有可用的串口号
/*** @brief BD_SerialPortSet::checkAvailableSerialPorts*/
void BD_SerialPortSet::checkAvailableSerialPorts()
{//ui->COM_CB->addItem("usb_beidou0_link");//找不到存在串口是不会进入到foreach内部的        存在不一定可用foreach ( const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()){QSerialPort availablePort;availablePort.setPortName(Info.portName());//检测该串口是否可用if (availablePort.open(QIODevice::ReadWrite))//protname:/dev/tty0或者/dev/ttyUSB0{ui->COM_CB->addItem(Info.portName());availablePort.close();}}
}void BD_SerialPortSet::haveAvailablePorts()
{ui->COM_CB->setEnabled(true);ui->Baud_CB->setEnabled(true);ui->DataBits_CB->setEnabled(true);ui->Parity_CB->setEnabled(true);ui->FlowCtrl_CB->setEnabled(true);ui->StopBits_CB->setEnabled(true);
}void BD_SerialPortSet::NoAvailablePorts()
{ui->Baud_CB->setEnabled(false);ui->DataBits_CB->setEnabled(false);ui->Parity_CB->setEnabled(false);ui->FlowCtrl_CB->setEnabled(false);ui->StopBits_CB->setEnabled(false);}//串口端口参数设置
void BD_SerialPortSet::Transmit_PortsSet()
{PORTNAME=ui->COM_CB->currentText();BAUD=ui->Baud_CB->currentText();DATABITS=ui->DataBits_CB->currentText();PARITY=ui->Parity_CB->currentText();FLOWCTRL=ui->FlowCtrl_CB->currentText();STOPBITS=ui->StopBits_CB->currentText();
}void BD_SerialPortSet::on_EnsureBtn_clicked()
{Transmit_PortsSet();this->close();}void BD_SerialPortSet::on_CancelBtn_clicked()
{this->close();
}

具体相关内容,代码中都有注释

  • 使用

当时测试时用了一台工控机(自带串口)装的是Ubuntu14.04,就直接用了工控机的串口与设备互联,发现一直无法成功解析到数据,使用CuteCom进行查看时发现接受到的数据毫无规则,并且与协议上的内容也不一致,最后在中间使用了一根USB转串口线进行尝试,才发现用程序能解析到数据。

准备条件:

  • Ubuntu下点开设置若没有串口选择项,应该是USB端口权限的问题,可以打开终端输入sudo chmod 666 /dev/ttyUSB*,一般情况下为sudo chmod 666 /dev/ttyUSB0
  • Windows下需要先安装USB转串口的驱动程序

打开程序,点击设置按钮,在弹出的串口配置框中进行相应配置

选择对应的端口号(Ubuntu下为ttyUSB*,Windows下为com*),点击确定,然后再点击打开按钮即可
下图分别是Ubuntu和Window下程序的运行截图

3.注意事项

  • 连接时最好使用USB转串口线
  • 民用卡单次通信上限好像是78Byte,如下图一次只能传输78Byte
  • 定位与通信间隔大于等于60s
  • 之前开发时Qt为5.2.1将源码放到Windows(Qt也是5.2.1)上,界面中文显示乱码,现在都改为Qt5.9.0后,Windows上显示正常

4.遗留问题

  • Ubuntu上测试时,使用汉字通信显示为乱码,当时查找了一些资料,原因可能是因为Qt环境设置Ubuntu环境设置默认是utf-8,Windows默认都是GBK引起的。
    ★UTF-8:Unicode TransformationFormat-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。
    ★GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。
    详细内容可参考以下链接了解
    解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)
    QT字符编码转换,可用于中文内码传输
    Windows上没有进行通信测试

5.备注

最后附上源码下载地址:
https://download.csdn.net/download/shijiegong123/11790528

北斗短报文一体机-Qt版(适用于Ubuntu和Windows)相关推荐

  1. 北斗短报文和北斗定位入门篇

    北斗通信和北斗定位已经家喻户晓,但是很多初学者和开发工程师往往被各种概念混淆.有鉴于此,北斗海聊整理出本篇入门文档,将常见问题进行系统性梳理.鉴于笔者水平有限,如果本文有什么错漏,请各位读者批评指正. ...

  2. 北斗终端与计算机传输信息,北斗短报文数据传输终端

    2018年世界标准日的主题是"国际标准与第四次工业革命",第四次工业革命是指技术的大融合,融合技术的发展模糊了传统意义上物理.数字与生物技术领域的边界.卫星导航在人类新一轮科技革命 ...

  3. 【miscellaneous】北斗短报文

    北斗系统最大的特色在于有源定位和短报文特色服务,不止解决了中国有无卫星导航系统的问题,还能将短信和导航结合,是中国北斗卫星导航系统的独特发明,也是一大优势. 北斗的短报文功能,在国防.民生和应急救援等 ...

  4. 北斗终端与计算机传输信息,北斗短报文船载终端,北斗卫星海上通信终端问世,海上作业再也不怕失联...

    产品功能特点: 产品简介:这是一款集北斗RDSS.GNSS.LORA.蓝牙.天线.充电.电池等于一体的多功能船载终端,可实现北斗短报文卫星通信.卫星定位.LORA通信的功能.终端可通过蓝牙连接手机.平 ...

  5. 北斗短报文服务在通信中的应用

    北斗作为我国具有自主知识产权的卫星导航系统,已经实现了全球性的导航服务,而作为其独特性存在的短报文服务,在通信应用中更是惊艳众人,有望在未来进一步推广.本文将展开如下论述:简要介绍北斗卫星导航系统和目 ...

  6. (实用详细)快速入门北斗短报文RDSS协议/北斗协议

    完整资料下载链接: https://pan.baidu.com/s/1npe3_RNuHKFYFYAXYMQJmw 提取码: 9m47 如有产品需求,请联系wx: 15889520531 北斗短报文协 ...

  7. 轻松开发北斗短报文设备(基于RDSS协议)

      北斗短报文模块遵循RDSS协议,目前RDSS协议有4.0和2.1协议,通用版本使用2.1协议,任何短报文设备都要支持2.1协议.2.1 协议的最大特点,1.是用 10 个波速表示信号强度,之前的 ...

  8. 北斗短报文优点以及行业应用

      北斗短报文设备是基于中国北斗二代.三代卫星导航系统的特点开发而来的,其同时具备定位与通讯功能,无需其他通讯系统支持,即可实现北斗用户间的双向短报文通信,而世界上其他卫星导航系统则不具备此功能. 什 ...

  9. 北斗终端,北斗短报文终端,北斗指挥机,北斗终端,北斗通信卡的区分和定义

    北斗终端普通人基本都认为是用北斗卫星来定位的一种设备,爱陆通北斗终端指的是具备北斗定位和北斗短报文收发通信的专业设备,用于特殊地区和应用的一种通信设备.北斗终端和北斗短报文终端其实说的是一类设备,也叫 ...

最新文章

  1. 当深度学习搭上一双鞋,有人要用这检测你的压力水平!可无线操作,准确率达84%...
  2. 一级二级标题_考二级造价师有啥要求?
  3. 我十年学习编程的历史
  4. flink的dataset/stream/sql三套API的选择以及是否应该阅读源码
  5. vscode 默认初始化_Visual Studio Code(vscode)使用介绍
  6. 为什么html运行之后不滚动,为什么很多移动端的HTML UI,在滚动时都用transform属性而不是用传统的滚动条?...
  7. 上万规模数据湖如何在实验室测试
  8. AgileEAS.NET SOA 中间件平台5.2版本下载、配置学习(四):开源的Silverlight运行容器的编译、配置...
  9. ehcache讲解及实例
  10. IR(红外遥控)基本原理
  11. [踩坑记录]VS2017+大恒MER-131-210U3C相机
  12. 【朝花夕拾】Android编码风格拾遗
  13. 双硬盘下安装win+linux关于开机引导的问题
  14. 中国科学研成都计算机,中国科学院成都分院
  15. 90 后高管:“下不手开除 70、80 后,公司死了谁负责?”
  16. js添加多marker 高德地图_web开发如何使用高德地图API(四)通过AMap.Marker自定义标点...
  17. html5点赞按钮特效,jquery仿直播app按钮点赞动画效果
  18. 网页中添加QQ聊天代码
  19. 思维导图——货币资金
  20. [蓝桥杯][算法提高VIP]去注释

热门文章

  1. 计算机二级MS office的高频考点~
  2. 干货:esp32彩屏自制太空人主题透明手表!
  3. Java Web学习(1)
  4. 一文了解Java强制类型转换
  5. 有什么好用的表单工具?
  6. 通过XMind Update制作思维导图
  7. 2022 IDEA大会引领科技创新趋势 沈向洋团队重磅发布低空经济白皮书
  8. AndroidTagView 云标签
  9. Chapter_06 更改图像的对比度和亮度
  10. Lucene打分公式详解(TFIDFSimilarity)