[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-39 HDMI视频输入测试

news2024/12/23 18:02:34

软件版本:VIVADO2021.1

操作系统:WIN10 64bit

硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA

实验平台:米联客-MLK-H3-CZ08-7100开发板

板卡获取平台:https://milianke.tmall.com/

登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

目录

1概述

2ADV7611参数介绍

3硬件电路分析

4 ADV7611配置说明

4.1 I2C从机地址

4.2主模式和视频制式

4.3像素输出

4.1 uicfg7611.v

4.2 ui7611reg.v

5 hdmi_in_test.v

6硬件接线

7测试结果


1概述

米联客开发板上集成的HDMI输入芯片方案采用ADV7611实现,对于没有集成HDMI输入芯片的开发板可以采用FEP扩展卡实现HDMI输入,本文介绍HDMI输入方案ADV7611的实现,对于通过FEP子卡实现的方案相关的配套课程会做出介绍。本文采用的ADV7611可以实现1080P60fps视频输出,默认我们输出的格式为RGB888。本文要实现的功能也很简单,只要完成HDMI视频输入后再通过前面一节课的HDMI输入IP把视频信号正确输出就可以。

本文内容也有一个重要的阶段就是我们会利用前面一些编写好的IP模块应用于新的方案中,比如前面的I2C控制器IP和HDMI输出IP,这也是我们米联客编写代码注重代码可重复利用,注重构架的优势。我们以后会把一些常用IP模块做一个列表说明方便大家使用。

2ADV7611参数介绍

ADV7611采用先进的CMOS工艺制造,提供64引脚、10 mm × 10 mm LQFP_EP表贴封装,符合RoHS标准,是一款高质量、单输入HDMI®接收器,内置HDMI兼容型接收器,支持HDMI 1.4a规定的所有强制性3D电视格式和最高UXGA 60 Hz、8位的分辨率。它集成一个CEC控制器,支持能力发现和控制(CDC)特性。并且提供汽车级、专业级(无HDCP)和工业级三种版本,工作温度范围为−40 ℃至+85 ℃。

具有一个音频输出端口,用于输出从HDMI流提取的音频数据。HDMI接收器具有高级静音控制器,可消除音频输出中的外来声频噪声。

可以访问下列音频格式:

1、来自I2S 串行器的音频流(两个音频通道)

2、来自S/PDIF串行器的音频流(两个未压缩通道或N个压缩通道,例如AC3)

3、DST音频流

HDMI端口具有专用的5 V检测和热插拔(Hot Plug™)置位引脚。该HDMI接收器还集成一个均衡器,用于确保与长电缆的接口具有鲁棒的工作性能。

3硬件电路分析

硬件接口和子卡模块请阅读“附录 1”

配套工程的 FPGA PIN 脚定义路径为 fpga_prj/uisrc/04_pin/ fpga_pin.xdc。

4 ADV7611配置说明

ADV7611是一款高质量、单输入HDMI®接收器,内置HDMI兼容型接收器,支持HDMI 1.4a规定的所有强制性3D电视格式,和最高UXGA 60 Hz、8位的分辨率。

4.1 I2C从机地址

ADV7611通过I2C接口配置,一个IIC总线上可以挂在两个adv7611。器件IO寄存器地址为0x98/0x9A,这个地址是固定的,通过复用的引脚 VS/FIELD/ALSB 和配置寄存器SAMPLE_ALSB来控制。默认以0x98为例介绍。

同时,ADV7611还包含几个IIC地址可配置的功能寄存器,它们的配置方式如下图所示。

可以看到,CEC、EDID、CP等功能寄存器的IIC地址都可以通过对应的IO寄存器来配置它们的默认地址。这里,可以使用上面给出的默认的地址。比如以EDID的IIC地址为例,只需要在IO寄存器地址0x98,子寄存器地址为0xFA的寄存器写入数值0x6C,那么EDID的IIC地址就配置为了0x6c。

4.2主模式和视频制式

设置主模式和选择视频标准是配置ADV7611时最基本的设置。adv7611有两种主要模式HDMI-component and HDMI-graphic modes 。也就是hdmi组件和hdmi图形两种模式。通过寄存器PRIM_MODE[3:0]来配置。

在HDMI模式下,ADV7611可以通过DVI/HDMI接收器前端接收和解码HDMI或DVI数据。来自HDMI接收器的视频数据被传递到组件处理器CP模块,而音频数据在音频接口上可用。可以通过选择hdmi组件或hdmi图形主模式来启用其中一种模式。

这里需要说明的是,HDMI接收器可以解码和处理任何应用的HDMI流,而不关心视频分辨率。然而,许多主要模式和视频标准组合可以用来定义如何处理传输到DPP和CP块的视频数据流。这允许一些系统可能需要的自由运行特性和数据抽取模式。

所谓的free run自由运行模式就是在没有接受到正常HDMI信号或者没有接入信号时,可以自动生成一个HDMI视频流,给到后级系统用于测试或者其他应用。比如,可以设置一个蓝屏的信号这在实际使用中很有用处。

这里主模式和视频制式设置很大的作用其实就是设置这个free run所执行的模式和视频标准。

PRIM_MODE[3:0]寄存器地址为0x98,0x01[3:0],功能描述如下图:

VID_STD[5:0][3:0]寄存器地址为0x98,0x00[5:0],寄存器为6bits,它与PRIM_MODE[3:0]配合使用,设置如下图:

V_FREQ[2:0]寄存器地址为0x98,0x01[6:4],用于设置帧率,功能描述如下图:

4.3像素输出

ADV7611的输出部分非常灵活。像素输出总线最高可支持24位4:4:4 YCrCb。像素数据支持SDR和DDR两种数据速率模式。在SDR模式下,可以实现16/24位4:2:2或24位4:4:4输出。在DDR模式下1,像素输出端口可配置为8/12位4:2:2YCrCb或24位4:4:4 RGB。

从上面两个表可以看到,ADV7611具有非常灵活的像素端口,可以各种格式配置以适应下游ic。

OP_FORMAT_SEL对应的寄存器地址为0x98,0x03 。如下图所示:

通常我们采用24bits SDR mode或者16bits SDRmode,也就是将对应寄存器配置为0x40或者0x80.注意这里对于444模式来说,包含RGB和YCBCR两种色彩制式,对于422模式来说,只有YCBCR一种。

上面说了,ADV7611的输出非常灵活,可以自由的配置输出接口总线对应的像素。如下图所示,可以通过寄存器OP_CH_SEL[2:0]来配置如下六种不同的引脚-总线对应关系。OP_CH_SEL[2:0]寄存器地址为0x98,0x04[7:5].

可以看到,默认情况下,P23-P16引脚对应的RGB模式的R分量输出,P15-P8引脚对应的RGB模式的G分量输出,P7-P0引脚对应的RGB模式的B分量输出。在444的YCBCR模式下,P23-P16引脚对应的为V分量输出,P15-P8引脚对应的Y分量输出,P7-P0引脚对应的U分量输出。在422的YCBCR模式下,P23-P16引脚无对应分量输出,P15-P8引脚对应的Y分量输出,P7-P0引脚对应的CBCR分量输出。同样的,可以通过配置寄存器将引脚和分量自由绑定。

其实到了这里,我们只需要再知道如何配置输出为RGB还是YCBCR就能够使用了。这里输出哪种色彩分量实际时通过CP CSC来控制的。也就是组件处理器的色彩空间转换功能。CP CSC转换功能有两种模式手动模式和自动模式。

这里CSC_COEFF_SEL[3:0]对应的寄存器地址时0x44,0x68[7:4] 。注意这里不再是IO寄存器地址了,时CP寄存器地址0x44。前面提到过,这个地址是可编程的,如果用户修改了CP地址,这里就要对应使用修改后的地址。

CP CSC配置为自动模式后,CSC矩阵、agc增益值、偏移量都能够通过下面的几个寄存器自动配置。

INP_COLOR_SPACE[3:0]寄存器地址为0x98,0x02[7:4],对应功能如下:

注意这个寄存器设置的是输入视频的色彩空间。通常我们不做特别的变换,使用默认值1111即可。

RGB_OUT寄存器地址为0x98,0x02[1],对应的功能如下:

可以看到,为0时是YCBCR的色彩空间输出,为1时是RGB的色彩空间输出。这里YPBPR是ycbcr是在模拟分量上的叫法,读者可以认为它们是一样的。

ALT_GAMMA寄存器地址0x98 ,0x02[3],对应的功能如下:

可以看到,该寄存器主要是做YUV601和yuv709之间的转换,默认为0不做转换,为1则输入为YUV601时转换为YUV709,输入为YUV709时转换为YUV601。

可以看到,这几个寄存器对应的地址都是0x98,0x02。它们的配置方式如下:

像素数据和同步信号控制

上面说的都是数据总线接口,还离不开时钟和同步信号,这里的时钟叫做LLC,行锁定时钟,其实就是常说的像素时钟。

ADV7611的像素输出引脚P0-P23 ,时钟引脚LLC,同步输出引脚VS/FIELD/ALSB、HS、DE,以及音频接口输出引脚都可以通过对应寄存器配置为输出有效和三态输出两种。对应的寄存器地址为0x98,0x15,在配置时需要将这些引脚设置为有效输出状态。这里不在详细叙述。

OP_SWAP_CB_CR寄存器地址为0x98,0x05[0],功能描述如下图:

这个功能就是交换Cr和Cb数据输出的顺序。默认值0为输出CrCb顺序按照OP_FORMAT_SET寄存器设置来,置位1后则交换CRCB的流出顺序,其实就是设置CB和CR谁在前的顺序问题。这里可以看到,这个功能只对设置为YUV422模式有效。在设计中,这个功能有时很有用。

同时,时钟引脚LLC,同步输出引脚VS/FIELD/ALSB、HS、DE的极性也可以通过对应寄存器设置。

ADV7611通过LLC引脚提供的像素时钟的极性可以使用INV_LLC_POL位进行反转。注意,这种反转只影响LLC输出引脚。其他输出引脚不受INV_LLC_POL影响。

为了满足处理ADV7611输出数据的下游设备的设置和保持时间预期,可能需要改变LLC时钟输出的极性。无论传输的视频数据是什么类型,INV_LLC_POL都适用。这其实相当于调整了时钟相位180度。

INV_LLC_POL寄存器地址为0x98, 0x06[0],功能描述如下图:

同样的,同步引脚极性也可以调整。

INV_HS_POL寄存器地址为0x98, 0x06[1],功能描述如下图:

INV_VS_POL寄存器地址为0x98, 0x06[2],功能描述如下图:

INV_F_POL寄存器地址为0x98, 0x06[3],功能描述如下图:

其实,到了这里我们就可以将adv7611使用起来了,可以看到,最关键的就是配置IO寄存器的前面几个寄存器。如下图将输出配置为24bits SDR 444 RGB输出。

那么,如果我需要的输出为24bits SDR 444 YCBCR输出怎么设置?只需要将RGB_OUT寄存器(地址为0x98,0x02[1])置为1即可。

同样的,调整对应寄存器,可以修改为16bits SDR 422 YCBCR输出。

当然,用户还可以根据自己的需要,按照前面寄存器功能说明,配置为相应的输出模式,比如,引脚输出和总线对应关系寄存器OP_CH_SEL[2:0](地址为0x98,0x04[7:5])来调整RGB或YCBCR各个分量所在的引脚。

这里需要注意的是,上面的调整没有涉及到分辨率的信息,比如我们常说的1920x1080、1280x720等等,前面其实提到了,adv7611接收器可以接收它支持的任意分辨率HDMI信号,通过adv7611之后输出为对应的分辨率的TLL信号。后端FPGA或者其他处理单元需要根据分辨率的不同做对应的逻辑处理。比如,配置为24bits SDR 444 RGB模式,既可以接受1080P信号也可以接受720P信号,而FPGA接收端需要根据接收到的数据流判断当前分辨率是哪种,将对应的参数信息给到后端处理单元。

4.1 uicfg7611.v

此文件里面有寄存器的配置表,以及调用米联客的i2c控制器把寄存器的配置信息写入到ADV7611,以下配置实现了ADV7611输入的视频信号以RGB888的格式输出。这里我们没有给出ADV7611每个寄存器的功能说明,读者如果觉得有必要可以自己登录ADI的官网搜索相关资料。

这里重点是看下状态机部分代码,因为这里是我们利用米联客的I2C控制器实现寄存器的配置,这个方法在FPGA里面配置HDMI芯片的寄存器,或者摄像头的寄存器,都非常实用,状态代码如下。代码中我们设置三个关键参数,iic_en/wr_cnt/ wr_data就可以完成对I2C总线设备的配置。

always@(posedge I_clk ) begin 
    if(rst_cnt[7] == 1'b0)begin //复位初始化寄存器
        reg_index<= 9'd0;
        iic_req  <= 1'b0;
        wr_data  <= 32'd0;
        O_cfg_done <= 1'b0;
        TS_S     <= 2'd0;    
    end
    else begin
        case(TS_S)
        0:if(reg_index == REG_SIZE) //如果配置完成
            O_cfg_done <= 1'b1;       //设置 O_cfg_done标准
          else if(O_cfg_done == 1'b0) //如果未配置完成
            TS_S <= 2'd1;           //下一个状态
        1:if(!iic_busy)begin        //当总线非忙,才可以操作I2C控制器
            iic_req  <= 1'b1;       //请求操作I2C控制器
            wr_data[7  :0] <= REG_DATA[23:16];  //器件地址   
            wr_data[15 :8] <= REG_DATA[15: 8];  //寄存器地址     
            wr_data[23:16] <= REG_DATA[7 : 0];  //寄存器数据
            TS_S      <= 2'd2; //下一个状态
        end    
        2:if(iic_busy)begin
             iic_req  <= 1'b0;  //重置 iic_req =0
             TS_S     <= 2'd3;  //下一个状态
        end
        3:if(!iic_busy)begin  //当总线非忙,才可以操作I2C控制器 
            reg_index<= reg_index + 1'b1;//寄存器索引加1
            TS_S    <= 2'd0;//回到初始状态
        end 
        endcase
   end
end
以下给出完整代码:
/*******************************uicfg7611***************************
--1.ADV7611芯片配置驱动程序
********************************************************************/
`timescale 1ns / 1ns

module uicfg7611#
(
parameter    CLK_DIV  = 16'd999
)
(
input  I_clk,  //系统时钟输入
input  I_rst_n,  //系统复位输入
output O_adv_scl, //I2C总线,SCL时钟
inout  IO_adv_sda, //I2C总线,SDA数据
output reg O_cfg_done //配置完成
);  

//内部计数器产生一个延迟复位
reg[7:0] rst_cnt =0;
always@(posedge I_clk or negedge I_rst_n)  
    if(I_rst_n == 1'b0) //复位初始化寄存器
        rst_cnt<= 8'd0; 
    else if(rst_cnt[7] == 1'b0)
       rst_cnt <= rst_cnt + 1'b1; 
    else 
       rst_cnt <= rst_cnt; 

reg  iic_req;//请求操作I2C控制器信号
wire ic_busy; //I2C控制器忙信号 
reg  [31:0] wr_data;     //写数据寄存器
reg  [1 :0] TS_S = 2'd0; //状态机寄存器
reg  [8 :0] reg_index;   //寄存索引
wire [23:0] REG_DATA;    //寄存器数据
wire [8 :0] REG_SIZE;    //寄存器数量

always@(posedge I_clk ) begin 
    if(rst_cnt[7] == 1'b0)begin //复位初始化寄存器
        reg_index<= 9'd0;
        iic_req  <= 1'b0;
        wr_data  <= 32'd0;
        O_cfg_done <= 1'b0;
        TS_S     <= 2'd0;    
    end
    else begin
        case(TS_S)
        0:if(reg_index == REG_SIZE) //如果配置完成
            O_cfg_done <= 1'b1;       //设置 O_cfg_done标准
          else if(O_cfg_done == 1'b0) //如果未配置完成
            TS_S <= 2'd1;           //下一个状态
        1:if(!iic_busy)begin        //当总线非忙,才可以操作I2C控制器
            iic_req  <= 1'b1;       //请求操作I2C控制器
            wr_data[7  :0] <= REG_DATA[23:16];  //器件地址   
            wr_data[15 :8] <= REG_DATA[15: 8];  //寄存器地址     
            wr_data[23:16] <= REG_DATA[7 : 0];  //寄存器数据
            TS_S      <= 2'd2; //下一个状态
        end    
        2:if(iic_busy)begin
             iic_req  <= 1'b0;  //重置 iic_req =0
             TS_S     <= 2'd3;  //下一个状态
        end
        3:if(!iic_busy)begin  //当总线非忙,才可以操作I2C控制器 
            reg_index<= reg_index + 1'b1;//寄存器索引加1
            TS_S    <= 2'd0;//回到初始状态
        end 
        endcase
   end
end

//例化I2C控制模块
uii2c#
(
.WMEN_LEN(4),     //最大支持一次写入4BYTE(包含器件地址)
.RMEN_LEN(1),     //最大支持一次读出1BYTE
.CLK_DIV(CLK_DIV) //100KHZ I2C总线时钟
)
uii2c_inst
(
.I_clk(I_clk),//系统时钟
.I_rstn(rst_cnt[7]),//系统复位
.O_iic_scl(O_adv_scl),//I2C SCL总线时钟
.IO_iic_sda(IO_adv_sda),//I2C SDA数据总线
.I_wr_data(wr_data),//写数据寄存器
.I_wr_cnt(8'd3),//需要写的数据BYTES
.O_rd_data(),   //读数据寄存器
.I_rd_cnt(8'd0),//需要读的数据BYTES
.I_iic_mode(1'b0),//读模式设置
.I_iic_req(iic_req),//I2C控制器请求
.O_iic_busy(iic_busy)//I2C控制器忙
);

//例化ADV7611的寄存器配置表
ui7611reg  ui7611reg_inst
(
.O_REG_SIZE(REG_SIZE),  //寄存器数量
.I_REG_INDEX(reg_index),//寄存索引
.O_REG_DATA(REG_DATA)   //寄存器数据
);  

endmodule

以下给出完整代码:

always@(posedge I_clk ) begin 
    if(rst_cnt[7] == 1'b0)begin //复位初始化寄存器
        reg_index<= 9'd0;
        iic_req  <= 1'b0;
        wr_data  <= 32'd0;
        O_cfg_done <= 1'b0;
        TS_S     <= 2'd0;    
    end
    else begin
        case(TS_S)
        0:if(reg_index == REG_SIZE) //如果配置完成
            O_cfg_done <= 1'b1;       //设置 O_cfg_done标准
          else if(O_cfg_done == 1'b0) //如果未配置完成
            TS_S <= 2'd1;           //下一个状态
        1:if(!iic_busy)begin        //当总线非忙,才可以操作I2C控制器
            iic_req  <= 1'b1;       //请求操作I2C控制器
            wr_data[7  :0] <= REG_DATA[23:16];  //器件地址   
            wr_data[15 :8] <= REG_DATA[15: 8];  //寄存器地址     
            wr_data[23:16] <= REG_DATA[7 : 0];  //寄存器数据
            TS_S      <= 2'd2; //下一个状态
        end    
        2:if(iic_busy)begin
             iic_req  <= 1'b0;  //重置 iic_req =0
             TS_S     <= 2'd3;  //下一个状态
        end
        3:if(!iic_busy)begin  //当总线非忙,才可以操作I2C控制器 
            reg_index<= reg_index + 1'b1;//寄存器索引加1
            TS_S    <= 2'd0;//回到初始状态
        end 
        endcase
   end
end
以下给出完整代码:
/*******************************uicfg7611***************************
--1.ADV7611芯片配置驱动程序
********************************************************************/
`timescale 1ns / 1ns

module uicfg7611#
(
parameter    CLK_DIV  = 16'd999
)
(
input  I_clk,  //系统时钟输入
input  I_rst_n,  //系统复位输入
output O_adv_scl, //I2C总线,SCL时钟
inout  IO_adv_sda, //I2C总线,SDA数据
output reg O_cfg_done //配置完成
);  

//内部计数器产生一个延迟复位
reg[7:0] rst_cnt =0;
always@(posedge I_clk or negedge I_rst_n)  
    if(I_rst_n == 1'b0) //复位初始化寄存器
        rst_cnt<= 8'd0; 
    else if(rst_cnt[7] == 1'b0)
       rst_cnt <= rst_cnt + 1'b1; 
    else 
       rst_cnt <= rst_cnt; 

reg  iic_req;//请求操作I2C控制器信号
wire ic_busy; //I2C控制器忙信号 
reg  [31:0] wr_data;     //写数据寄存器
reg  [1 :0] TS_S = 2'd0; //状态机寄存器
reg  [8 :0] reg_index;   //寄存索引
wire [23:0] REG_DATA;    //寄存器数据
wire [8 :0] REG_SIZE;    //寄存器数量

always@(posedge I_clk ) begin 
    if(rst_cnt[7] == 1'b0)begin //复位初始化寄存器
        reg_index<= 9'd0;
        iic_req  <= 1'b0;
        wr_data  <= 32'd0;
        O_cfg_done <= 1'b0;
        TS_S     <= 2'd0;    
    end
    else begin
        case(TS_S)
        0:if(reg_index == REG_SIZE) //如果配置完成
            O_cfg_done <= 1'b1;       //设置 O_cfg_done标准
          else if(O_cfg_done == 1'b0) //如果未配置完成
            TS_S <= 2'd1;           //下一个状态
        1:if(!iic_busy)begin        //当总线非忙,才可以操作I2C控制器
            iic_req  <= 1'b1;       //请求操作I2C控制器
            wr_data[7  :0] <= REG_DATA[23:16];  //器件地址   
            wr_data[15 :8] <= REG_DATA[15: 8];  //寄存器地址     
            wr_data[23:16] <= REG_DATA[7 : 0];  //寄存器数据
            TS_S      <= 2'd2; //下一个状态
        end    
        2:if(iic_busy)begin
             iic_req  <= 1'b0;  //重置 iic_req =0
             TS_S     <= 2'd3;  //下一个状态
        end
        3:if(!iic_busy)begin  //当总线非忙,才可以操作I2C控制器 
            reg_index<= reg_index + 1'b1;//寄存器索引加1
            TS_S    <= 2'd0;//回到初始状态
        end 
        endcase
   end
end

//例化I2C控制模块
uii2c#
(
.WMEN_LEN(4),     //最大支持一次写入4BYTE(包含器件地址)
.RMEN_LEN(1),     //最大支持一次读出1BYTE
.CLK_DIV(CLK_DIV) //100KHZ I2C总线时钟
)
uii2c_inst
(
.I_clk(I_clk),//系统时钟
.I_rstn(rst_cnt[7]),//系统复位
.O_iic_scl(O_adv_scl),//I2C SCL总线时钟
.IO_iic_sda(IO_adv_sda),//I2C SDA数据总线
.I_wr_data(wr_data),//写数据寄存器
.I_wr_cnt(8'd3),//需要写的数据BYTES
.O_rd_data(),   //读数据寄存器
.I_rd_cnt(8'd0),//需要读的数据BYTES
.I_iic_mode(1'b0),//读模式设置
.I_iic_req(iic_req),//I2C控制器请求
.O_iic_busy(iic_busy)//I2C控制器忙
);

//例化ADV7611的寄存器配置表
ui7611reg  ui7611reg_inst
(
.O_REG_SIZE(REG_SIZE),  //寄存器数量
.I_REG_INDEX(reg_index),//寄存索引
.O_REG_DATA(REG_DATA)   //寄存器数据
);  

endmodule

4.2 ui7611reg.v

/*******************************ui7611reg***************************
--1.ADV7611芯片配置寄存器配置表
*********************************************************************/
module ui7611reg
(
input      [8 :0]  I_REG_INDEX,
output reg [31:0]  O_REG_DATA,
output     [8 :0]  O_REG_SIZE  
);

assign  O_REG_SIZE = 9'd182;

//-----------------------------------------------------------------
/   Config Data REG   //    
always@(*)
case(I_REG_INDEX)
//write Data Index
    0   : O_REG_DATA    =   {8'h98,8'hF4, 8'h80};   //配置,CEC SLAVE ADDRESS
    1   : O_REG_DATA    =   {8'h98,8'hF5, 8'h7c};   //配置,INFOFRAME SLAVE ADDRESS
    2   : O_REG_DATA    =   {8'h98,8'hF8, 8'h4c};   //配置,DPLL SLAVE ADDRESS
    3   : O_REG_DATA    =   {8'h98,8'hF9, 8'h64};   //配置,KSV SLAVE ADDRESS
    4   : O_REG_DATA    =   {8'h98,8'hFA, 8'h6c};   //配置,EDID SLAVE ADDRESS
    5   : O_REG_DATA    =   {8'h98,8'hFB, 8'h68};   //配置,HDMI SLAVE ADDRESS
    6   : O_REG_DATA    =   {8'h98,8'hFD, 8'h44};   //配置,CP SLAVE ADDRESS
    7   : O_REG_DATA    =   {8'h98,8'h01, 8'h05};   //[3:0]寄存器的设置HDMI工作模式为HDMI-component mode,[6:4]设置分辨率60fps
    8   : O_REG_DATA    =   {8'h98,8'h00, 8'h13};   //设置视频输入输出set VID_STD input video HD1X1 output 1280x720
    9   : O_REG_DATA    =   {8'h98,8'h02, 8'hF7};   //[3]=0默认不转换,[1]=1RGB色彩空间,[7:4]=1111,使用默认色彩空间
    10  : O_REG_DATA  =     {8'h98,8'h03, 8'h40};   //OP_FORMAT_SEL=0X40 24bits 4:4:4 SDR MODE 设置SDR模式,P23~P0 输出
    11  : O_REG_DATA  =     {8'h98,8'h04, 8'h62};   //011 - P[23:16] V/R, P[15:8] Y/G, P[7:0] U/CrCb/B ; XTAL = 28.868 MHz   
    12  : O_REG_DATA    =   {8'h98,8'h05, 8'h28};   //OP_SWAP_CB_CR寄存器[0]=0,CrCb顺序按照OP_FORMAT_SET寄存器设置来
    13  : O_REG_DATA    =   {8'h98,8'h06, 8'ha7};   //INV_LLC_POL寄存器[0],不调整时钟数据输出相位,INV_HS_POL寄存器[1]HS极性调整,INV_VS_POL寄存器[2]极性调整,INV_F_POL寄存器[3],FIELD/DE极性调整
    14  : O_REG_DATA    =   {8'h98,8'h0b, 8'h44};   //Powers up CP and digital sections of HDMI block; Powers up XTAL buffer to the digital core 
    15  : O_REG_DATA    =   {8'h98,8'h0C, 8'h42};   //Chip is operational,Disables power save mode,Powers up the clock to the CP core,Powers up the pads of the digital output pins
    16  : O_REG_DATA    =   {8'h98,8'h15, 8'h80};   //Disable Tristate of Pins  
    17  : O_REG_DATA    =   {8'h98,8'h19, 8'h8a};   //LLC DLL phase  
    18  : O_REG_DATA    =   {8'h98,8'h33, 8'h40};   //LLC DLL enable
    19  : O_REG_DATA    =   {8'h98,8'h14, 8'h3f};   //
    20  : O_REG_DATA    =   {8'h44,8'hba, 8'h01};   //Set HDMI FreeRun when the TMDS clock is not detected on the selected HDMI port 
    21  : O_REG_DATA    =   {8'h44,8'h7c, 8'h01};   //  
    22  : O_REG_DATA    =   {8'h64,8'h40, 8'h81};   //Disable HDCP 1.1 features     
    23  : O_REG_DATA    =   {8'h68,8'h9b, 8'h03};   //ADI recommanded setting
    24  : O_REG_DATA    =   {8'h68,8'hc1, 8'h01};   //ADI recommanded setting
    25  : O_REG_DATA    =   {8'h68,8'hc2, 8'h01};   //ADI recommanded setting
    26  : O_REG_DATA    =   {8'h68,8'hc3, 8'h01};   //ADI recommanded setting
    27  : O_REG_DATA    =   {8'h68,8'hc4, 8'h01};   //ADI recommanded setting
    28  : O_REG_DATA    =   {8'h68,8'hc5, 8'h01};   //ADI recommanded setting
    29  : O_REG_DATA    =   {8'h68,8'hc6, 8'h01};   //ADI recommanded setting
    30  : O_REG_DATA    =   {8'h68,8'hc7, 8'h01};   //ADI recommanded setting
    31  : O_REG_DATA    =   {8'h68,8'hc8, 8'h01};   //ADI recommanded setting
    32  : O_REG_DATA    =   {8'h68,8'hc9, 8'h01};   //ADI recommanded settin g
    33  : O_REG_DATA    =   {8'h68,8'hca, 8'h01};   //ADI recommanded setting
    34  : O_REG_DATA    =   {8'h68,8'hcb, 8'h01};   //ADI recommanded setting
    35  : O_REG_DATA    =   {8'h68,8'hcc, 8'h01};   //ADI recommanded setting
    36  : O_REG_DATA    =   {8'h68,8'h00, 8'h00};   //Set HDMI input Port A
    37  : O_REG_DATA    =   {8'h68,8'h83, 8'hfe};   //Enable clock terminator for port A 
    38  : O_REG_DATA    =   {8'h68,8'h6f, 8'h08};   //ADI recommended setting
    39  : O_REG_DATA    =   {8'h68,8'h85, 8'h1f};   //ADI recommended setting
    40  : O_REG_DATA    =   {8'h68,8'h87, 8'h70};   //ADI recommended setting
    41  : O_REG_DATA    =   {8'h68,8'h8d, 8'h04};  //LF gain equalizer settings for dynamic mode range 1
    42  : O_REG_DATA    =   {8'h68,8'h8e, 8'h1e};  //HF gain equalizer settings for dynamic mode range 1 
    43  : O_REG_DATA    =   {8'h68,8'h1a, 8'h8a};   //unmute audio
    44  : O_REG_DATA    =   {8'h68,8'h57, 8'hda};   //ADI recommended setting
    45  : O_REG_DATA    =   {8'h68,8'h58, 8'h01};   //ADI recommended setting
    46  : O_REG_DATA    =   {8'h68,8'h75, 8'h10};   // DDC drive strength
    47  : O_REG_DATA    =   {8'h68,8'h6c ,8'ha3};   //enable manual HPA
    48  : O_REG_DATA    =   {8'h98,8'h20 ,8'h70};   //HPD low
    49  : O_REG_DATA    =   {8'h64,8'h74 ,8'h00};   //disable internal EDID 

//edid par
    50  : O_REG_DATA    =   {8'h6c,8'd0  , 8'h00};
    51  : O_REG_DATA    =   {8'h6c,8'd1  , 8'hFF};
    52  : O_REG_DATA    =   {8'h6c,8'd2  , 8'hFF};
    53  : O_REG_DATA    =   {8'h6c,8'd3  , 8'hFF};
    54  : O_REG_DATA    =   {8'h6c,8'd4  , 8'hFF};
    55  : O_REG_DATA    =   {8'h6c,8'd5  , 8'hFF};
    56  : O_REG_DATA    =   {8'h6c,8'd6  , 8'hFF};
    57  : O_REG_DATA    =   {8'h6c,8'd7  , 8'h00};
    58  : O_REG_DATA    =   {8'h6c,8'd8  , 8'h20};
    59  : O_REG_DATA    =   {8'h6c,8'd9  , 8'hA3};
    60  : O_REG_DATA    =   {8'h6c,8'd10 , 8'h29};
    61  : O_REG_DATA    =   {8'h6c,8'd11 , 8'h00};
    62  : O_REG_DATA    =   {8'h6c,8'd12 , 8'h01};
    63  : O_REG_DATA    =   {8'h6c,8'd13 , 8'h00};
    64  : O_REG_DATA    =   {8'h6c,8'd14 , 8'h00};
    65  : O_REG_DATA    =   {8'h6c,8'd15 , 8'h00};
    66  : O_REG_DATA    =   {8'h6c,8'd16 , 8'h23};
    67  : O_REG_DATA    =   {8'h6c,8'd17 , 8'h12};
    68  : O_REG_DATA    =   {8'h6c,8'd18 , 8'h01};
    69  : O_REG_DATA    =   {8'h6c,8'd19 , 8'h03};
    70  : O_REG_DATA    =   {8'h6c,8'd20 , 8'h80};
    71  : O_REG_DATA    =   {8'h6c,8'd21 , 8'h73};
    72  : O_REG_DATA    =   {8'h6c,8'd22 , 8'h41};
    73  : O_REG_DATA    =   {8'h6c,8'd23 , 8'h78};
    74  : O_REG_DATA    =   {8'h6c,8'd24 , 8'h0A};
    75  : O_REG_DATA    =   {8'h6c,8'd25 , 8'hF3};
    76  : O_REG_DATA    =   {8'h6c,8'd26 , 8'h30};
    77  : O_REG_DATA    =   {8'h6c,8'd27 , 8'hA7};
    78  : O_REG_DATA    =   {8'h6c,8'd28 , 8'h54};
    79  : O_REG_DATA    =   {8'h6c,8'd29 , 8'h42};
    80  : O_REG_DATA    =   {8'h6c,8'd30 , 8'hAA};
    81  : O_REG_DATA    =   {8'h6c,8'd31 , 8'h26};
    82  : O_REG_DATA    =   {8'h6c,8'd32 , 8'h0F};
    83  : O_REG_DATA    =   {8'h6c,8'd33 , 8'h50};
    84  : O_REG_DATA    =   {8'h6c,8'd34 , 8'h54};
    85  : O_REG_DATA    =   {8'h6c,8'd35 , 8'h25};
    86  : O_REG_DATA    =   {8'h6c,8'd36 , 8'hC8};
    87  : O_REG_DATA    =   {8'h6c,8'd37 , 8'h00};
    88  : O_REG_DATA    =   {8'h6c,8'd38 , 8'h61};
    89  : O_REG_DATA    =   {8'h6c,8'd39 , 8'h4F};
    90  : O_REG_DATA    =   {8'h6c,8'd40 , 8'h01};
    91  : O_REG_DATA    =   {8'h6c,8'd41 , 8'h01};
    92  : O_REG_DATA    =   {8'h6c,8'd42 , 8'h01};
    93  : O_REG_DATA    =   {8'h6c,8'd43 , 8'h01};
    94  : O_REG_DATA    =   {8'h6c,8'd44 , 8'h01};
    95  : O_REG_DATA    =   {8'h6c,8'd45 , 8'h01};
    96  : O_REG_DATA    =   {8'h6c,8'd46 , 8'h01};
    97  : O_REG_DATA    =   {8'h6c,8'd47 , 8'h01};
    98  : O_REG_DATA    =   {8'h6c,8'd48 , 8'h01};
    99  : O_REG_DATA    =   {8'h6c,8'd49 , 8'h01};
    100 : O_REG_DATA    =   {8'h6c,8'd50 , 8'h01};
    101 : O_REG_DATA    =   {8'h6c,8'd51 , 8'h01};
    102 : O_REG_DATA    =   {8'h6c,8'd52 , 8'h01};
    103 : O_REG_DATA    =   {8'h6c,8'd53 , 8'h01};
    104 : O_REG_DATA    =   {8'h6c,8'd54 , 8'h02};
    105 : O_REG_DATA    =   {8'h6c,8'd55 , 8'h3A};
    106 : O_REG_DATA    =   {8'h6c,8'd56 , 8'h80};
    107 : O_REG_DATA    =   {8'h6c,8'd57 , 8'h18};
    108 : O_REG_DATA    =   {8'h6c,8'd58 , 8'h71};
    109 : O_REG_DATA    =   {8'h6c,8'd59 , 8'h38};
    110 : O_REG_DATA    =   {8'h6c,8'd60 , 8'h2D};
    111 : O_REG_DATA    =   {8'h6c,8'd61 , 8'h40};
    112 : O_REG_DATA    =   {8'h6c,8'd62 , 8'h58};
    113 : O_REG_DATA    =   {8'h6c,8'd63 , 8'h2C};
    114 : O_REG_DATA    =   {8'h6c,8'd64 , 8'h45};
    115 : O_REG_DATA    =   {8'h6c,8'd65 , 8'h00};
    116 : O_REG_DATA    =   {8'h6c,8'd66 , 8'h80};
    117 : O_REG_DATA    =   {8'h6c,8'd67 , 8'h88};
    118 : O_REG_DATA    =   {8'h6c,8'd68 , 8'h42};
    119 : O_REG_DATA    =   {8'h6c,8'd69 , 8'h00};
    120 : O_REG_DATA    =   {8'h6c,8'd70 , 8'h00};
    121 : O_REG_DATA    =   {8'h6c,8'd71 , 8'h1E};
    122 : O_REG_DATA    =   {8'h6c,8'd72 , 8'h8C};
    123 : O_REG_DATA    =   {8'h6c,8'd73 , 8'h0A};
    124 : O_REG_DATA    =   {8'h6c,8'd74 , 8'hD0};
    125 : O_REG_DATA    =   {8'h6c,8'd75 , 8'h8A};
    126 : O_REG_DATA    =   {8'h6c,8'd76 , 8'h20};
    127 : O_REG_DATA    =   {8'h6c,8'd77 , 8'hE0};
    128 : O_REG_DATA    =   {8'h6c,8'd78 , 8'h2D};
    129 : O_REG_DATA    =   {8'h6c,8'd79 , 8'h10};
    130 : O_REG_DATA    =   {8'h6c,8'd80 , 8'h10};
    131 : O_REG_DATA    =   {8'h6c,8'd81 , 8'h3E};
    132 : O_REG_DATA    =   {8'h6c,8'd82 , 8'h96};
    133 : O_REG_DATA    =   {8'h6c,8'd83 , 8'h00};
    134 : O_REG_DATA    =   {8'h6c,8'd84 , 8'h80};
    135 : O_REG_DATA    =   {8'h6c,8'd85 , 8'h88};
    136 : O_REG_DATA    =   {8'h6c,8'd86 , 8'h42};
    137 : O_REG_DATA    =   {8'h6c,8'd87 , 8'h00};
    138 : O_REG_DATA    =   {8'h6c,8'd88 , 8'h00};
    139 : O_REG_DATA    =   {8'h6c,8'd89 , 8'h18};
    140 : O_REG_DATA    =   {8'h6c,8'd90 , 8'h00};
    141 : O_REG_DATA    =   {8'h6c,8'd91 , 8'h00};
    142 : O_REG_DATA    =   {8'h6c,8'd92 , 8'h00};
    143 : O_REG_DATA    =   {8'h6c,8'd93 , 8'hFC};
    144 : O_REG_DATA    =   {8'h6c,8'd94 , 8'h00};
    145 : O_REG_DATA    =   {8'h6c,8'd95 , 8'h48};
    146 : O_REG_DATA    =   {8'h6c,8'd96 , 8'h44};
    147 : O_REG_DATA    =   {8'h6c,8'd97 , 8'h4D};
    148 : O_REG_DATA    =   {8'h6c,8'd98 , 8'h49};
    149 : O_REG_DATA    =   {8'h6c,8'd99 , 8'h20};
    150 : O_REG_DATA    =   {8'h6c,8'd100, 8'h20};
    151 : O_REG_DATA    =   {8'h6c,8'd101, 8'h20};
    152 : O_REG_DATA    =   {8'h6c,8'd102, 8'h20};
    153 : O_REG_DATA    =   {8'h6c,8'd103, 8'h0A};
    154 : O_REG_DATA    =   {8'h6c,8'd104, 8'h20};
    155 : O_REG_DATA    =   {8'h6c,8'd105, 8'h20};
    156 : O_REG_DATA    =   {8'h6c,8'd106, 8'h20};
    157 : O_REG_DATA    =   {8'h6c,8'd107, 8'h20};
    158 : O_REG_DATA    =   {8'h6c,8'd108, 8'h00};
    159 : O_REG_DATA    =   {8'h6c,8'd109, 8'h00};
    160 : O_REG_DATA    =   {8'h6c,8'd110, 8'h00};
    161 : O_REG_DATA    =   {8'h6c,8'd111, 8'hFD};
    162 : O_REG_DATA    =   {8'h6c,8'd112, 8'h00};
    163 : O_REG_DATA    =   {8'h6c,8'd113, 8'h32};
    164 : O_REG_DATA    =   {8'h6c,8'd114, 8'h55};
    165 : O_REG_DATA    =   {8'h6c,8'd115, 8'h1F};
    166 : O_REG_DATA    =   {8'h6c,8'd116, 8'h45};
    167 : O_REG_DATA    =   {8'h6c,8'd117, 8'h0F};
    168 : O_REG_DATA    =   {8'h6c,8'd118, 8'h00};
    169 : O_REG_DATA    =   {8'h6c,8'd119, 8'h0A};
    170 : O_REG_DATA    =   {8'h6c,8'd120, 8'h20};
    171 : O_REG_DATA    =   {8'h6c,8'd121, 8'h20};
    172 : O_REG_DATA    =   {8'h6c,8'd122, 8'h20};
    173 : O_REG_DATA    =   {8'h6c,8'd123, 8'h20};
    174 : O_REG_DATA    =   {8'h6c,8'd124, 8'h20};
    175 : O_REG_DATA    =   {8'h6c,8'd125, 8'h20};
    176 : O_REG_DATA    =   {8'h6c,8'd126, 8'h01};
    177 : O_REG_DATA    =   {8'h6c,8'd127, 8'h24};
    178 : O_REG_DATA    =   {8'h64,8'h74 , 8'h01};// enable internal EDID
    179 : O_REG_DATA    =   {8'h98,8'h20 , 8'hf0};// HPD high
    180 : O_REG_DATA    =   {8'h68,8'h6c , 8'ha2};// disable manual HPA 
    181 : O_REG_DATA    =   {8'h98,8'hf4 , 8'h00};
    default:O_REG_DATA =0;
endcase

endmodule

5 hdmi_in_test.v

在这个文件中,首先对视频数据做了一次寄存操作,再调用了HDMI输出IP,把HDMI输入的视频信号(格式为RGB888)给HDMI输出IP。当然这个IP里面也调用了ADV7611寄存器配置的代码。如果读者对于HDMI输出IP的使用还有疑问可以前前面一篇文章的内容。

/*************HDMI 视频采集测试*************
--通过配置ADV7611工作于RGB模式,利用HDMI 输出IP 环路输出视频
*********************************************************************/
`timescale 1ns / 1ns //仿真时间刻度/精度

module hdmi_in_test
(
input  I_sysclk_p,
input  I_sysclk_n,
//HDMI ADV7611视频输入
output O_adv7611_rst,        //ADV7611  复位
inout  IO_adv7611_sda,        //ADV7611  I2C 数据总线
output O_adv7611_scl,        //ADV7611  I2C 地址总线
input  I_adv7611_hs,       //ADV7611  I2C HS同步信号
input  I_adv7611_vs,       //ADV7611  I2C VS同步信号
input  I_adv7611_de,       //ADV7611  I2C de数据有效信号
input  I_adv7611_pclk,     //ADV7611  时钟输入
input  [23:0]I_adv7611_rgb,//ADV7611  数据输入

//HDMI输出
output O_hdmi_tx_clk_p,         //HDMI 时钟差分信号P端
output O_hdmi_tx_clk_n,         //HDMI 时钟差分信号N端
output [2:0]O_hdmi_tx_p,     //HDMI 数据差分信号P端
output [2:0]O_hdmi_tx_n,     //HDMI 数据差分信号N端
output wire O_card_power_en

);
assign O_card_power_en = 1'b1; //子卡上电
assign O_adv7611_rst = 1'b1;      //ADV7611 复位
wire I_clk;
IBUFGDS CLK_U(
.I(I_sysclk_p),
.IB(I_sysclk_n),
.O(I_clk)
);
wire cfg_done; //ADV7611配置完成信号
wire locked ; // PLL lock 信号
wire pclkx1,pclkx5; //时钟信号

//MMCM/PLL时钟管理IP 输出 pclkx1和pclkx5以及locked信号
clk_wiz_0 clk_wiz_inst(.clk_out1(pclkx1),.clk_out2(pclkx5),.locked(locked), .clk_in1(I_adv7611_pclk));

//例化HDMI输出IP,把TPG产生的测试图像经过HDMI输出
uihdmitx #
(
.FAMILY("7FAMILY")  //选择芯片所支持的系列"7FAMILY" “UFAMILY”     
)
uihdmitx_inst
(
.I_rstn(cfg_done&&locked),//复位
.I_hs(I_adv7611_hs),      //hs信号
.I_vs(I_adv7611_vs),      //vs信号
.I_de(I_adv7611_de),     //de信号
.I_rgb(I_adv7611_rgb),    //RGB数据
.I_pclkx1(pclkx1),        //像素时钟
.I_pclkx2_5(1'b0),        //2.5倍像素时钟,只有UFAMILY需要
.I_pclkx5(pclkx5),        //5倍像素时钟
.O_hdmi_tx_clk_p(O_hdmi_tx_clk_p),//HDMI时钟输出P端
.O_hdmi_tx_clk_n(O_hdmi_tx_clk_n),//HDMI时钟输出N端
.O_hdmi_tx_p(O_hdmi_tx_p),     //HDMI输出数据P端
.O_hdmi_tx_n(O_hdmi_tx_n)      //HDMI输出数据N端
);

//例化ADV7611 驱动
uicfg7611#
(
.CLK_DIV(100_000_000/50_000 -1 )//设置I2C时钟50K,时钟过高可能导致配置失败
)
uicfg7611_inst
(
.I_clk(I_clk),//系统时输入
.I_rst_n(1'b1),    //复位
.O_adv_scl(O_adv7611_scl),//ADV7611  I2C 数据总线
.IO_adv_sda(IO_adv7611_sda),//ADV7611  I2C 地址总线
.O_cfg_done(cfg_done)
);

endmodule

6硬件接线

(该教程为通用型教程,教程中仅展示一款示例开发板的连接方式,具体连接方式以所购买的开发板型号以及结合配套代码管脚约束为准。)

本实验注意采我们的cep跳线帽跳线1.8V,子卡采用1.8V的HDMI7611。请确保下载器和开发板已经正确连接,另外需要把核心板上的2P模式开关设置到JTAG模式,即ON ON,并且开发板已经上电。(注意JTAG端子不支持热插拔,而USB接口支持,所以在不通电的情况下接通好JTAG后,再插入USB到电脑,之后再上电,以免造成JTAG IO损坏)

1、开发板HDMI IN 接口连接输入源:测试使用PC机做输入源,HDMI线连接子卡HDMI IN 接口。

2、开发板HDMI OUT接口连接输出源:测试使用显示器做输出源,HDMI线连接底板HDMI OUT 接口。

说明:测试图片中的开发板不一定是本课程配套的开发板,但是具有样例代表性。

7测试结果

说明:测试图片中的开发板不一定是本课程配套的开发板,但是具有样例代表性。

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

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

相关文章

软考(计算机技术与软件专业技术资格(水平)考试)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

《JavaEE进阶》----11.<SpringIOCDI【Spring容器+IOC详解+DI介绍】>

本篇博客会详细讲解什么是Spring。 SpringIOC SpringID 五个类注解&#xff1a;Controller、Service、Repository、Component、Configuration 一个方法注解&#xff1a;Bean 什么是Spring IOC容器 Spring 是包含众多工具的IOC容器。能装东西的容器。 1.容器 如我们之前学的 Tom…

高效传输秘籍,揭秘Rsync和SCP的优劣,助你做出明智选择!

在日常的运维工作中&#xff0c;文件传输任务频繁出现&#xff0c;而选择合适的工具能显著提高工作效率。Rsync 和 SCP 是两款常见的文件传输工具&#xff0c;但它们各具优缺点&#xff0c;适合不同的场景。本文将通过深入分析这两款工具的特性、使用场景和性能&#xff0c;帮助…

Django+Vue3前后端分离学习(一)(项目开始时settings.py里的设置)

一、创建django项目 二、修改settings.py里的配置&#xff1a; 1、修改语言和时区&#xff1a; # 语言编码 LANGUAGE_CODE zh-hansTIME_ZONE UTCUSE_I18N True# 不用时区 USE_TZ False 2、配置数据库&#xff1a; DATABASES {default: {ENGINE: django.db.backends.m…

如何启动网络安全计划:首先要做的事情

目录 数据分类&#xff1a;网络安全的基石 为什么它很重要&#xff1f; 如何对数据进行分类&#xff1f; 风险分析 什么是风险分析&#xff1f; 如何进行风险分析&#xff1f; 业务影响分析 (BIA) BIA 的用途是什么&#xff1f; BIA 是如何进行的&#xff1f; 安全解…

文法—语法推导树例题

答案:C 解析&#xff1a; S推出A0&#xff0c;A0推出1&#xff0c;可以推出字符串01 S推出B1&#xff0c;B1推出0&#xff0c;可以推出字符串10 选项A&#xff0c;所有由0构成的字符串&#xff0c;不正确 选项B&#xff0c;所有由1构成的字符串。不正确 选项C&#xff0c…

探索Invoke:Python自动化任务的瑞士军刀

文章目录 探索Invoke&#xff1a;Python自动化任务的瑞士军刀背景&#xff1a;为何选择Invoke&#xff1f;invoke是什么&#xff1f;如何安装invoke&#xff1f;简单的invoke库函数使用方法场景应用&#xff1a;invoke在实际项目中的使用场景一&#xff1a;自动化测试场景二&am…

DAQmx Connect Terminals 路由的实际应用与注意事项

DAQmx Connect Terminals VI 是 NI 数据采集 (DAQ) 系统中的关键功能&#xff0c;用于在物理或虚拟终端之间建立信号路由。它允许用户自定义信号的硬件连接路径&#xff0c;以满足复杂的测试和测量需求。本文将详细介绍如何使用该功能&#xff0c;实际应用中的例子&#xff0c;…

UE5引擎工具链知识点

当我们提到“引擎工具链的开发”时&#xff0c;通常指的是为游戏开发或其他类型的软件开发创建一系列工具和技术栈的过程。这包括但不限于游戏引擎本身&#xff08;如Unity或Unreal Engine&#xff09;&#xff0c;以及围绕这些引擎构建的各种工具和服务&#xff0c;比如用于构…

基于SpringBoot+Vue+MySQL的宿舍维修管理系统

系统展示 前台界面 管理员界面 维修员界面 学生界面 系统背景 在当今高校后勤管理的日益精细化与智能化背景下&#xff0c;宿舍维修管理系统作为提升校园生活品质、优化资源配置的关键环节&#xff0c;其重要性日益凸显。随着学生规模的扩大及住宿条件的不断提升&#xff0c;宿…

Redis 篇-深入了解基于 Redis 实现分布式锁(解决多线程安全问题、锁误删问题和确保锁的原子性问题)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 分布式锁概述 1.1 Redis 分布式锁实现思路 1.2 实现基本的分布式锁 2.0 Redis 分布式锁误删问题 2.1 解决 Redis 分布式锁误删问题 3.0 Redis 分布式锁原子性问题…

高级法医视频分析技术 2024

高级法医视频分析技术 2024 如今&#xff0c;法医视频分析是数字取证的重要组成部分 &#xff0c;因为它可以帮助特工了解视频证据很重要的案件的重要信息。到 2024 年&#xff0c;该领域使用的工具和方法将以前所未有的速度发生变化。在这个领域工作的人需要了解这些变化。在本…

ctfshow-nodejs

什么是nodejs Node.js 是一个基于 Chrome V8 引擎的 Javascript 运行环境。可以说nodejs是一个运行环境&#xff0c;或者说是一个 JS 语言解释器 Nodejs 是基于 Chrome 的 V8 引擎开发的一个 C 程序&#xff0c;目的是提供一个 JS 的运行环境。最早 Nodejs 主要是安装在服务器…

线性代数 第六讲 特征值和特征向量_相似对角化_实对称矩阵_重点题型总结详细解析

文章目录 1.特征值和特征向量1.1 特征值和特征向量的定义1.2 特征值和特征向量的求法1.3 特征值特征向量的主要结论 2.相似2.1 相似的定义2.2 相似的性质2.3 相似的结论 3.相似对角化4.实对称矩阵4.1 实对称矩阵的基本性质4.2 施密特正交化 5.重难点题型总结5.1 判断矩阵能否相…

Flutter集成Firebase中的 A/B Testing

前提 完成Flutter集成Firebase中的远程配置流程 A/B Test的使用流程 我们先通过远程配置设置变量&#xff0c;应用程序根据变量值展示不同的界面创建一个A/B Test实验&#xff0c;在实验中创建满足条件的用户才能加入到这个实验中&#xff0c;并且在A/B 实验中修改远程配置变…

【网络安全】服务基础第二阶段——第二节:Linux系统管理基础----Linux统计,高阶命令

目录 一、Linux高阶命令 1.1 管道符的基本原理 1.2 重定向 1.2.1 输出重定向 1.2.2 输入重定向 1.2.3 wc命令基本用法 1.3 别名 1.3.1 which命令基本语法 1.3.2 alias命令基本语法 1.4 压缩归档tar 1.4.1 第一种&#xff1a;gzip压缩 1.4.2 第二种&#xff1a;bzip…

多款式随身WiFi如何挑选,USB随身WiFi、无线电池随身WiFi、充电宝随身WiFi哪个好?优缺点分析!

市面上的随身WiFi款式多样琳琅满目&#xff0c;最具代表性的就是USB插电款、无线款和充电宝款。今天就来用一篇文章分析一下这三种款式的优缺点。 USB插电款 优点&#xff1a;便宜&#xff0c;无需充电&#xff0c;在有电源的地方可以随时随地插电使用&#xff0c;比如中兴的U…

交换两个变量数值的3种方法

前言&#xff1a;交换两个数值可不是"a b&#xff0c;b a"。这样做的话&#xff0c;a先等于了b的值&#xff1b;当“b a”后&#xff0c;因为此时a已经等于b的值了&#xff0c;这个语句就相当于执行了b b。最终的数值关系就成了a b&#xff0c;b b。 下面教给大…

综合DHCP、ACL、NAT、Telnet和PPPoE进行网络设计练习

描述&#xff1a;企业内网和运营商网络如上图所示。 公网IP段&#xff1a;12.1.1.0/24。 内网IP段&#xff1a;192.168.1.0/24。 公网口PPPOE 拨号采用CHAP认证&#xff0c;用户名:admin 密码:Admin123 财务PC 配置静态IP&#xff1a;192.168.1.8 R1使用模拟器中的AR201型…

重生奇迹MU老大哥剑士职业宝刀未老

重生奇迹MU中&#xff0c;老大哥剑士职业一直以来备受玩家们的喜爱。这个职业不仅拥有强大的攻击力、防御力和战斗技巧&#xff0c;而且还能够通过使用各种宝刀来增强自身的战斗能力。即便经过了多年的沉淀&#xff0c;老大哥剑士依然是一名宝刀未老的男人&#xff0c;仍然能够…