当前位置: 首页 > news >正文

ZYNQ实验---IQ调制实现SSB PART2

一、前言

  本文实验在ZYNQ实验—IQ调制实现SSB PART1的基础上进行优化完善。

下图为IQ调制实现SSB PART1中设想实现设计框图
在这里插入图片描述
在这里插入图片描述
该图设计存在的几个问题:

  • PC-PS的UDP传输存在丢包
  • 中断控制发包实际不适合流数据的传输
  • 采用的BRAM模块可以存储的空间较小,PC到PL的时间相对较长,很容易出现RAM读空。

针对以上几个问题提出的解决方案

  • 设计对速率和实时性要求不高,UDP在低速情况下丢包率低。
  • PC数据如果不缓存直接送到PL中时间过长。ZYNQ带4Gbit的DDR选择将数据先完整的存在DDR中再进行PS到PL的传输。
  • 输出的数据是一种流数据形式,使用半空读写方式持续读写FIFO即可保持数据的连续性。

新的IQ调制实现SSB设计框图
在这里插入图片描述

二、实验准备

实验平台与工具:ZYNQ7020,HackRF One,AN108 ADDA板,Matlab 2021b,Vivado 2018

2.1 IQ数据生成

使用matlab生成IQ基带数据,不同形式的基带数据决定了我们的输出调制方式,本实验先用正弦信号做测试。

fs_au = 32E3;         % 采样频率
f = 2E3;              % 正弦信号测试频率
ts=128;				  % 采样时间,秒为单位
t = 0:1/fs_au:ts-1/fs_au;  % 生成ts秒的时间序列,步进为1/fs_au% 定义文件路径和文件名
filename = 'nengcd.mp3'; %测试音频
% 读取MP3文件
[y, Fs] = audioread(filename);
% 转换采样率
y_resampled = resample(y, fs_au, Fs);
% 截取ts秒数据
start_time = 1; % 从缓存结束开始
end_time = ts*fs_au; % 截取ts秒
y_s = y_resampled(start_time : end_time);% % 生成正弦信号
% x = sin(2*pi*f*t);
% y_hilbert=fi(hilbert(x), 1, 16); %定点化数据% 进行希尔伯特变换生成IQ数据
y_hilbert=fi(hilbert(y_s), 1, 16); %定点化数据y_real=real(y_hilbert);
y_imag=imag(y_hilbert);% 绘制采样信号
plot(t, y_real);
xlabel('时间(秒)');
ylabel('幅度');
ylim([-2 2]);
title('原始信号');
grid on;% IQ数据保存 保存为16进制格式,4个字符表示一个数据
% 这样的数据格式虽然增加了数据量但是便于输出观察,实际2个字节表示16bit即可
filename = 'music_real.txt';
% 打开文件进行写入
fileID = fopen(filename, 'w');
% 将定点数以格式化的方式写入文件
fprintf(fileID, '%s\n', y_real.hex);
% 关闭文件
fclose(fileID);% 文件名
filename = 'music_imag.txt';
% 打开文件进行写入
fileID = fopen(filename, 'w');
% 将定点数以格式化的方式写入文件
fprintf(fileID, '%s\n', y_imag.hex);
% 关闭文件
fclose(fileID);

2.2 Simulink 仿真及Verliog代码生成

参考文章:
Simulink HDL–如何生成Verliog代码
IQ调制实现SSB PART1

2.3 C#设计PC端软件

在以往的工程中使用C#设计过简单的软件,实验中也设计了一个调试软件。

  1. 红色区域为串口区域,可以接收PS端的串口信息
  2. 黄色区域为网络区域,读取matlab生成的数据文件通过UDP发送至DDR
    UDP 通信协议帧结构
    数据报文结构 0xAA 1byte类型 2bytes数据长度 2bytes分片数 Lbytes数据 1byte和校验
    指令报文结构 0xAA 1byte类型 2bytes指令长度 2bytes指令 1byte和校验

在这里插入图片描述

2.3 Vivado – PL与PS设计

