FPGA实现AD9708和AD9280波形收发输出HDMI模拟示波器,串口协议帧控制显示,提供工程源码和技术支持

news2025/1/16 1:03:20

目录

  • 1、AD9708芯片解读和电路设计
  • 2、AD9280芯片解读和电路设计
  • 3、FPGA设计框架
  • 4、AD9708波形生成并发送
  • 5、AD9280采集接收波形
  • 6、HDMI波形显示算法
  • 7、串口协议帧控制波形显示
  • 8、vivado工程
  • 9、上板调试验证
  • 10、福利:工程源码获取

1、AD9708芯片解读和电路设计

AD9708 很简单,8 位分辨率,125MSPS 采样率,输入参考电压3~5V,内置 1.2V 参考电压,8bit数字信号输入,差分电流输出;芯片操作不需要软件配置,给个时钟信号就工作,简单得很,根据官方手册,内部结构如下:
在这里插入图片描述
在这里插入图片描述
SLEEP引脚提供芯片休眠功能,当不需要使用该芯片时可拉高SLEEP以降低电路板功耗,当不使用休眠功能时,官方建议该引脚悬空;
REFLO引脚接模拟地开启内置1.2V 参考电压功能,既然芯片都提供了这样的功能,当然要用啊,不用时要接AVDD;
芯片外围电路就这么简单,照着官方手册画就完事儿了,重要的是芯片输出的匹配电路设计,AD9708 是差分输出,若要用线缆输出连接其他设备,必然要实现差分转单端的功能,为了为了防止噪声干扰,保持输出波形的线条完美,参考了网上大佬,推荐使用7 阶巴特沃斯低通滤波器;原理图部分如下:
在这里插入图片描述
然后再使用差分转单端芯片输出模拟单端信号;

2、AD9280芯片解读和电路设计

AD9280也 很简单,8 位分辨率,32MSPS 采样率,输入参考电压2.7~5.5V,芯片操作不需要软件配置,给个时钟信号就工作,简单得很,根据官方手册,内部结构如下:
在这里插入图片描述
在这里插入图片描述
STBY引脚接高电平进入休眠模式,接低电平则一直工作;根据电路板功耗要求设计;
这里重点将一下输入电压AIN;作为模拟输入,它可以配置为多种模式,分别由不同引脚得上下拉决定,具体看手册,说得很清楚,这里只将我这里的配置,参考了官方给的设计如下:
在这里插入图片描述
根据官方给的公式:
在这里插入图片描述
REFBS引脚接地;REFTS引脚接地2V;

3、FPGA设计框架

在这里插入图片描述
可以看到:本设计哟如下功能:
1、上位机软件生成波形文件,通过AD9708发送出去;
2、AD9280接收AD9708发出的波形(回环);并采集;
3、HDMI显示器显示AD9280采集的波形;
4、AD9708发送的波形类型由串口配置;
5、HDMI显示波形的位置由串口配置;

4、AD9708波形生成并发送

采用上位机软件生成波形文件,并转化为.coe文件,vivado调用rom ip核,将.coe文件固化进去即可,波形数据直接给到AD9708输出接口即可,简单得很;
本设计设计了三种波形,正弦波,三角波,正弦波和三角波结合的自定义波形;
AD9708输出哪种波形由串口控制,串口发送不同数据,AD9708输出不同波形;
波形生成上位机软件附带在工程目录下,可直接转化为.coe文件,如下:
在这里插入图片描述

5、AD9280采集接收波形

AD9280采集接收AD9708发来波形;由于要适配显示器,所以AD9280采集需要设置时间间隔,不然看不到波形了;同时,AD9280采集数据后需要写入ram中,由视频时序生成器读出数据,达到跨时钟的作用;AD9280采集时钟为32M,视频时钟为65M;

6、HDMI波形显示算法

波形在屏幕上的显示效果如下:
在这里插入图片描述
显示分辨率设为1024X768;
对照上图,设置相关参数如下:

