GPS模块运用: 定位测试软件设计(上位机)

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据同步 1个月
简介: GPS模块运用: 定位测试软件设计(上位机)

一、硬件介绍

GPS模块型号:  中科微电子ATGM336H-5N 系列模块


ATGM336H-5N 系列模块是 9.7X10.1 尺寸的高性能 BDS/GNSS 全星座定位导航模块系列的总称。该系列模块产品都是基于中科微第四代低功耗 GNSS SOC 单芯片—AT6558,支持多种卫星导航系统,包括中国的 BDS(北斗卫星导航系统),美国的 GPS,俄罗斯的 GLONASS,欧盟的 GALILEO,日本的 QZSS以及卫星增强系统 SBAS(WAAS,EGNOS,GAGAN,MSAS)。AT6558 是一款真正意义的六合一多模卫星导航定位芯片,包含 32 个跟踪通道,可以同时接收六个卫星导航系统的 GNSS 信号,并且实现联合定位、导航与授时。


二、软件功能介绍

解析GPS模块接收的数据,得到经纬度和速度。


软件支持GPS模式配置、指定的语句输出配置。


软件设计思路:


串口在子线程里完成数据接收,将解析的数据保存到全局类中,全局类里加了读写锁,防止多线程读写全局变量出现问题。


主UI线程里负责数据显示,解析的结果使用定时器2秒钟显示一次。


软件下载地址: https://download.csdn.net/download/xiaolong1126626497/12721684


软件运行效果:

image.png

GPS模块连线:

image.png

三、软件核心代码

3.1 uart_code.h

#ifndef UART_CODE_H
#define UART_CODE_H
#include <QSerialPort>
#include <QObject>
#include <QThread>
#include <QDebug>
#include <QString>
#include "config.h"
class OBD_Data
{
public:
      QString V; //电瓶电压
      QString R; //转速
      QString S; //速度
      QString P; //绝对气门开度
      QString O; //发动机负荷
      QString C; //冷却液温度
      QString L; //油量
      QString M; //此次行程米
      QString F; //此次油耗L
      QString XM; //瞬时油耗、百公里油耗
      QString T; //运行时间
      //QString E; //发动机状态 0熄火 1点火 2自动启动
      QString A; //急加速次数
      QString B; //急刹车次数
      QString D; //故障码个数
      QString GX;//X
      QString GY;//Y
      QString GZ;//Z
      QString data;
};
class GPS_Data
{
private:
    double lat; //纬度
    double lng; //经度
    QString speed; //速度
    QReadWriteLock lock; //读写锁
    QString save_src_data; //原始数据
public:
    QString Data;
    //构造函数
    GPS_Data()
    {
        lat=0.0;
        lng=0.0;
        speed="0";
        save_src_data="";
    }
    //读取纬度
    double get_lat(void)
    {
        lock.lockForRead();
        double tmp_lat=lat;
        lock.unlock();
        return  tmp_lat;
    }
    //设置纬度
    void set_lat(double tmp_lat)
    {
        lock.lockForWrite();
        lat=tmp_lat;
        lock.unlock();
    }
    //读取经度
    double get_lng(void)
    {
        lock.lockForRead();
        double tmp_lng=lng;
        lock.unlock();
        return  tmp_lng;
    }
    //设置经度
    void set_lng(double tmp_lng)
    {
        lock.lockForWrite();
        lng=tmp_lng;
        lock.unlock();
    }
    //读取速度
    QString get_speed(void)
    {
        lock.lockForRead();
        QString tmp_speed=speed;
        lock.unlock();
        return  tmp_speed;
    }
    //设置速度
    void set_speed(QString tmp_speed)
    {
        lock.lockForWrite();
        speed=tmp_speed;
        lock.unlock();
    }
    //读取原始数据
    QString get_src_data(void)
    {
        lock.lockForRead();
        QString tmp_speed=save_src_data;
        lock.unlock();
        return  tmp_speed;
    }
    //设置原始数据
    void set_src_data(QString tmp_save_src_data)
    {
        lock.lockForWrite();
        save_src_data+=tmp_save_src_data;
        if(save_src_data>1024)save_src_data.clear();
        lock.unlock();
    }
    //清除原始数据
    void set_src_clear(void)
    {
        lock.lockForWrite();
        save_src_data.clear();
        lock.unlock();
    }
};
class UART_ReadWriteThread:public QObject
{
    Q_OBJECT
public:
    QByteArray byte_all;
    UART_ReadWriteThread(QObject* parent=nullptr):QObject(parent){}
    ~UART_ReadWriteThread();
    //成员变量
    QSerialPort *UART_Config=nullptr; //串口---数据接收串口
    int GPS_GetData(const char *gps_src,const char *find_head,char *buff,int cnt);
    int GPS_GetCheckSum(const char *src_str,const char *find_str);
public slots:
    void UART_ReadUasrtData(void);
    void run();
    void Open_UART(void);
    void Close_UART(void);
    void UART_Send(QString text);
signals:
    void LogSend(QString text);
    void SendUartState(qint8 state);  //发送串口状态   true 表示连接 否则表示断开
};
#endif // UART_CODE_H