ZYNQ的设计如图所示
连接关系:PS->AXI Stream FIFO->AXI Stream Data FIFO->上变频和调制模块->DAC输出
在这里插入图片描述
说明:

  1. AXI Stream FIFO设置半空读写,AXI Stream Data FIFO做缓冲作用。ZYNQ实验 FIFO读写实验(如何平衡跨时钟域的读写)
    在这里插入图片描述
    PS端对AXI Stream FIFO的半空读写示例程序
//初始化FIFO
DDR_rd(0,4096,IQchioce);
Status = FIFOTxSend(&FifoInstance, FIFOSourceBuffer);//FIFOTxSend是FIFO示例中的发送函数
while(1)
{//UDP是按512个数据发送到DDR中的,因此读取2048是从DDR中读4组数据for(i=0;i<cmd_picenum;i+=4){// 半空状态读取Status = XLlFifo_Status(&FifoInstance);Halfempty= Status & 0x00200000;if(Halfempty){//DDR读取数据,幅值到FIFOSourceBufferDDR_rd(0,2048,IQchioce);//发送数据至FIFO。循环写入相同的2048个数据XLlFifo_IntClear(&FifoInstance,0xffffffff);Status = FIFOTxSend2(&FifoInstance, FIFOSourceBuffer);//FIFOTxSend2只发送2048个数据的if (Status != XST_SUCCESS){xil_printf("Transmisson of Data failed\n\r");return XST_FAILURE;}memset(FIFOSourceBuffer2,0,2048);}else{i=i-4;}}
}
  1. Data_interception 模块
    该模块将AXI Stream类型的数据转化为上变频模块可以使用的数据格式。实验中DDR的32bit数据的高16bit存I数据,低16bit存Q数据,因此将DDR中读取到的数据分为两路16bit数据送入上变频模块。
    在这里插入图片描述
  2. PS端代码问题
    IQ调制实现SSB PART1实验中是不涉及PS端设计的,数据存在RAM中进行循环输出。在本实验中PS成为了很关键的沟通PC和FPGA的部分,PS端功能主要涉及串口收发,UDP收发,DDR读写,AXI Stream FIFO读写,某些功能在我的ZYNQ学习专栏中可以找到,网上也有很多实现教程。

三、 实验结果

3.1 输出2kHz正弦信号

ILA 观察信号

在这里插入图片描述
在这里插入图片描述

示波器观察信号

2kHz在1MHz上经过SSB调制,输出1.002MHz信号
在这里插入图片描述

3.2 输出音频信号

HackRF One接收SSB信号,解调出音频信号,最终的效果一般。结果不好与收发端设备有关,整个系统比较简易。
在这里插入图片描述

总结

  整个工程设计虽然简单,但也算我设计的第一个完整的系统。实验数据从PC端一直到DAC输出的过程在框图中看着简单,但在实际调试中遇到了很多的bug和曲折,matlab生成的代码也是存在一定的问题对FPGA设计不熟练的话很容易遇到很多难以发现和解决的问题。这个东西也是抽空做一点慢慢搭起来的,虽然在某些问题上花费了很大的精力但是我也学到了很多东西,各种开发调试的经验,工具平台的了解使用,包括现在对FPGA和嵌入式也有了新的认识等等。

main函数代码

