基于FPGA实现正弦插值算法
1、正弦插值的算法分析
1.1 信号在时域与频域的映射关系
在进行正弦算法分析之前,我们回顾一下《数字信号处理》课程中,对于信号在时域与频域之间的映射关系,如下图。
对于上图中的原始信号x(t),使用ADC对信号进行采样,即实现了时域信号的离散化,得到x[k]。根据时域与频域之间的映射关系:时域的离散化对应着频域的周期化,即x[k]的频域响应为。
那么离散化的x[k]如何还原为原来的x(t)呢?时域上分析较为复杂,我们可以从频域上进行分析,即如何将频域响应还原成X(jw)。这样就比较直观了,只需要截取
一个周期的信号,就可以还原成X(jw),示例如下图。
1.2 sinc函数
上面用到的窗函数,实际上是一个理想的低通滤波器,其时域形态是什么样子的呢?如下图。
其时域形态公式: ,sinc函数在频域上是一个矩形的方窗,如下图。
1.3 使用sinc函数实现正弦插值的算法分析
综上所述,对于我们可以使用sinc函数实现离散信号还原为连续信号,即使用sinc函数实现离散信号的无限插值。
而频域的乘积对应着时域的卷积,因此我们可以将离散的采样信号与sinc函数进行卷积运算,从而获得插值后的信号。
其中,y(n)为插值后信号;x(n)为待插值的离散信号;h(n)为sinc函数,也称为插值核或者插值因子。
假设有一个离散信号x(n),含有8个离散点,x(n)={-10,0,10,0,-10,0,10,0};如下图:
我们使用前后共计8个原始采样点,来求插值点x(0.5)的数值。套用上面描述的公式,即x(0.5)=x(-3)h(0.5-(-3)) + x(-2)h(0.5-(-2)) + x(-1)h(0.5-(-1)) + x(0)h(0.5-(0)) + x(1)h(0.5-(1)) + x(2)h(0.5-(2)) + x(3)h(0.5-(3)) =-6.3056,即求得插值点的数值。
根据这种思想,我们可以无限的求得每个插值点的数值。那么如何在工程也能够中使用sinc函数实现信号的插值,是我们接下来要讲述的。
2、使用matlab计算插值核
在使用FPGA实现插值算法时,由于sinc函数的计算实现起来比较消耗硬件资源,所以一般预先计算好插值核存放在ROM或者寄存器中,直接进行调用。
假设我们要使用前后8个点计算插值,插值倍数为10,那么使用matlab计算插值核的代码如下:
interp_mul = 10; %插值倍数为10
orig_point_num = 8;%原始点数8个coe_group = zeros(interp_mul,orig_point_num); %定义系数组
for group = 1:1:interp_mul %计算interp_mul组系数for Hn = 1:1:orig_point_num %计算每组系数的orig_point_num个加权值if(group == 1)if(Hn==4)coe_group(group,Hn) = 1; %原始点保持数据不变[0,0,0,1,0,0,0,0]elsecoe_group(group,Hn) = 0; %原始点保持数据不变[0,0,0,1,0,0,0,0]endelsecoe_group(group,Hn) = sinc(4- Hn + 0.1*(group-1));%找规律映射endend
end
运行结果保存在coe_group数组中,结果如下:
上述算法计算得到的插值核为小数,而FPGA计算小数运算时,需要现将数值左移相应位数进行放大,方便进行计算,输出结果时,截取高bit即可。由于后续FPGA实现卷积和时使用18bits的插值核进行运算,因此实际工程中的matlab代码如下:
interp_mul = 10; %插值倍数为10
orig_point_num = 8;%原始点数8个coe_group = zeros(interp_mul,orig_point_num); %定义系数组
for group = 1:1:interp_mul %计算interp_mul组系数for Hn = 1:1:orig_point_num %计算每组系数的orig_point_num个加权值if(group == 1)if(Hn==4)coe_group(group,Hn) = 1; %原始点保持数据不变[0,0,0,1,0,0,0,0]elsecoe_group(group,Hn) = 0; %原始点保持数据不变[0,0,0,1,0,0,0,0]endelsecoe_group(group,Hn) = sinc(4- Hn + 0.1*(group-1)) *2^17;%找规律映射,小数放大2^17倍endend
end
结果如下:
3、使用FPGA实现离散采样点的插值
本文中仅使用一个测试程序,说明FPGA实现插值的原理,结构相对简单,架构图如下:
离散采样RAM模块代码如下:
module disc_samp_gen(input clk,input disc_rd,//读待插值数据标志output [7:0] disc_samp //离散采样点输出 有符号数据);
reg [1:0]addra=0;always@(posedge clk)
beginif(disc_rd)addra <= addra + 1'b1;
endDataSrc_ROM DataSrc_ROM (.clka(clk), // input wire clka.addra(addra), // input wire [1 : 0] addra.douta(disc_samp) // output wire [7 : 0] douta
);endmodule
插值处理模块,主要通过乘法器实现卷积和,如下:
module sinc_process(input clk,input sinc_en,//插值使能标志input [7:0]disc_samp,//待插值数据,有符号数output disc_rd,//读取插值数据标志output sinc_valid,//插值数据有效标志output [7:0]sinc_data//插值后数据);
//插值倍数10,使用8个离散采样点进行插值处理
第0组插值核
//localparam [17:0] group0_coe[7:0] = {18'h0,18'h0,18'h0,18'h0,
// 18'h1FFFF,18'h0,18'h0,18'h0};//临时粗略将18'h1FFFF视为1
第1组插值核
//localparam [17:0] group1_coe[7:0] = {18'h3F317,18'h0115D,18'h3E57F,18'h037F5,
// 18'h1F79E,18'h3D238,18'h017FB,18'h3EFC2};
第2组插值核
//localparam [17:0] group2_coe[7:0] = {18'h3E6CB,18'h02236,18'h3CAC8,18'h077BE,
// 18'h1DEF8,18'h3B02C,18'h02B8A,18'h3E211};
第3组插值核
//localparam [17:0] group3_coe[7:0] = {18'h3DC5E,18'h030D5,18'h3B272,18'h0BC5B,
// 18'h1B77F,18'h39A94,18'h03953,18'h3D80C};
第4组插值核
//localparam [17:0] group4_coe[7:0] = {18'h3D4F2,18'h03B9D,18'h39F21,18'h10254,
// 18'h1837E,18'h3914A,18'h04095,18'h3D26A};
第5组插值核
//localparam [17:0] group5_coe[7:0] = {18'h3D170,18'h04130,18'h3935A,18'h145F3,
// 18'h145F3,18'h3935A,18'h04130,18'h3D170};
第6组插值核
//localparam [17:0] group6_coe[7:0] = {18'h3D26A,18'h04095,18'h3914A,18'h1837E,
// 18'h10254,18'h39F21,18'h03B9D,18'h3D4F2};
第7组插值核
//localparam [17:0] group7_coe[7:0] = {18'h3D80C,18'h03953,18'h39A94,18'h1B77F,
// 18'h0BC5B,18'h3B272,18'h030D5,18'h3DC5E};
第8组插值核
//localparam [17:0] group8_coe[7:0] = {18'h3E211,18'h02B8A,18'h3B02C,18'h1DEF8,
// 18'h077BE,18'h3CAC8,18'h02236,18'h3E6CB};
第9组插值核
//localparam [17:0] group9_coe[7:0] = {18'h3EFC2,18'h017FB,18'h3D238,18'h1F79E,
// 18'h037F5,18'h3E57F,18'h0115D,18'h3F317};//第0组插值核
localparam [17:0] group0_coe[7:0] = {18'h0,18'h0,18'h0,18'h1FFFF,18'h0,18'h0,18'h0,18'h0};//临时粗略将18'h1FFFF视为1
//第1组插值核
localparam [17:0] group1_coe[7:0] = {18'h3EFC2,18'h017FB,18'h3D238,18'h1F79E,18'h037F5,18'h3E57F,18'h0115D,18'h3F317};
//第2组插值核
localparam [17:0] group2_coe[7:0] = {18'h3E211,18'h02B8A,18'h3B02C,18'h1DEF8,18'h077BE,18'h3CAC8,18'h02236,18'h3E6CB};
//第3组插值核
localparam [17:0] group3_coe[7:0] = {18'h3D80C,18'h03953,18'h39A94,18'h1B77F,18'h0BC5B,18'h3B272,18'h030D5,18'h3DC5E};
//第4组插值核
localparam [17:0] group4_coe[7:0] = {18'h3D26A,18'h04095,18'h3914A,18'h1837E,18'h10254,18'h39F21,18'h03B9D,18'h3D4F2};
//第5组插值核
localparam [17:0] group5_coe[7:0] = {18'h3D170,18'h04130,18'h3935A,18'h145F3,18'h145F3,18'h3935A,18'h04130,18'h3D170};
//第6组插值核
localparam [17:0] group6_coe[7:0] = {18'h3D4F2,18'h03B9D,18'h39F21,18'h10254,18'h1837E,18'h3914A,18'h04095,18'h3D26A};
//第7组插值核
localparam [17:0] group7_coe[7:0] = {18'h3DC5E,18'h030D5,18'h3B272,18'h0BC5B,18'h1B77F,18'h39A94,18'h03953,18'h3D80C};
//第8组插值核
localparam [17:0] group8_coe[7:0] = {18'h3E6CB,18'h02236,18'h3CAC8,18'h077BE,18'h1DEF8,18'h3B02C,18'h02B8A,18'h3E211};
//第9组插值核
localparam [17:0] group9_coe[7:0] = {18'h3F317,18'h0115D,18'h3E57F,18'h037F5,18'h1F79E,18'h3D238,18'h017FB,18'h3EFC2};reg [17:0] sinc_coe [7:0];//对应插值点使用的插值核
reg [3:0] sinc_cnt = 0;//插值计数,0时为原始点,1~9为插值点,其余数值保留
reg [7:0] samp_data [7:0];//每次从RAM读取数据时进行锁存更新//8个乘法结果
reg [25:0] mult_data[7:0];assign disc_rd = (sinc_cnt == 4'd8) ? 1'b1:1'b0; //插值第8个点时,读取新的数据//插值倍数10,插值点计数
always@(posedge clk)
beginif(sinc_en == 1'b1) beginif(sinc_cnt == 4'd9) sinc_cnt <= 4'd0;elsesinc_cnt <= sinc_cnt + 1;endelsesinc_cnt <= 4'd0;
end
//原始点锁存
always@(posedge clk)
beginif(sinc_en == 1'b1 && sinc_cnt == 4'd0) begin //插值使能samp_data[0] <= disc_samp;//新输入的点samp_data[1] <= samp_data[0];samp_data[2] <= samp_data[1];samp_data[3] <= samp_data[2];samp_data[4] <= samp_data[3];samp_data[5] <= samp_data[4];samp_data[6] <= samp_data[5];samp_data[7] <= samp_data[6];end
end//插值核系数选择
always@(posedge clk)
begincase(sinc_cnt)4'd0:sinc_coe <= group0_coe;//原始点系数4'd1:sinc_coe <= group1_coe;//第1个插值点系数4'd2:sinc_coe <= group2_coe;//第2个插值点系数4'd3:sinc_coe <= group3_coe;//第3个插值点系数4'd4:sinc_coe <= group4_coe;//第4个插值点系数4'd5:sinc_coe <= group5_coe;//第5个插值点系数4'd6:sinc_coe <= group6_coe;//第6个插值点系数4'd7:sinc_coe <= group7_coe;//第7个插值点系数4'd8:sinc_coe <= group8_coe;//第8个插值点系数4'd9:sinc_coe <= group9_coe;//第9个插值点系数default:;endcase
end//乘法器0
mult_gen mult_gen_0 (.CLK(clk), // input wire CLK.A(samp_data[0]), // input wire [7 : 0] A.B(sinc_coe[0]), // input wire [17 : 0] B.P(mult_data[0]) // output wire [25 : 0] P
);//乘法器1
mult_gen mult_gen_1 (.CLK(clk), // input wire CLK.A(samp_data[1]), // input wire [7 : 0] A.B(sinc_coe[1]), // input wire [17 : 0] B.P(mult_data[1]) // output wire [25 : 0] P
);//乘法器2
mult_gen mult_gen_2 (.CLK(clk), // input wire CLK.A(samp_data[2]), // input wire [7 : 0] A.B(sinc_coe[2]), // input wire [17 : 0] B.P(mult_data[2]) // output wire [25 : 0] P
);//乘法器3
mult_gen mult_gen_3 (.CLK(clk), // input wire CLK.A(samp_data[3]), // input wire [7 : 0] A.B(sinc_coe[3]), // input wire [17 : 0] B.P(mult_data[3]) // output wire [25 : 0] P
);//乘法器4
mult_gen mult_gen_4 (.CLK(clk), // input wire CLK.A(samp_data[4]), // input wire [7 : 0] A.B(sinc_coe[4]), // input wire [17 : 0] B.P(mult_data[4]) // output wire [25 : 0] P
);//乘法器5
mult_gen mult_gen_5 (.CLK(clk), // input wire CLK.A(samp_data[5]), // input wire [7 : 0] A.B(sinc_coe[5]), // input wire [17 : 0] B.P(mult_data[5]) // output wire [25 : 0] P
);//乘法器6
mult_gen mult_gen_6 (.CLK(clk), // input wire CLK.A(samp_data[6]), // input wire [7 : 0] A.B(sinc_coe[6]), // input wire [17 : 0] B.P(mult_data[6]) // output wire [25 : 0] P
);//乘法器7
mult_gen mult_gen_7 (.CLK(clk), // input wire CLK.A(samp_data[7]), // input wire [7 : 0] A.B(sinc_coe[7]), // input wire [17 : 0] B.P(mult_data[7]) // output wire [25 : 0] P
);//使用加法器实现有符号数相加//二点相加
wire [25:0] add2_0;
wire [25:0] add2_1;
wire [25:0] add2_2;
wire [25:0] add2_3;
adder2 adder2_inst0 (.A(mult_data[0]), // input wire [25 : 0] A.B(mult_data[1]), // input wire [25 : 0] B.CLK(clk), // input wire CLK.S(add2_0) // output wire [26 : 0] S
);adder2 adder2_inst1 (.A(mult_data[2]), // input wire [25 : 0] A.B(mult_data[3]), // input wire [25 : 0] B.CLK(clk), // input wire CLK.S(add2_1) // output wire [26 : 0] S
);adder2 adder2_inst2 (.A(mult_data[4]), // input wire [25 : 0] A.B(mult_data[5]), // input wire [25 : 0] B.CLK(clk), // input wire CLK.S(add2_2) // output wire [26 : 0] S
);adder2 adder2_inst3 (.A(mult_data[5]), // input wire [25 : 0] A.B(mult_data[6]), // input wire [25 : 0] B.CLK(clk), // input wire CLK.S(add2_3) // output wire [26 : 0] S
);//四点相加
reg [25:0] add4_0;
reg [25:0] add4_1;
adder4 adder4_inst0 (.A(add2_0), // input wire [26 : 0] A.B(add2_1), // input wire [26 : 0] B.CLK(clk), // input wire CLK.S(add4_0) // output wire [27 : 0] S
);adder4 adder4_inst1 (.A(add2_2), // input wire [26 : 0] A.B(add2_3), // input wire [26 : 0] B.CLK(clk), // input wire CLK.S(add4_1) // output wire [27 : 0] S
);//八点相加
wire [25:0] add8;
adder8 adder8 (.A(add4_0), // input wire [26 : 0] A.B(add4_1), // input wire [26 : 0] B.CLK(clk), // input wire CLK.S(add8) // output wire [27 : 0] S
);assign sinc_valid = 1'b1;
assign sinc_data = add8[25:18];
endmodule
编写testbench,对插值模块进行仿真验证,testbench代码如下:
module testbench();
reg clk = 0; //100M时钟always
begin# 5clk <= ~clk;
endwire disc_rd;//采样点有效标志
wire [7:0] disc_samp; //离散采样点输出
disc_samp_gen disc_samp_gen(.clk(clk),.disc_rd(disc_rd),//采样点有效标志.disc_samp(disc_samp)//离散采样点输出);sinc_process sinc_process(.clk(clk),.sinc_en(1'b1),.disc_rd(disc_rd),//采样点有效标志.disc_samp(disc_samp),//离散采样点输出.sinc_valid(),//插值数据有效标志.sinc_data()//插值后数据);endmodule
仿真验证结果如下:
可以看到,图中黄色部分为原始采样点的直线连接波形,紫色部分为正弦插值后的波形。正弦插值仿真成功。
vivado工程以及学习sinc插值的过程文件(主要是为了存档,方便后续自己使用):https://download.csdn.net/download/yindq1220/87557975?spm=1001.2014.3001.5501
相关文章:

基于FPGA实现正弦插值算法
1、正弦插值的算法分析 1.1 信号在时域与频域的映射关系 在进行正弦算法分析之前,我们回顾一下《数字信号处理》课程中,对于信号在时域与频域之间的映射关系,如下图。 对于上图中的原始信号x(t),使用ADC对信号进行采样࿰…...
JavaWeb_会话技术
文章目录会话跟踪技术的概述Cookie概念Cookie工作流程Cookie基本使用发送Cookie获取CookieCookie原理分析Cookie的使用细节Cookie的存活时间Cookie存储中文SessionSession的基本使用概念工作流程Session的基本使用Session的原理分析Session的使用细节Session的钝化与活化Sessio…...

Reactor响应式流的核心机制——背压机制
响应式流是什么? 响应式流旨在为无阻塞异步流处理提供一个标准。它旨在解决处理元素流的问题——如何将元素流从发布者传递到订阅者,而不需要发布者阻塞,或订阅者有无限制的缓冲区或丢弃。 响应式流模型存在两种基本的实现机制。一种就是传统…...

[数据结构]栈的深入学习-java实现
CSDN的各位uu们你们好,今天千泽带来了栈的深入学习,我们会简单的用代码实现一下栈, 接下来让我们一起进入栈的神奇小世界吧!0.速览文章一、栈的定义1. 栈的概念2. 栈的图解二、栈的模拟实现三.栈的经典使用场景-逆波兰表达式总结一、栈的定义 1. 栈的概念 栈:一种…...

网络编程基础
1 互联网的本质硬件设备有了操作系统,然后装上软件之后我们就能够正常使用了,然后也只能自己使用。像这样,每个人都拥有一台自己的机器,然而彼此孤立。如何才能和大家一起愉快的玩耍?什么是网络?简单来说&a…...
华为OD机试题 - 数列还原(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:数列还原题目输入输出示例一输入输出Code代码解析版权说明华为O…...
10-Oracle存储过程(创建,修改,使用及管理)
本章内容 1、我们为什么要用存储过程? 2、存储过程是如何定义和维护的? 3、我们如何调用存储过程? 4、存储过程中常用的复合数据处理方式及CTE 5、存储过程如何进行异常处理? 6、存储过程如何进行事务处理? 7、我们应如何优化存储过程? 1、我们为什么要用存储过程…...

创建线程的三种方法
文章目录1、创建一个类实现Runnable接口,并重写run方法。2、创建一个类继承Thread类,并重写run方法。3、实现Callable接口,重写call()方法,这种方式可以通过FutureTask获取任务执行的返回值。4、run()方法和start()方法有什么区别…...
第一章---Pytorch快速入门---第三节---pytorch中的数据操作和预处理
目录 1.高维数组 1.1 回归数据准备 1.2 分类数据准备 2. 图像数据 1.torchvision.datasets模块导入数据并预处理 2.从文件夹中导入数据并进行预处理 pytorch中torch.utils.data模块包含着一些常用的数据预处理的操作,主要用于数据的读取、切分、准备等。 常用…...
【代码随想录训练营】【Day38】第九章|动态规划|理论基础|509. 斐波那契数|70. 爬楼梯|746. 使用最小花费爬楼梯
理论基础 动态规划与贪心的区别并不是学习动态规划所必须了解的,所以并不重要。 想要了解动态规划算法题的特点,可以直接做下面三道入门简单题练练手感,找找感觉,很快就能体会到动态规划的解题思想。 总结成一句话就是…...
华为OD机试题 - 快递货车(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:快递货车题目输入输出示例一输入输出Code解题思路版权说明华为O…...

前端——7.图像标签和路径
这篇文章,我们来讲解一下图像标签 目录 1.图像标签 1.1介绍 1.2实际展示 1.3图像标签的属性 1.3.1 alt属性 1.3.2 title属性 1.3.3 width / height 属性 1.3.4 border属性 1.4注意事项 2.文件夹 2.1目录文件夹和根目录 2.2 VSCode打开目录文件夹 3.路…...

java -- stream流
写在前面: stream流一直在使用,但是感觉还不够精通,现在深入研究一下。 stream这个章节中,会用到 函数式接口–lambda表达式–方法引用的相关知识 介绍 是jdk8引进的新特性。 stream流是类似一条流水线一样的操作,每次对数据进…...

【Spring6】| Bean的四种获取方式(实例化)
目录 一:Bean的实例化方式 1. 通过构造方法实例化 2. 通过简单工厂模式实例化 3. 通过factory-bean实例化 4. 通过FactoryBean接口实例化 5. BeanFactory和FactoryBean的区别(面试题) 6. 使用FactoryBean注入自定义Date 一:…...

01: 新手学SpringCloud前需知道的5点
目录 第一点: 什么是微服务架构 第二点:为什么需要学习Spring Cloud 第三点: Spring Cloud 是什么 第四点: SpringCloud的优缺点 1、SpringCloud优点 2、SpringCloud缺点 第五点: SpringCloud由什么组成 1&…...
ubuntu apt安装arm交叉编译工具
查找查找编译目标为32位的gcc-arm交叉编译器命令apt-cache search arm|awk index($1,"arm")!0 {print}|grep gcc-arm\|g-arm #或者 apt-cache search arm|awk index($1,"arm")!0 {print}|grep -E gcc-arm|g\\-arm输出如下g-arm-linux-gnueabihf - GNU C co…...
阿里云一面经历
文章目录 ES 查询方式都有哪些?1 基于词项的查询term & terms 查询Fuzzy QueryWildcard Query2 基于全文的查询Match QueryQuery String QueryMatch Phrase Query3 复合查询Bool QueryElasticsearch 删除原理ES 大文章怎么存arthas 常用命令arthas 排查问题过程arthas 工作…...
Java Stream中 用List集合统计 求和 最大值 最小值 平均值
对集合数据的统计,是开发中常用的功能,掌握好Java Stream提供的方法,避免自己写代码统计,可以提高工作效率。 先造点数据: pigs.add(new Pig(1, "猪爸爸", 31, "M", false)); pigs.add(new Pig(…...

【Linux】多线程---线程控制
进程在前面已经讲过了,所以这次我们来讨论一下多线程。前言:线程的背景进程是Linux中资源及事物管理的基本单位,是系统进行资源分配和调度的一个独立单位。但是实现进程间通信需要借助操作系统中专门的通信机制,但是只这些机制将占…...

秒杀高并发解决方案
秒杀高并发解决方案 1.秒杀/高并发方案-介绍 秒杀/高并发 其实主要解决两个问题,一个是并发读,一个是并发写并发读的核心优化理念是尽量减少用户到 DB 来"读"数据,或者让他们读更少的数据, 并 发写的处理原则也一样针对秒杀系统需…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...