3.2 uart_code.cpp

#include "uart_code.h"
#include "config.h"
QString current_SerialPort="";  //当前串口端口号
qint32 current_SerialBaudRate=0; //当前波特率
class OBD_Data obd_data;
class GPS_Data gps_data;
UART_ReadWriteThread::~UART_ReadWriteThread()
{
}
void UART_ReadWriteThread::run()
{
    //串口配置
    if(UART_Config)
    {
        UART_Config->close();
        delete UART_Config;
        UART_Config=nullptr;
    }
    UART_Config =new QSerialPort;
    //打开串口设备
    Open_UART();
}
//当串口打不开的时候,间隔一段时间再次重新测试
void UART_ReadWriteThread::Open_UART(void)
{
    //配置串口属性
    UART_Config->setBaudRate(current_SerialBaudRate);              //默认波特率
    UART_Config->setDataBits(QSerialPort::Data8);  //数据位
    UART_Config->setParity(QSerialPort::NoParity); //奇偶校验
    UART_Config->setStopBits(QSerialPort::OneStop);//停止位
    UART_Config->setFlowControl(QSerialPort::NoFlowControl); //流控开关
    UART_Config->setPortName(current_SerialPort);    //COM的名称
    //1 数据传输串口连接 2 数据传输串口断开
    if(!(UART_Config->open(QIODevice::ReadWrite)))      //打开的属性权限
    {
        LogSend("数据传输串口打开失败.\n");
        SendUartState(2); //发送信号 通知状态改变
    }
    else
    {
        LogSend("数据传输串口打开成功.\n");
        SendUartState(1); //发送信号 通知状态改变
        //关联数据读信号
        connect(UART_Config,SIGNAL(readyRead()),this,SLOT(UART_ReadUasrtData()),Qt::QueuedConnection);
    }
}
//读取串口数据
void UART_ReadWriteThread::UART_ReadUasrtData()
{
    QString byte;
    /*读取串口缓冲区所有的数据*/
    byte=UART_Config->readAll();
    LogSend(byte);
    /*读取串口缓冲区所有的数据*/
    gps_data.Data+=byte;
    //完整的1帧VTG--RMC数据在109字节左右
    //if(gps_data.Data.size()>=200)
    if(gps_data.Data.count("\r\n")>=2 && gps_data.Data.count("$GNRMC")>=1 && gps_data.Data.count("$GNVTG")>=1)
    {
        //保存原始数据
        gps_data.set_src_data(gps_data.Data);
        char *gps_p;
        char gps_tmp_buff[50];
        gps_p=gps_data.Data.toLocal8Bit().data();
        //计算$GNRMC校验和
        if(GPS_GetCheckSum(gps_p,"$GNRMC")==0)
        {
            //qDebug()<<"$GNRMC 校验和计算成功.\n";
           // LogSend("$GNRMC 校验和计算成功\n");
            //提取定位状态数据
            GPS_GetData(gps_p,"$GNRMC",gps_tmp_buff,2);
            //判断定位数据是否有效
            if(gps_tmp_buff[0]=='A')
            {
                SendUartState(3); //发送信号 通知状态改变  定位成功
                //qDebug()<<"定位成功.";
                //提取纬度
                GPS_GetData(gps_p,"$GNRMC",gps_tmp_buff,3);
                QString lat=gps_tmp_buff;  //得到纬度
                //提取经度
                GPS_GetData(gps_p,"$GNRMC",gps_tmp_buff,5);
                QString lng=gps_tmp_buff;  //得到经度
               // qDebug()<<"当前纬度:"<<lat;
               //qDebug()<<"当前经度:"<<lng;
                unsigned int int_data;
                double s_Longitude,s_latitude;
                //转换纬度
                s_latitude=lat.toDouble();
                s_latitude=s_latitude/100;
                int_data=s_latitude;//得到纬度整数部分
                s_latitude=s_latitude-int_data;//得到纬度小数部分
                s_latitude=(s_latitude)*100;
                gps_data.set_lat(int_data+(s_latitude/60.0)); //得到转换后的值
                //转换经度
                s_Longitude=lng.toDouble();
                s_Longitude=s_Longitude/100;
                int_data=s_Longitude;//得到经度整数部分
                s_Longitude=s_Longitude-int_data; //得到经度小数部分
                s_Longitude=s_Longitude*100;
                //gai guo le
                gps_data.set_lng(int_data+(s_Longitude/60.0));
            }
            else
            {
                SendUartState(4); //发送信号 通知状态改变  定位失败
                //GPS经纬度置0
                gps_data.set_lat(0.0);
                gps_data.set_lng(0.0);
            }
        }
        else
        {
            //GPS经纬度置0
            gps_data.set_lat(0.0);
            gps_data.set_lng(0.0);
        }
        //计算GNVTG校验和
        if(GPS_GetCheckSum(gps_p,"$GNVTG")==0)
        {
            //提取速度
            GPS_GetData(gps_p,"$GNVTG",gps_tmp_buff,7);
            gps_data.set_speed(gps_tmp_buff);
        }
        else
        {
            gps_data.set_speed("0");//当前速度置0
        }
        //清空数据
        gps_data.Data.clear();
    }
}
//关闭串口
//1 数据传输串口连接 2 数据传输串口断开
void UART_ReadWriteThread::Close_UART(void)
{
    SendUartState(2); //发送信号 通知状态改变
    if(UART_Config->isOpen())
    {
       UART_Config->close();
    }
}
//发送数据
void UART_ReadWriteThread::UART_Send(QString text)
{
   //qDebug()<<text;
    //如果串口处于打开状态就发送数据
    if(UART_Config->isOpen())
    {
        QByteArray byte=text.toLocal8Bit();
        UART_Config->write(byte);
    }
}
/*
函数功能: 根据逗号位置提取数据
函数参数:
char *gps_src GPS源字符串地址
char *buff 存放提取的数据
char *find_head 查找的GPS数据头  例如:$GNVTG
int cnt  逗号的偏移量
返回值:提取的字节数。
*/
int UART_ReadWriteThread::GPS_GetData(const char *gps_src,const char *find_head,char *buff,int cnt)
{
    const char *p;
    int number=0; //提取的数量
    int a=0;
    p=strstr(gps_src,find_head);
    if(p!=nullptr)
    {
        //查找逗号的位置
        while(*p!='\0')
        {
            if(*p==',')a++; //记录逗号的数量
            if(a==cnt)break; //逗号找成功了
            p++;
        }
        p++; //跨过当前逗号
        //提取数据
        while(*p!='\0')
        {
            if(*p==',')break; //遇到逗号停止提取数据
            buff[number]=*p;
            p++;
            number++;
        }
        buff[number]='\0';
    }
    return number;
}
/*
 * 计算GPS数据指定数据的校验和
 * char *src_str GPS源字符串
 * char *find_str GPS数据头  例如:$GNVTG
 * 返回值: -1表示失败  0表示成功
*/
int UART_ReadWriteThread::GPS_GetCheckSum(const char *src_str,const char *find_str)
{
    const char *tmp_p;
    /*1. 开始解析数据*/
    tmp_p=strstr(src_str,find_str);
    if(tmp_p!=nullptr)
    {
        unsigned char data=0;
        tmp_p++;
        //计算校验和
        while(*tmp_p!='*' && *tmp_p!='\0')
        {
            data^=*tmp_p;
            tmp_p++;
        }
        QString sum_str=QString::number(data,16);
        QString sum_val;
        //提取校验和
        sum_val[0]=*(tmp_p+1);
        sum_val[1]=*(tmp_p+2);
        //qDebug()<<"sum_val:"<<sum_val;
        //qDebug()<<"sum_str:"<<sum_str;
        //判断校验和,不区分大小写
        if(sum_str.compare(sum_val,Qt::CaseInsensitive)==0)
        {
            return 0; //校验正确
        }
    }
    return -1;
}