wire [23:0] GRID_BACK         = 24'h000000                     ;	//波形显示区域背景颜色
wire [23:0] GRID_WAVE         = 24'h00ff00                     ;	//波形格子条纹颜色
wire [10:0] GRID_LENGTH       = 11'd1010                       ;	//波形显示区域长度
wire [10:0] GRID_WIDTH        = 11'd300                        ;	//波形显示区域宽度
//parameter GRID_X_START      = 11'd9                        ;	//波形显示区域背景x轴起始坐标
wire [10:0] GRID_X_END        = i_grid_x_start+GRID_LENGTH-1'b1;	//波形显示区域背景x轴终点坐标
//parameter GRID_Y_START      = 11'd243                      ;	//波形显示区域背景y轴起始坐标	
wire [10:0] GRID_Y_END        = i_grid_y_start+GRID_WIDTH-1'b1 ;	//波形显示区域背景y轴终点坐标	
wire [10:0] GRID_CENTRE       = i_grid_y_start+GRID_WIDTH/2    ;	//波形显示区域背景中间线位置
wire [10:0] GRID_Y_WAVE_START = i_grid_y_start+11'd23          ;	//波形格子条纹y轴起始坐标
wire [10:0] GRID_Y_WAVE_END   = GRID_Y_END-11'd21            	 ;	//波形格子条纹y轴终点坐标

其中波形显示区域背景x轴起始坐标和波形显示区域背景y轴起始坐标由输入接口决定,如下:

	input  [10:0] i_grid_x_start,
	input  [10:0] i_grid_y_start,

波形显示区模块的顶层接口如下:

module helai_grid_disp (
	input         pclk          ,
	input  [10:0] i_grid_x_start,
	input  [10:0] i_grid_y_start,
	input  [10:0] i_pos_x       ,	
	input  [10:0] i_pos_y       ,
	input         i_de          ,
	input  [23:0] i_data        ,     
	output [23:0] o_data        
);

波形显示画线模块的顶层接口如下:

module helai_wav_disp (
	input         pclk          ,  
	input  [23:0] wave_color    ,
	input         adc_clk       ,
	input         adc_buf_wr    ,
	input  [11:0] adc_buf_addr  ,
	input  [7:0]  adc_buf_data  ,
	input  [10:0] i_grid_x_start,
	input  [10:0] i_grid_y_start,	
	input  [10:0] i_pos_x       ,	
	input  [10:0] i_pos_y       ,	
	input         i_de          ,	
	input  [23:0] i_data        ,    
	output [23:0] o_data        
);

只要给出i_grid_x_start和i_grid_y_start两个参数,就能决定波形显示区的位置;
而这两个参数由串口输入决定;

7、串口协议帧控制波形显示

串口协议帧由帧头、数据、和校验、帧尾组成,其中数据4字节,有关串口协议帧,请参考我之前写的文章点击查看串口协议帧
FPGA解析串口协议帧,提取有效的4字节数据,控制波形输出和显示位置,具体协议如下:

//串口有效数据 Byte3 Byte2 Byte1 Byte0
//Byte3:定义波形显示区域背景x轴起始坐标
//Byte2和Byte1:波形显示区域背景y轴起始坐标
//Byte0=0-->输出正弦波
//Byte0=1-->输出三角波
//Byte0=2-->输出自定义波

代码层面如下:

always @(posedge clk_200m) begin
	if(~rst_n) _rx_data<=32'h09_00_f3_00;	//9 ,234 ,0
	else if(o_rx_done) _rx_data<=o_rx_data;
end

reg [7:0] wave_data;