int main()
{int Status;int Halffull;//半满标记XUartPs_Config *Config;u16 revnum=0;u16 i,j=0;u8 state = UART_RXCHECK ;ReceivedBufferPtr = ReceivedBuffer ;ReceivedFlag = 0 ;ReceivedByteNum = 0 ;/* Uart init*/Config = XUartPs_LookupConfig(UART_DEVICE_ID);if (NULL == Config) {return XST_FAILURE;}Status = XUartPs_CfgInitialize(&Uart_PS, Config, Config->BaseAddress);if (Status != XST_SUCCESS) {return XST_FAILURE;}/* Use Normal mode. */XUartPs_SetOperMode(&Uart_PS, XUARTPS_OPER_MODE_NORMAL);/* Set uart mode Baud Rate 115200, 8bits, no parity, 1 stop bit */XUartPs_SetDataFormat(&Uart_PS, &UartFormat) ;/*Set receiver FIFO interrupt trigger level, here set to 1*/XUartPs_SetFifoThreshold(&Uart_PS,1) ;/* Enable the receive FIFO trigger level interrupt and empty interrupt for the device */XUartPs_SetInterruptMask(&Uart_PS,XUARTPS_IXR_RXOVR|XUARTPS_IXR_RXEMPTY);SetupInterruptSystem(&IntcInstPtr, &Uart_PS, UART_INT_IRQ_ID);/* UDP init*/struct netif *netif, server_netif;ip_addr_t ipaddr, netmask, gw;/*  开发板MAC地址  */unsigned char mac_ethernet_address [] ={0x00, 0x0a, 0x35, 0x00, 0x01, 0x02};/*  开启中断系统  */Init_Intr_System(&IntcInstPtr);Setup_Intr_Exception(&IntcInstPtr);netif = &server_netif;IP4_ADDR(&ipaddr,  192, 168,  1, 30);IP4_ADDR(&netmask, 255, 255, 255, 0);IP4_ADDR(&gw,      192, 168,  1,  1);lwip_init();   //初始化lwIP库/* 添加网络接口并将其设置为默认接口 */if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, XPAR_XEMACPS_0_BASEADDR)) {xil_printf("Error adding N/W interface\r\n");return -1;}netif_set_default(netif);netif_set_up(netif);        //启动网络user_udp_init();            //初始化UDP/* FIFO init*/Status = XLlFifoPollingExample(&FifoInstance, FIFO_DEV_ID);//初始化FIFOwhile (1){/*  将MAC队列中的包传输的LwIP/IP栈中   */xemacif_input(netif);//revnum=UartRevdata(); //串口通信revnum=udp_ReadData(UDPrecvBuffer);memcpy(PC2PScmd,UDPrecvBuffer,revnum);if(revnum>=6){switch(PC2PScmd[1]){case 0x00: //DDR数据输出至FIFO{if(revnum==7 && RX_CheckSum(PC2PScmd,7)==0){cmd_picenum=(u16)PC2PScmd[4]+((u16)PC2PScmd[5]<<8);xil_printf("cmd_picenum=%x\n\r",cmd_picenum);DDR_rdIQ(0,4096,IQchioce);Status = FIFOTxSend(&FifoInstance, FIFOSourceBuffer); //填满FIFOwhile(1) //循环输出数据{for(i=0;i<cmd_picenum;i+=4){// FIFO_sentStatus = XLlFifo_Status(&FifoInstance);//xil_printf("Status=%x\n\r",Status);Halffull= Status & 0x00200000;if(Halffull){DDR_rdIQ(i*512,2048,IQchioce);/* Transmit the Data Stream */XLlFifo_IntClear(&FifoInstance,0xffffffff);Status = FIFOTxSend2(&FifoInstance, FIFOSourceBuffer2);//半满FIFOif (Status != XST_SUCCESS){xil_printf("Transmisson of Data failed\n\r");return XST_FAILURE;}}else{i=i-4;}}}memcpy(UDPsentBuffer,PC2PScmd,7);memset(PC2PScmd,0,7);udp_SentData(7,UDPsentBuffer);countnum=0;}break;}case 0x01: //写入DDR{cmd_datalen=PC2PScmd[2]+(PC2PScmd[3]<<8);cmd_picenum=PC2PScmd[4]+(PC2PScmd[5]<<8);if(revnum==1031 && RX_CheckSum(PC2PScmd,1031)==0) //1031 为整个数据帧的长度,数据一次传1024字节{DDR_wr(cmd_picenum*512,cmd_datalen,IQchioce); //512*16bits=1024*8bits,16bit才是一个完整的数据memcpy(UDPsentBuffer,PC2PScmd,3);UDPsentBuffer[3]=0x01;udp_SentData(4,UDPsentBuffer);printf("picenum=%d\n",cmd_picenum);memset(PC2PScmd,0,1031);countnum=0;}break;}case 0x02: //写入IQ选择,分别存在DDR的不同区域{if(revnum==7 && RX_CheckSum(PC2PScmd,7)==0){IQchioce=PC2PScmd[4];memset(PC2PScmd,0,7);}countnum=0;break;}default:{countnum=0;break;}}}}return 0;}

相关文章:

ZYNQ实验---IQ调制实现SSB PART2

一、前言 本文实验在ZYNQ实验—IQ调制实现SSB PART1的基础上进行优化完善。 下图为IQ调制实现SSB PART1中设想实现设计框图 该图设计存在的几个问题&#xff1a; PC-PS的UDP传输存在丢包中断控制发包实际不适合流数据的传输采用的BRAM模块可以存储的空间较小&#xff0c;PC…...

机器学习-特征工程

一、特征工程介绍 1.1 什么是特征 数值特征&#xff08;连续特征&#xff09;、文本特征&#xff08;离散特征&#xff09; 1.2 特征的种类 1.3 特征工程 特征是机器学习可疑直接使用的&#xff0c;模型和特征之间是一个循环过程&#xff1b; 实际上特征工程就是将原始数据…...

大数据技术之集群数据迁移

文章目录 数据治理之集群迁移数据 数据治理之集群迁移数据 准备两套集群&#xff0c;我这使用apache集群和CDH集群。 启动集群 启动完毕后&#xff0c;将apache集群中&#xff0c;hive库里dwd,dws,ads三个库的数据迁移到CDH集群 在apache集群里hosts加上CDH Namenode对应域名并…...

CF1265E Beautiful Mirrors

CF1265E Beautiful Mirrors 洛谷CF1265E Beautiful Mirrors 题目大意 Creatnx \text{Creatnx} Creatnx有 n n n面魔镜&#xff0c;每天她会问一面镜子&#xff1a;“我漂亮吗&#xff1f;”&#xff0c;第 i i i面魔镜有 p i 100 \dfrac{p_i}{100} 100pi​​的概率告诉 Creat…...

软件测试/测试开发丨利用ChatGPT自动生成架构图

点此获取更多相关资料 简介 架构图通过图形化的表达方式&#xff0c;用于呈现系统、软件的结构、组件、关系和交互方式。一个明确的架构图可以更好地辅助业务分析、技术架构分析的工作。架构图的设计是一个有难度的任务&#xff0c;设计者必须要对业务、相关技术栈都非常清晰…...

Java学习笔记(六)——面向对象编程(基础)

一、类与对象 &#xff08;一&#xff09;类与对象的概念 &#xff08;二&#xff09;对象内存布局 ​编辑 对象分配机制 ​编辑 &#xff08;三&#xff09;属性/成员变量 &#xff08;四&#xff09;创建对象与访问属性 二、成员方法 &#xff08;一&#xff09;方法…...

0基础学习PyFlink——个数滚动窗口(Tumbling Count Windows)

大纲 Tumbling Count WindowsmapreduceWindow Size为2Window Size为3Window Size为4Window Size为5Window Size为6 完整代码参考资料 之前的案例中&#xff0c;我们的Source都是确定内容的数据。而Flink是可以处理流式&#xff08;Streaming&#xff09;数据的&#xff0c;就是…...

车载终端构筑智慧工厂:无人配送车的高效物流体系

​随着科技的不断进步和应用&#xff0c;智能化已经成为许多领域的关键词。在物流行业中&#xff0c;随着无人配送车的兴起和智慧工厂的崛起&#xff0c;车载终端正引领着无人配送车的科技变革之路。 文章同款&#xff1a;https://www.key-iot.com/iotlist/sv900.html 车载终端…...

插件_日期_lunar-calendar公历农历转换

现在存在某需求&#xff0c;需要将公历、农历日期进行相互转换&#xff0c;在此借助lunar-calendar插件完成。 下载 [1] 通过npm安装 npm install lunar-calendar[2]通过文件方式引入 <script type"text/javascript" src"lib/LunarCalendar.min.js">…...

【FreeRTOS】【STM32】08 FreeRTOS 消息队列

简单来说 消息队列是一种数据结构 任务操作队列的基本描述 1.如果队列未满或者允许覆盖入队,FreeRTOS会将任务需要发送的消息添加到队列尾。 2.如果队列满,任务会阻塞(等待)。 3.用户可以指定等待时间。 4.当其它任务从其等待的队列中读取入了数据&#xff08;这时候队列未满…...

【计算机组成原理】CPU的工作原理

一.CPU的组成结构 CPU主要有运算器、控制器、寄存器和内部总线等组成&#xff0c;其大概的样子长这样&#xff1a; 看不懂没关系&#xff0c;我们将采用自顶而下的方法来讲解CPU的具体工作原理&#xff0c;我们首先来说一下什么叫寄存器&#xff0c;顾名思义&#xff0c;寄存器…...

部署ELK

一、elasticsearch #拉取镜像 docker pull elasticsearch:7.12.1 #创建ELK docker网络 docker network create elk #启动ELK docker run -d --name es --net elk -P -e "discovery.typesingle-node" elasticsearch:7.12.1 #拷贝配置文件 docker cp es:/usr/share/el…...

纯前端实现图片验证码

前言 之前业务系统中验证码一直是由后端返回base64与一个验证码的字符串来实现的&#xff0c;想了下&#xff0c;前端其实可以直接canvas实现&#xff0c;减轻服务器压力。 实现 子组件&#xff0c;允许自定义图片尺寸(默认尺寸为100 * 40)与验证码刷新时间(默认时间为60秒)…...

#django基本常识01#

1、manage.py 所有子命令的入口&#xff0c;比如&#xff1a; python3 manage.py runserver 启动服务 python3 manage.py startapp 创建应用 python3 manage.py migrate 数据库迁移 直接执行python3 manage.py 可显示所有子命令...

什么是物流RPA?物流RPA解决什么问题?物流RPA实施难点在哪里?

RPA指的是机器人流程自动化&#xff0c;它是一套模拟人类在计算机、平板电脑、移动设备等界面执行任务的软件。通过RPA&#xff0c;可以自动完成重复性、繁琐的工作&#xff0c;提高工作效率和质量&#xff0c;降低人力成本。RPA适用于各种行业和场景&#xff0c;例如财务、人力…...

乐鑫工程部署过程记录

一、获取编译环境 1、下载sdk&#xff0c;ESP-IDF 这里有很多发布版本&#xff0c;当前我选择的是4.4.6&#xff0c;可以选择下载压缩包&#xff0c;也可以git直接clone 2、配置编译环境 我选择的是Linux Ubuntu下部署开发环境 查看入门指南 选择对应的芯片&#xff0c;我…...

to 后接ing形式的情况

look forward to seeing you. (期待着见到你) She admitted to making a mistake. (承认犯了个错误) He is accustomed to working long hours. (习惯于长时间工作)...

我做云原生的那几年

背景介绍 在2020年6月&#xff0c;我加入了一家拥有超过500人的企业。彼时&#xff0c;前端团队人数众多&#xff0c;有二三十名成员。在这样的大团队中&#xff0c;每个人都要寻找自己的独特之处和核心竞争力。否则&#xff0c;你可能会沉没于常规的增删改查工作中&#xff0…...

@EventListener注解使用说明

在Java的Spring框架中&#xff0c;EventListener注解用于监听和处理应用程序中的各种事件。通过使用EventListener注解&#xff0c;开发人员可以方便地实现事件驱动的编程模型&#xff0c;提高代码的灵活性和可维护性。本文将详细探讨EventListener注解的使用方法和作用&#x…...

算法通关村第五关-白银挑战实现队列

大纲 队列基础队列的基本概念和基本特征实现队列队列的基本操作Java中的队列 队列基础 队列的基本概念和基本特征 队列的特点是节点的排队次序和出队次序按入队时间先后确定&#xff0c;即先入队者先出队&#xff0c;后入队者后出队&#xff0c;即我们常说的FIFO(first in fi…...

Android Studio里的BLE数据接收策略

#本人是初次接触Android蓝牙开发&#xff0c;若有不对地方&#xff0c;欢迎指出。 #由于是讲接收数据策略(其中还包含数据发送的部分策略)&#xff0c;因此其他问题部分不会讲述&#xff0c;只描述数据接收。 简介(对于客户端---手机端) 博主在处理数据接收的时候&#xff0…...

独立机构软件第三方检测:流程、需求分析及电商软件检验要点?

独立机构承担着对软件进行第三方检测的任务&#xff0c;这一环节对于提升软件的质量和稳定性起到了极其关键的作用。检测过程拥有一套完善的流程&#xff0c;目的在于确保检测结果的精确性&#xff0c;并保障软件达到高标准。 需求分析 确保软件测试需求清晰十分关键。我们需…...

历年武汉大学计算机保研上机真题

2025武汉大学计算机保研上机真题 2024武汉大学计算机保研上机真题 2023武汉大学计算机保研上机真题 在线测评链接&#xff1a;https://pgcode.cn/school 分段函数计算 题目描述 写程序计算如下分段函数&#xff1a; 当 x > 0 x > 0 x>0 时&#xff0c; f ( x ) …...

(18)混合云架构部署

文章目录 &#x1f680; 混合云架构部署&#xff1a;Java应用的云原生之旅&#x1f329;️ 混合云架构简介⚡ Java应用云原生部署五大核心技术1️⃣ 容器化与编排技术2️⃣ 服务网格与API网关3️⃣ CI/CD自动化流水线4️⃣ 多云管理平台5️⃣ 云原生Java框架与运行时 &#x1f…...

深度剖析Node.js的原理及事件方式

早些年就接触过Node.js&#xff0c;当时对于这个连接前后端框架就感到很特别。尤其是以独特的异步阻塞特性&#xff0c;重塑了了服务器端编程的范式。后来陆陆续续做了不少项目&#xff0c;通过实践对它或多或少增强了不少理解。今天&#xff0c;我试着将从将从原理层剖析其运行…...

有什么excel.js支持IE11,可以显示EXCEL单元格数据,支持单元格合并,边框线,单元格背景

有什么excel.js支持IE11,可以显示EXCEL单元格数据,支持单元格合并,边框线,单元格背景 在 IE11 环境下操作 Excel 且需要支持单元格合并、边框、背景等格式时&#xff0c;需考虑兼容性较强的库。以下是符合需求的工具及对比分析&#xff1a; 1. SheetJS&#xff08;js-xlsx&am…...

Kubernetes超详细教程,一篇文章帮助你从零开始学习k8s,从入门到实战

k8s 概述 k8s github地址&#xff1a;https://github.com/kubernetes/kubernetes 官方文档&#xff1a;https://kubernetes.io/zh-cn/docs/home/ k8s&#xff0c;全程是 kubernetes&#xff0c;这个名字源于希腊语&#xff0c;意为"舵手"或"飞行员” k8s 这…...

智能外呼系统中 NLP 意图理解的工作原理与技术实现

智能外呼系统通过整合语音识别&#xff08;ASR&#xff09;、自然语言处理&#xff08;NLP&#xff09;和语音合成&#xff08;TTS&#xff09;等技术&#xff0c;实现了自动化的电话交互。其中&#xff0c;NLP 意图理解是核心模块&#xff0c;负责解析用户话语中的语义和意图&…...

黑马点评-分布式锁Lua脚本

文章目录 分布式锁Redis setnxredis锁误删Lua脚本 分布式锁 当我们的项目服务器不只是一台&#xff08;单体&#xff09;&#xff0c;而是部署在多态服务器上&#xff08;集群/分布式&#xff09;&#xff0c;同样会出现线程安全问题。不同服务器内部有不同的JVM&#xff0c;每…...

leetcode617.合并二叉树:递归思想下的树结构融合艺术

一、题目深度解析与核心规则 题目描述 合并两棵二叉树是一个经典的树结构操作问题&#xff0c;题目要求我们将两棵二叉树合并成一棵新二叉树。合并规则如下&#xff1a; 若两棵树的对应节点都存在&#xff0c;则将两个节点的值相加作为新节点的值若其中一棵树的节点存在&…...