3.3 widget.h代码

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSerialPortInfo>
#include <QSerialPort>
#include <QPlainTextEdit>
#include <QScrollBar>
#include <QTimer>
#include <QThread>
#include <QDebug>
#include "uart_code.h"
#include "config.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = NULL);
    ~Widget();
    void GetDeviceList();
    /*构造一个列表*/
    QList<QSerialPortInfo> usart_device_list;
    QSerialPort *UART_Config; //串口
    QTimer timer;
    qint8 connect_state=0; //串口连接状态
    //串口线程
    UART_ReadWriteThread uart_WorkClass; //串口读写-工作函数
    QThread uart_Workthread; //串口读写--线程
private slots:
    void Log_Text_Display(QString text);
    void Log_Text_Display2(QString text);
    void UART_State_Display(qint8 state);  //串口状态显示
    void update();
    void on_pushButton_2_clicked();
    void on_pushButton_clicked();
    void on_pushButton_send_data_clicked();
    void on_pushButton_mode_set_clicked();
    void on_pushButton_open_all_clicked();
    void on_pushButton_close_all_clicked();
    void on_pushButton_open_rmc_clicked();
    void on_pushButton_open_vtg_clicked();
signals:
    void Start_Uart_Read();
    void Uart_SendData(QString text);
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