always @(*) begin
	if(_rx_data[7:0]==8'd0) wave_data<=dac_sin;	
	else if(_rx_data[7:0]==8'd1) wave_data<=dac_triangular; 
	else if(_rx_data[7:0]==8'd2) wave_data<=dac_zihui;
	else wave_data<=dac_sin;
end

上电后,波形默认显示在屏幕正中间位置,如下:
在这里插入图片描述

8、vivado工程

开发板:Xilinx Artix7开发板;
开发环境:vivado2019.1;
输入:串口、AD波形;
输出:AD数据、HDMI视频;
代码架构如下:
在这里插入图片描述
顶层代码如下:

module top(
	input        sys_clk_p  ,
	input        sys_clk_n  ,
	input[7:0]   ad9280_data,
	output       ad9280_clk ,
	output[7:0]  ad9708_data,
	output       ad9708_clk ,
    inout        hdmi_scl   ,
    inout        hdmi_sda   ,
    output       hdmi_nreset,
    output       vout_clk   ,
    output       vout_hs    ,
    output       vout_vs    ,
    output       vout_de    ,
    output[23:0] vout_data  ,
	input        i_uart_rx  ,	
	output       o_uart_tx	
	
);

wire      video_clk;
wire      video_hs;
wire      video_vs;
wire      video_de;

wire       adc_clk;
wire       adc0_buf_wr;
wire[10:0] adc0_buf_addr;
wire[7:0]  adc0_buf_data;
wire       dac_clk;

wire [7:0] dac_sin  ;
wire [7:0] dac_triangular;
wire [7:0] dac_zihui;
reg  [8:0] rom_addr;

wire[9:0]  hdmi_lut_index;
wire[31:0] hdmi_lut_data;

assign vout_clk    = video_clk;
assign vout_hs     = video_hs;
assign vout_vs     = video_vs;
assign vout_de     = video_de;
assign vout_data   = wave0_rgb;

assign hdmi_nreset = rst_n;
assign ad9280_clk = adc_clk;
assign ad9708_clk = dac_clk;
assign ad9708_data = wave_data;
wire rst_n;
wire clk_200m;

wire        o_rx_done;
wire [31:0] o_rx_data;
reg  [31:0] _rx_data;

wire [23:0] video_rgb;
wire [10:0] x_pos;
wire [10:0] y_pos;
wire [23:0] grid_rgb;
wire [23:0] wave0_rgb;

clk_wiz_0 u_clk_wiz_0
   (
    // Clock out ports
    .clk_200m(clk_200m),     // output clk_200m
    .clk_video(video_clk),     // output clk_video
    .clk_adc(adc_clk),     // output clk_adc
    .clk_dac(dac_clk),     // output clk_dac
    // Status and control signals
    .locked(rst_n),       // output locked
   // Clock in ports
    .clk_in1_p(sys_clk_p),    // input clk_in1_p
    .clk_in1_n(sys_clk_n));    // input clk_in1_n 
 
 //I2C master controller
i2c_config i2c_config_m2(
   .rst           (~rst_n              ),
   .clk           (clk_200m            ),
   .clk_div_cnt   (16'd500             ),
   .i2c_addr_2byte(1'b0                ),
   .lut_index     (hdmi_lut_index      ),
   .lut_dev_addr  (hdmi_lut_data[31:24]),
   .lut_reg_addr  (hdmi_lut_data[23:8] ),
   .lut_reg_data  (hdmi_lut_data[7:0]  ),
   .error         (                    ),
   .done          (                    ),
   .i2c_scl       (hdmi_scl            ),
   .i2c_sda       (hdmi_sda            )
);
//configure look-up table
lut_hdmi lut_hdmi_m0(
   .lut_index(hdmi_lut_index),
   .lut_data (hdmi_lut_data )
); 
//dac 125Mhz/512 = 244.14khz
always@(posedge dac_clk) rom_addr <= rom_addr + 9'd1;

always @(posedge clk_200m) begin
	if(~rst_n) _rx_data<=32'h09_00_f3_00;	//9 ,234 ,0
	else if(o_rx_done) _rx_data<=o_rx_data;
end

reg [7:0] wave_data;

always @(*) begin
	if(_rx_data[7:0]==8'd0) wave_data<=dac_sin;	
	else if(_rx_data[7:0]==8'd1) wave_data<=dac_triangular; 
	else if(_rx_data[7:0]==8'd2) wave_data<=dac_zihui;
	else wave_data<=dac_sin;
end

sin_rom u_sin_rom (
	.clka (dac_clk ),   
	.ena  (1'b1    ),     
	.addra(rom_addr), 
	.douta(dac_sin )  
);

triangular_rom u_triangular_rom (
  .clka (dac_clk       ),    // input wire clka
  .ena  (1'b1          ),      // input wire ena
  .addra(rom_addr      ),  // input wire [8 : 0] addra
  .douta(dac_triangular)  // output wire [7 : 0] douta
);

zihui_rom u_zihui_rom (
  .clka (dac_clk     ),    // input wire clka
  .ena  (1'b1        ),      // input wire ena
  .addra(rom_addr    ),  // input wire [8 : 0] addra
  .douta(dac_zihui   )  // output wire [7 : 0] douta
);

uart_rx_analysis_top #(
    .CLK_FREQ(200_000_000),  //系统时钟频率
    .UART_BPS(115200     )   //串口波特率
)
u_uart_rx_analysis_top(
	.clk       (clk_200m ),
	.rst_n     (rst_n    ),
	.i_uart_rx (i_uart_rx),
	.o_uart_tx (o_uart_tx),
	.o_rx_done (o_rx_done),
	.o_rx_data (o_rx_data)
);

video_timing_control u_video_timing_control(
	.i_clk  (video_clk ),	
	.i_rst_n(rst_n     ), 
	.i_rgb  (24'hffffff),
	.o_hs   (video_hs  ),
	.o_vs   (video_vs  ),
	.o_de   (video_de  ),
	.o_rgb  (video_rgb ),
	.o_x_pos(x_pos     ),
	.o_y_pos(y_pos     )
);

helai_grid_disp u_helai_grid_disp(
	.pclk          (video_clk      ), 
	.i_grid_x_start(_rx_data[31:24]),
	.i_grid_y_start(_rx_data[23: 8]),	
	.i_pos_x       (x_pos          ),	
	.i_pos_y       (y_pos          ),
	.i_de          (video_de       ),	
	.i_data        (video_rgb      ),     
	.o_data        (grid_rgb       )
);

ad9280_sample ad9280_sample_m0(
	.adc_clk       (adc_clk      ),
	.rstn          (rst_n        ),
	.adc_data      (ad9280_data  ),
	.adc_data_valid(1'b1         ),
	.adc_buf_wr    (adc0_buf_wr  ),
	.adc_buf_addr  (adc0_buf_addr),
	.adc_buf_data  (adc0_buf_data)
);

helai_wav_disp u_helai_wav_disp(
	.pclk          (video_clk      ),  
	.wave_color    (24'h00ff00     ),
	.adc_clk       (adc_clk        ),
	.adc_buf_wr    (adc0_buf_wr    ),
	.adc_buf_addr  (adc0_buf_addr  ),
	.adc_buf_data  (adc0_buf_data  ),
	.i_grid_x_start(_rx_data[31:24]),
	.i_grid_y_start(_rx_data[23: 8]),	
	.i_pos_x       (x_pos          ),	
	.i_pos_y       (y_pos          ),	
	.i_de          (video_de       ),	
	.i_data        (grid_rgb       ),    
	.o_data        (wave0_rgb      )
);
endmodule

9、上板调试验证

演示视频如下:

FPGA实现AD9708和AD9280波形收发输出HDMI模

10、福利:工程源码获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料如下:获取方式:文章末尾
网盘资料如下
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/331233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

85024A是德科技keysight高频探头

附加功能&#xff1a; 易于执行在线测量出色的频率响应和单位增益探头灵敏度高低失真度规格输入电容&#xff08;在 500 MHz 时&#xff09;&#xff1a;< 0.7pF&#xff08;标称值&#xff09;输入电阻&#xff1a;1 MΩ&#xff08;标称值&#xff09;带宽&#xff1a;30…

2月8日刷题总结

写题一点思路也没有&#xff0c;题解也不能看得很懂。所以系统性的学习DP ing……跟着进度来&#xff0c;因此刷了一些已经刷过的类型的题&#xff08;也算再次熟悉一下&#xff09;P1077 [NOIP2012 普及组] 摆花题目描述小明的花店新开张&#xff0c;为了吸引顾客&#xff0c;…

力扣SQL刷题5

目录597. 好友申请 I&#xff1a;总体通过率602. 好友申请 II &#xff1a;谁有最多的好友603. 连续空余座位1045. 买下所有产品的客户597. 好友申请 I&#xff1a;总体通过率 官方讲的题目太繁琐了&#xff0c;大概就是&#xff08;表2中列1列2不全相同的行数&#xff09;/&a…

测试开发之Vue学习笔记-Vue路由

Vue路由18. Vue-路由基础安装 cnpm install --save vue-router官方文档&#xff1a;https://router.vuejs.org/zh/src/main.js中&#xff08;1&#xff09;引入VueRouter&#xff1a;import VueRouter from "vue-router"&#xff08;2&#xff09;使用VueRouter&…

《知行合一王阳明》读书笔记

《知行合一王阳明》用通俗易懂的语言介绍了王阳明一生的传奇经历和他的心学的核心思想。这篇读后感主要介绍一下我对心学的理解。在我看来&#xff0c;心学最本质的要求是“致良知”&#xff0c;最核心的方法论是“知行合一”。致良知是说要遵从自己的本心。王阳明相信人性本善…

(蓝桥杯 刷题全集)【备战(蓝桥杯)算法竞赛-第1天(基础算法-上 专题)】( 从头开始重新做题,记录备战竞赛路上的每一道题 )距离蓝桥杯还有75天

&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6;&#x1f3c6; 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&a…

兔年新佳绩,思迈特软件获奖喜讯纷至沓来

近年来&#xff0c;随着大数据、云计算、人工智能、5G等技术加速创新&#xff0c;越来越多的ToB企业开始下沉探索边际&#xff0c;纵深业务服务场景&#xff0c;通过技术与行业的深度融合&#xff0c;为客户提供全面的转型服务&#xff0c;尽一切可能创造客户价值和商业价值。思…

【C++: list的模拟实现】

目录 1 list的简单回顾 2 类中成员变量的声明 3 __list_iterator 中运算符重载 4 list中的迭代器 5 list中增删查改以及clear 6 const迭代器 6.1 __list_iterator的重新实现 6.2 list类的巧妙修改 7 构造函数&&拷贝构造&&赋值运算符重载 8 反向迭代器…

金三银四丨黑蛋老师带你剖析-二进制漏洞

作者&#xff1a;黑蛋二进制漏洞岗上篇文章我们初步了解了一下简历投递方式以及二进制方向相关逆向岗位的要求&#xff0c;今天我们就来看看二进制漏洞相关的岗位&#xff0c;当然&#xff0c;漏洞岗位除了分不同平台&#xff0c;也有漏洞挖掘岗和漏洞分析利用岗。同样&#xf…

[人工智能-综述-11]:ChatGPT, 通用人工智能还是要来了

该来的还是要来的&#xff01;补充信息&#xff1a;ChatGPT是由人工智能研究实验室OpenAI在2022年11月30日发布的全新聊天机器人模型&#xff0c;一款人工智能技术驱动的自然语言处理工具。它能够通过学习和理解人类的语言来进行对话&#xff0c;还能根据聊天的上下文进行互动&…

C语言共用体(C语言union用法)详解

我们知道结构体&#xff08;Struct&#xff09;是一种构造类型或复杂类型&#xff0c;它可以包含多个类型不同的成员。在C语言中&#xff0c;还有另外一种和结构体非常类似的语法&#xff0c;叫做共用体&#xff08;Union&#xff09;&#xff0c;它的定义格式为&#xff1a;un…

STM32的HAL库分析及使用

STM32的HAL库分析及使用 STM32的三种开发方式 通常新手在入门STM32的时候&#xff0c;首先都要先选择一种要用的开发方式&#xff0c;不同的开发方式会导致你编程的架构是完全不一样的。一般大多数都会选用标准库和HAL库&#xff0c;而极少部分人会通过直接配置寄存器进行开发…

【Mysql第八期 子查询】

文章目录前言1. 需求分析与问题解决1.2 子查询的基本使用1.3 子查询的分类2. 单行子查询2.1 单行比较操作符2.2 代码示例2.5 子查询中的空值问题3. 多行子查询3.1 多行比较操作符3.2 代码示例3.3 空值问题4. 相关子查询4.2 代码示例4.3 EXISTS 与 NOT EXISTS关键字4.4 相关更新…

开发者社区「运营官」招募启动啦!

国内首个聚焦AI3D视觉技术的开发者社区「运营官」招募启动啦&#xff01; 想积累实习经验&#xff0c;却苦于找不到大厂机会&#xff1f; 想进入AI3D视觉行业&#xff0c;却苦于没有知音伯乐&#xff1f; 想积累更多工作经历&#xff0c;却苦于路程奔波、天各一方&#xff1f…

我们的微服务中为什么需要网关?

说起 Spring Cloud Gateway 的使用场景&#xff0c;我相信很多小伙伴都能够脱口而出认证二字&#xff0c;确实&#xff0c;在网关中完成认证操作&#xff0c;确实是 Gateway 的重要使用场景之一&#xff0c;然而并不是唯一的使用场景。在微服务中使用网关的好处可太多了&#x…

MODBUS TCP 转 PROFINET 网关从站快速配置手册

一、本案例是1500PLC通过微硬创新MODBUS TCP 转 PROFINET 网关连接组态王服务器从站快速配置&#xff0c;将 Modbus TCP 设备数据转接入到西门子 PROFINET 网络中 二、设备列表如下&#xff1a; 三、MODBUS TCP 转 PROFINET 网关从站快速配置方法步骤&#xff1a; 第1步&#x…

全网最详细的介绍ChatGPT:包括ChatGPT原理、应用、如何试用以及回答ChatGPT能否让程序员失业

文章目录1. 介绍ChatGPT2. ChatGPT示例3. 试用ChatGPT4. ChatGPT原理5. ChatGPT应用5.1 世界杯问题咨询5.2 写书信&#xff08;情书&#xff09;6. 总结1. 介绍ChatGPT 今天开车去上班的路上&#xff0c;听到电台介绍ChatGPT&#xff0c;此时百度的股价涨幅为25%&#xff0c;当…

谈谈Spring中Bean的生命周期?(让你瞬间通透~)

目录 1.Bean的生命周期 1.1、概括 1.2、图解 2、代码示例 2.1、初始化代码 2.2、初始化的前置方法和后置方法&#xff08;重写&#xff09; 2.3、Spring启动类 2.4、执行结果 2.5、经典面试问题 3.总结 1.Bean的生命周期 1.1、概括 Spring中Bean的生命周期就是Bean在…

Spring Cloud Alibaba+saas企业架构技术选型+架构全景业务图 + 架构典型部署方案

基于Spring Cloud Alibaba 分布式微服务高并发数据平台化(中台)思想多租户saas设计的企业开发架构&#xff0c;支持源码二次开发、支持其他业务系统集成、集中式应用权限管理、支持拓展其他任意子项目。 一、架构技术选型 核心框架 Spring Boot SOA Spring Cloud …

如何搞垮一个测试团队【反向教学,最为致命】

如何搞垮一个测试团队【反向教学&#xff0c;最为致命】 目录&#xff1a;导读 一、QA 二、项目经理 三、产品经理 四、开发人员 五、测试人员 六、组织文化 七、组织战略 要想彻底搞垮一个测试团队并非易事&#xff0c;需要多角色通力配合、多方联动、综合施策&#x…