3.4 widget.cpp代码

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("GPS数据解析工具");
    GetDeviceList();
    connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
    timer.start(2000);
    //串口初始化
    //连接串口的日志信息
    connect(&uart_WorkClass,SIGNAL(LogSend(QString)),this,SLOT(Log_Text_Display(QString)));
    connect(&uart_WorkClass,SIGNAL(SendUartState(qint8)),this,SLOT(UART_State_Display(qint8)));
    //连接串口初始化函数
    connect(this,SIGNAL(Start_Uart_Read()),&uart_WorkClass,SLOT(run()));
    //连接串口发送函数
    connect(this,SIGNAL(Uart_SendData(QString)),&uart_WorkClass,SLOT(UART_Send(QString)));
    //将串口工作对象移动到子线程里工作
    uart_WorkClass.moveToThread(&uart_Workthread);
}
Widget::~Widget()
{
    delete ui;
}
void Widget::GetDeviceList()
{
    ui->comboBox->clear();
    //获取系统串口设备
    usart_device_list=QSerialPortInfo::availablePorts();
    /*打印出支持的串口名称*/
    for(int i=0;i<usart_device_list.count();i++)
    {
        ui->comboBox->addItem(usart_device_list.at(i).portName());
    }
}
void Widget::on_pushButton_2_clicked()
{
    GetDeviceList();
}
void Widget::on_pushButton_clicked()
{
    current_SerialPort=ui->comboBox->currentText();  //当前串口端口号
    current_SerialBaudRate=ui->comboBox_baud->currentText().toInt(); //当前波特率
    if(ui->pushButton->text()=="打开串口")
    {
        if(current_SerialPort.isEmpty()||current_SerialBaudRate<=0)
        {
            QMessageBox::information(this,"提示","请先选择串口COM和波特率\n在菜单栏的设置页面找到串口设置按钮.",
            QMessageBox::Ok,QMessageBox::Ok);
        }
        else
        {
            ui->pushButton->setText("关闭串口");
            uart_Workthread.start(); //启动串口线程
            Start_Uart_Read(); //发送信号启动串口工作
        }
    }
    else
    {
        uart_WorkClass.Close_UART(); //关闭串口
        uart_Workthread.quit(); //退出线程
        uart_Workthread.wait(); //等待线程退出
        ui->pushButton->setText("打开串口");
    }
}
/*日志显示*/
void Widget::Log_Text_Display(QString text)
{
    QPlainTextEdit *plainTextEdit_log=ui->plainTextEdit;
    //设置光标到文本末尾
    plainTextEdit_log->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
    //当文本数量超出一定范围就清除
    if(plainTextEdit_log->toPlainText().size()>4096)
    {
        plainTextEdit_log->clear();
    }
    plainTextEdit_log->insertPlainText(text);
    //移动滚动条到底部
    QScrollBar *scrollbar = plainTextEdit_log->verticalScrollBar();
    if(scrollbar)
    {
        scrollbar->setSliderPosition(scrollbar->maximum());
    }
}
/*日志显示*/
void Widget::Log_Text_Display2(QString text)
{
    QPlainTextEdit *plainTextEdit_log=ui->plainTextEdit2;
    //设置光标到文本末尾
    plainTextEdit_log->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
    //当文本数量超出一定范围就清除
    if(plainTextEdit_log->toPlainText().size()>4096)
    {
        plainTextEdit_log->clear();
    }
    plainTextEdit_log->insertPlainText(text);
    //移动滚动条到底部
    QScrollBar *scrollbar = plainTextEdit_log->verticalScrollBar();
    if(scrollbar)
    {
        scrollbar->setSliderPosition(scrollbar->maximum());
    }
}
void Widget::update()
{
    QString text="";
    QString gps_text=gps_data.get_src_data();
    gps_data.set_src_clear(); //清除保存的原始数据
    gps_text=gps_text.remove("\r");
    gps_text=gps_text.remove("\n");
    //串口连接成功的情况下才需要打印
    if(connect_state==1)
    {
        text="GPS:";
        text+=tr("纬度=%1,").arg(gps_data.get_lat(),0,'g',13); //纬度
        text+=tr("经度=%1,").arg(gps_data.get_lng(),0,'g',13); //经度
        text+=tr("速度=%1\n").arg(gps_data.get_speed());//速度
        Log_Text_Display2(text);
        text+=tr("原始数据:%1\n").arg(gps_text);//原始数据
        Log_Text_Display2(text);
    }
}
//串口状态显示
//1 数据传输串口连接 2 数据传输串口断开
void Widget::UART_State_Display(qint8 state)
{
   if(state==1)
   {
       connect_state=state;
       Log_Text_Display("串口连接\n");
   }
   if(state==2)
   {
       connect_state=state;
       Log_Text_Display("串口断开\n");
   }
   if(state==3)  //GPS定位成功
   {
       ui->label_gps_stat->setText("GPS定位状态: 定位成功");
   }
   if(state==4)  //GPS定位失败
   {
       ui->label_gps_stat->setText("GPS定位状态: 正在定位中..请稍等");
   }
}
//发送数据
void Widget::on_pushButton_send_data_clicked()
{
    QString text=ui->lineEdit_send_data->text();
    if(ui->checkBox->isChecked())
    {
        text+="\r\n";
        Uart_SendData(text);
    }
    else
    {
        Uart_SendData(text);
    }
}
void Widget::on_pushButton_mode_set_clicked()
{
     Uart_SendData("$PCAS11,3*1E\r\n");
}
void Widget::on_pushButton_open_all_clicked()
{
    Uart_SendData("$CCRMO,GGA,4,1*38\r\n");
}
void Widget::on_pushButton_close_all_clicked()
{
    Uart_SendData("$CCRMO,GGA,3,1*3F\r\n");
}
void Widget::on_pushButton_open_rmc_clicked()
{
    Uart_SendData("$CCRMO,RMC,2,1*23\r\n");
}
void Widget::on_pushButton_open_vtg_clicked()
{
     Uart_SendData("$CCRMO,VTG,2,1*3A\r\n");
}


目录
打赏
0
0
0
0
88
分享
相关文章
【硬件测试】基于FPGA的1024QAM基带通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文介绍了基于FPGA的1024QAM基带通信系统的硬件测试版本,包含testbench、高斯信道模块和误码率统计模块。系统新增ila在线数据采集和vio在线SNR设置模块,支持不同SNR条件下的性能测试。1024QAM调制将10比特映射到复平面上的1024个星座点之一,实现高效数据传输。硬件测试结果表明,在SNR=32dB和40dB时,系统表现出良好的性能。Verilog核心程序展示了各模块的连接与功能实现。
58 7
【硬件测试】基于FPGA的QPSK调制+软解调系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文基于FPGA实现QPSK调制与软解调系统,包含Testbench、高斯信道、误码率统计模块,并支持不同SNR设置。硬件版本新增ILA在线数据采集和VIO在线SNR设置功能,提供无水印完整代码及测试结果。通过VIO分别设置SNR为6dB和12dB,验证系统性能。配套操作视频便于用户快速上手。 理论部分详细解析QPSK调制原理及其软解调实现过程,涵盖信号采样、相位估计、判决与解调等关键步骤。软解调通过概率估计(如最大似然法)提高抗噪能力,核心公式为*d = d_hat / P(d_hat|r[n])*,需考虑噪声对信号点分布的影响。 附Verilog核心程序代码及注释,助力理解与开发。
55 5
【硬件测试】基于FPGA的MSK调制解调系统系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文基于FPGA实现MSK调制解调系统,采用Verilog开发,包含同步模块、高斯信道模拟、误码率统计等功能。相比仿真版本,新增ILA数据采集与VIO在线SNR设置模块。通过硬件测试验证,展示不同SNR(如10dB和16dB)下的性能表现。研究聚焦软件无线电领域,优化算法复杂度以适应硬件限制,利用MSK恒定包络、相位连续等特性提升频谱效率。核心代码实现信号生成、调制解调、滤波及误码统计,提供完整的硬件设计与分析方案。
91 19
【硬件测试】基于FPGA的4ASK调制解调通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文介绍了基于FPGA的4ASK调制解调系统的硬件测试版本,该系统包括testbench、高斯信道模块和误码率统计模块,并新增了ILA在线数据采集和VIO在线SNR设置功能。通过VIO设置不同SNR(如15dB和25dB),实现了对系统性能的实时监测与调整。4ASK是一种通过改变载波幅度表示数据的数字调制方式,适用于多种通信场景。FPGA平台的高效性和灵活性使其成为构建高性能通信系统的理想选择。
81 17
【硬件测试】基于FPGA的16QAM调制+软解调系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文基于之前开发的16QAM调制与软解调系统,增加了硬件测试功能。该系统包含FPGA实现的16QAM调制、软解调、高斯信道、误码率统计模块,并新增了ILA在线数据采集和VIO在线SNR设置模块。通过硬件测试,验证了不同SNR条件下的系统性能。16QAM软解调通过比较接收信号采样值与16个调制点的距离,选择最近的调制点来恢复原始数据。核心Verilog代码实现了整个系统的功能,包括SNR设置、信号处理及误码率统计。硬件测试结果表明系统在不同SNR下表现良好,详细操作步骤可参考配套视频。
62 13
【硬件测试】基于FPGA的4FSK调制解调通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文基于之前的文章《基于FPGA的4FSK调制解调系统》,增加了ILA在线数据采集模块和VIO在线SNR设置模块,实现了硬件测试版本。通过VIO设置不同SNR(如10dB和20dB),并展示了ILA采集的数据结果。四频移键控(4FSK)是一种数字调制方法,利用四个不同频率传输二进制数据,具有较高的频带利用率和抗干扰性能。输入的二进制数据分为两组,每组两个比特,对应四个频率f1、f2、f3、f4,分别代表二进制组合00、01、10、11。调制过程中选择相应频率输出,并进行幅度调制以增强抗干扰能力。接收端通过带通滤波器提取信号并还原为原始二进制数据。
56 7
【硬件测试】基于FPGA的256QAM基带通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文介绍了基于FPGA的256QAM基带通信系统的硬件测试版本,包含testbench、高斯信道模块和误码率统计模块。系统新增ila在线数据采集和vio在线SNR设置模块,支持不同信噪比(如30dB和40dB)的仿真测试,并提供配套操作视频。256QAM调制方案每个符号携带8比特信息,通过复数值星座图映射实现高效传输。Verilog代码展示了核心模块设计,包括SNR设置、数据处理和ILA测试分析,确保系统在实际硬件环境中的稳定性和性能。
30 2
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(一)
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(一)
118 2
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(二)
Kali 渗透测试:基于结构化异常处理的渗透-使用Python编写渗透模块(二)
132 2
【硬件测试】基于FPGA的16QAM基带通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文介绍了基于FPGA的16QAM基带通信系统硬件测试版本。该系统在仿真基础上增加了ILA在线数据采集和VIO在线SNR设置模块,支持不同信噪比(如15dB、25dB)的测试。16QAM是一种正交幅度调制方式,通过两路4ASK信号叠加实现,每个符号包含4比特信息。系统采用正交调幅法生成16QAM信号,并通过DAC转换为模拟信号。解调时使用正交相干解调,经低通滤波器恢复电平信号。开发板内完成发射与接收,无需定时同步模块。代码可移植至其他开发板,具体步骤见配套文档。
44 2

热门文章

最新文章

下一篇
oss创建bucket
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等