【FPGA零基础学习之旅#15】串口接收模块设计与验证(工业环境)

news2025/1/16 1:59:32

🎉欢迎来到FPGA专栏~串口接收模块设计与验证(工业环境)


  • ☆* o(≧▽≦)o *☆~我是小夏与酒🍹
  • 博客主页:小夏与酒的博客
  • 🎈该系列文章专栏:FPGA学习之旅
  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • 📜 欢迎大家关注! ❤️
    FPGQ2

CSDN

🎉 目录-串口接收模块设计与验证(工业环境)

  • 一、效果演示
  • 二、模块设计思路
  • 三、代码详解
  • 四、扩展项目练习
    • 4.1 项目要求
    • 4.2 实现效果
    • 4.3 实现过程

遇见未来

一、效果演示

🥝效果展示:
效果展示

🥝接收展示:
PC机的串口助手发送数据,FPGA接收数据并将数据显示到数码管上(hex格式数据):
数码管显示

🥝代码展示:

串口接收模块:uart_byte_rx.v

module uart_byte_rx(
	input 				Clk,//50M
	input 				Rst_n,
	input 		[2:0]	baud_set,
	input 				data_rx,
	output 	reg [7:0]	data_byte,
	output 	reg			Rx_Done
);

	reg s0_Rx,s1_Rx;//同步寄存器
	
	reg tmp0_Rx,tmp1_Rx;//数据寄存器
	
	reg [15:0]bps_DR;//分频计数器计数最大值
	reg [15:0]div_cnt;//分频计数器
	reg bps_clk;//波特率时钟
	reg [7:0]bps_cnt;
	
	reg uart_state;
	
	reg [2:0] r_data_byte [7:0];
	
	reg [2:0]START_BIT;
	reg [2:0]STOP_BIT;
	
	wire nedge;
	
//--------<同步寄存器处理>--------		
//用于消除亚稳态
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)begin
			s0_Rx <= 1'b0;
			s1_Rx <= 1'b0;
		end
		else begin
			s0_Rx <= data_rx;
			s1_Rx <= s0_Rx;
		end
	end
	
//--------<数据寄存器处理>--------		
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)begin
			tmp0_Rx <= 1'b0;
			tmp1_Rx <= 1'b0;
		end
		else begin
			tmp0_Rx <= s1_Rx;
			tmp1_Rx <= tmp0_Rx;
		end
	end
	
//--------<下降沿检测>--------	
	assign nedge = !tmp0_Rx & tmp1_Rx;
	
//--------<div_cnt模块>--------	
//得到不同计数周期的计数器
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			div_cnt <= 16'd0;
		else if(uart_state)begin
			if(div_cnt == bps_DR)
				div_cnt <= 16'd0;
			else
				div_cnt <= div_cnt + 1'b1;
		end
		else
			div_cnt <= 16'd0;
	end
//--------<bps_clk信号的产生>--------	
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			bps_clk <= 1'b0;
		else if(div_cnt == 16'd1)
			bps_clk <= 1'b1;
		else
			bps_clk <= 1'b0;
	end
	
//--------<bps_clk计数模块>--------		
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			bps_cnt <= 8'd0;
		else if(bps_cnt == 8'd159 || (bps_cnt == 8'd12 && (START_BIT > 2)))
			bps_cnt <= 8'd0;
		else if(bps_clk)
			bps_cnt <= bps_cnt + 1'b1;
		else
			bps_cnt <= bps_cnt;
	end
	
//--------<Rx_Done模块>--------	
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			Rx_Done <= 1'b0;
		else if(bps_cnt == 8'd159)
			Rx_Done <= 1'b1;
		else
			Rx_Done <= 1'b0;
	end	
	
//--------<波特率查找表>--------		
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			bps_DR <= 16'd324;
		else begin
			case(baud_set)
				0:bps_DR <= 16'd324;
				1:bps_DR <= 16'd162;
				2:bps_DR <= 16'd80;
				3:bps_DR <= 16'd53;
				4:bps_DR <= 16'd26;
				default:bps_DR <= 16'd324;
			endcase
		end	
	end

//--------<采样数据接收模块>--------	
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)begin
			START_BIT <= 3'd0;
			r_data_byte[0] <= 3'd0; 
			r_data_byte[1] <= 3'd0;
			r_data_byte[2] <= 3'd0; 
			r_data_byte[3] <= 3'd0;
			r_data_byte[4] <= 3'd0; 
			r_data_byte[5] <= 3'd0;
			r_data_byte[6] <= 3'd0; 
			r_data_byte[7] <= 3'd0;
			STOP_BIT <= 3'd0;
		end
		else if(bps_clk)begin
			case(bps_cnt)
				0:begin
					START_BIT <= 3'd0;
					r_data_byte[0] <= 3'd0;
					r_data_byte[1] <= 3'd0;
					r_data_byte[2] <= 3'd0;
					r_data_byte[3] <= 3'd0;
					r_data_byte[4] <= 3'd0;
					r_data_byte[5] <= 3'd0;
					r_data_byte[6] <= 3'd0;
					r_data_byte[7] <= 3'd0;
					STOP_BIT <= 3'd0; 
				end
				6,7,8,9,10,11:START_BIT <= START_BIT + s1_Rx;
				22,23,24,25,26,27:r_data_byte[0] <= r_data_byte[0] + s1_Rx;
				38,39,40,41,42,43:r_data_byte[1] <= r_data_byte[1] + s1_Rx;
				54,55,56,57,58,59:r_data_byte[2] <= r_data_byte[2] + s1_Rx;
				70,71,72,73,74,75:r_data_byte[3] <= r_data_byte[3] + s1_Rx;
				86,87,88,89,90,91:r_data_byte[4] <= r_data_byte[4] + s1_Rx;
				102,103,104,105,106,107:r_data_byte[5] <= r_data_byte[5] + s1_Rx;
				118,119,120,121,122,123:r_data_byte[6] <= r_data_byte[6] + s1_Rx;
				134,135,136,137,138,139:r_data_byte[7] <= r_data_byte[7] + s1_Rx;
				150,151,152,153,154,155:STOP_BIT <= STOP_BIT + s1_Rx;
				default:begin
					START_BIT <= START_BIT;
					r_data_byte[0] <= r_data_byte[0];
					r_data_byte[1] <= r_data_byte[1];
					r_data_byte[2] <= r_data_byte[2];
					r_data_byte[3] <= r_data_byte[3];
					r_data_byte[4] <= r_data_byte[4];
					r_data_byte[5] <= r_data_byte[5];
					r_data_byte[6] <= r_data_byte[6];
					r_data_byte[7] <= r_data_byte[7];
					STOP_BIT <= STOP_BIT;
				end
			endcase
		end
	end

//--------<数据状态判定模块>--------	
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			data_byte <= 8'd0;
		else if(bps_cnt == 8'd159)begin
			data_byte[0] <= r_data_byte[0][2];
			data_byte[1] <= r_data_byte[1][2];
			data_byte[2] <= r_data_byte[2][2];
			data_byte[3] <= r_data_byte[3][2];
			data_byte[4] <= r_data_byte[4][2];
			data_byte[5] <= r_data_byte[5][2];
			data_byte[6] <= r_data_byte[6][2];
			data_byte[7] <= r_data_byte[7][2];
		end
		else
			;
	end

//--------<uart_state模块>--------	
	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			uart_state <= 1'b0;
		else if(nedge)
			uart_state <= 1'b1;
		else if(Rx_Done || (bps_cnt == 8'd12 && (START_BIT > 2)))
			uart_state <= 1'b0;
		else
			uart_state <= uart_state;
	end

endmodule

二、模块设计思路

🔸有关于串口发送模块设计的相关文章如下:
【FPGA零基础学习之旅#13】串口发送模块设计与验证。
【FPGA零基础学习之旅#14】串口发送字符串。

在串口通信的一般应用中,采集每一位数据中间时刻的电平即认为是此位数据的电平。

但是在实际工业应用中,现场往往有非常强的电磁干扰,只采样一次就作为该数据的电平状态是不可靠的。很有可能恰好采集到被干扰的信号而导致结果出错,因此提出以下改进型的单 bit 数据接收方式示意图,使用多次采样求概率的方式进行状态判定:
采样方式
将每一位数据再平均分成了 16 小段。对于 Bit_x 这一位数据,考虑到数据在刚刚发生变化和即将发生变化的这一时期,数据极有可能不稳定的(用深灰色标出的两段),在这两个时间段采集数据,很有可能得到错误的结果,因此判定这两段时间的电平无效,采集时直接忽略。而中间这一时间段(用浅灰色标出),数据本身是比较稳定的,一般都代表了正确的结果。也就是前面提到的中间测量方式,但是也不排除该段数据受强电磁干扰而出现错误的电平脉冲。因此对这一段电平,进行多次采样,并求高低电平发生的概率,6 次采集结果中,取出现次数多的电平作为采样结果。例如,采样 6 次的结果分别为 1/1/1/1/0/1/,则取电平结果为 1,若为 0/0/1/0/0/0,,则取电平结果为 0,当 6 次采样结果中 1 和 0 各占一半(各 3 次),则可判断当前通信线路环境非常恶劣,数据不具有可靠性,不进行处理。

🥝串口接收模块的设计如下:
模块设计
🥝端口作用:

信号名称功能描述
Clk系统时钟 50Mhz
Rst_n系统复位信号
baud_set波特率选择信号
data_rx串行数据输入
data_byte并行数据输出
Rx_Done接收结束信号

三、代码详解

Verilog HDL的一维数组讲解参考:verilog数组的定义、转换和加法器的实现。

在代码的编写过程中,可以参考串口发送数据时的设计框架:
设计框架
其中,采样时钟的计算变为如下:
采样时钟的计算

代码中较难理解的部分如下:

//--------<采样数据接收模块>--------	
always@(posedge Clk or negedge Rst_n)begin
	if(!Rst_n)begin
		START_BIT <= 3'd0;
		r_data_byte[0] <= 3'd0; 
		r_data_byte[1] <= 3'd0;
		r_data_byte[2] <= 3'd0; 
		r_data_byte[3] <= 3'd0;
		r_data_byte[4] <= 3'd0; 
		r_data_byte[5] <= 3'd0;
		r_data_byte[6] <= 3'd0; 
		r_data_byte[7] <= 3'd0;
		STOP_BIT <= 3'd0;
	end
	else if(bps_clk)begin
		case(bps_cnt)
			0:begin
				START_BIT <= 3'd0;
				r_data_byte[0] <= 3'd0;
				r_data_byte[1] <= 3'd0;
				r_data_byte[2] <= 3'd0;
				r_data_byte[3] <= 3'd0;
				r_data_byte[4] <= 3'd0;
				r_data_byte[5] <= 3'd0;
				r_data_byte[6] <= 3'd0;
				r_data_byte[7] <= 3'd0;
				STOP_BIT <= 3'd0; 
			end
			6,7,8,9,10,11:START_BIT <= START_BIT + s1_Rx;
			22,23,24,25,26,27:r_data_byte[0] <= r_data_byte[0] + s1_Rx;
			38,39,40,41,42,43:r_data_byte[1] <= r_data_byte[1] + s1_Rx;
			54,55,56,57,58,59:r_data_byte[2] <= r_data_byte[2] + s1_Rx;
			70,71,72,73,74,75:r_data_byte[3] <= r_data_byte[3] + s1_Rx;
			86,87,88,89,90,91:r_data_byte[4] <= r_data_byte[4] + s1_Rx;
			102,103,104,105,106,107:r_data_byte[5] <= r_data_byte[5] + s1_Rx;
			118,119,120,121,122,123:r_data_byte[6] <= r_data_byte[6] + s1_Rx;
			134,135,136,137,138,139:r_data_byte[7] <= r_data_byte[7] + s1_Rx;
			150,151,152,153,154,155:STOP_BIT <= STOP_BIT + s1_Rx;
			default:begin
				START_BIT <= START_BIT;
				r_data_byte[0] <= r_data_byte[0];
				r_data_byte[1] <= r_data_byte[1];
				r_data_byte[2] <= r_data_byte[2];
				r_data_byte[3] <= r_data_byte[3];
				r_data_byte[4] <= r_data_byte[4];
				r_data_byte[5] <= r_data_byte[5];
				r_data_byte[6] <= r_data_byte[6];
				r_data_byte[7] <= r_data_byte[7];
				STOP_BIT <= STOP_BIT;
			end
		endcase
	end
end

//--------<数据状态判定模块>--------	
always@(posedge Clk or negedge Rst_n)begin
	if(!Rst_n)
		data_byte <= 8'd0;
	else if(bps_cnt == 8'd159)begin
		data_byte[0] <= r_data_byte[0][2];
		data_byte[1] <= r_data_byte[1][2];
		data_byte[2] <= r_data_byte[2][2];
		data_byte[3] <= r_data_byte[3][2];
		data_byte[4] <= r_data_byte[4][2];
		data_byte[5] <= r_data_byte[5][2];
		data_byte[6] <= r_data_byte[6][2];
		data_byte[7] <= r_data_byte[7][2];
	end
	else
		;
end

上述部分的代码需要紧密结合模块设计思路和verilog一维数组的语法来理解。

特别是在进行数据状态的判定中一直选择读取一维数组中每位数据的第三位:

data_byte[0] <= r_data_byte[0][2];
data_byte[1] <= r_data_byte[1][2];
data_byte[2] <= r_data_byte[2][2];
data_byte[3] <= r_data_byte[3][2];
data_byte[4] <= r_data_byte[4][2];
data_byte[5] <= r_data_byte[5][2];
data_byte[6] <= r_data_byte[6][2];
data_byte[7] <= r_data_byte[7][2];

编写思想举例如下:

对一位数据需进行 6 次采样,然后取出现次数较多的数据作为采样结果,也就是说,6 次采样中出现次数多于 3 次的数据才能作为最终的有效数据。对此,可以用接收到数据 r_data_byte[n]结合数值比较器来判断,也可以直接令其等于当前位的最高位数据。
以下面例子说明:当 r_data_byte[n]分别为二进制的 011B/010B/100B/101B时,这几个数据十进制格式分别为 3d/2d/4d/5d,可以发现大于等 4d 的为 100B/101B。当最高位是 1 即此时的数据累加值大于等于 4d,可以说明数据真实值为 1;当最高位是 0 即此时的数据累加值小于等于 3d,可以说明数据真实值为 0,因此只需判断最高位即可。

我们将该模块与串口发送模块(串口发送模块讲解)放到一起来进行仿真测试:

uart_byte_rx_tb.v:

`timescale 1ns/1ns
`define clock_period 20

module uart_byte_rx_tb;

	reg Clk;
	reg Rst_n;
	reg [2:0]baud_set;
	
	reg [7:0]data_byte;
	reg send_en;
	
	wire uart_tx;
	wire [7:0]data_byte_r;
	
	wire uart_state;
	
	wire Tx_Done;
	wire Rx_Done;
	
	uart_byte_tx uart_byte_tx0(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.data_byte(data_byte),
		.send_en(send_en),
		.baud_set(baud_set),
		.uart_tx(uart_tx),
		.Tx_Done(Tx_Done),
		.uart_state(uart_state)
	);
	
	uart_byte_rx uart_byte_rx0(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.baud_set(baud_set),
		.data_rx(uart_tx),
		.data_byte(data_byte_r),
		.Rx_Done(Rx_Done)
	);

	initial Clk = 1;
	always#(`clock_period / 2) Clk = ~Clk;

	initial begin
		Rst_n = 1'b0;
		data_byte = 8'd0;
		send_en = 1'd0;
		baud_set = 3'd4;
		#(`clock_period*20 + 1 );
		Rst_n = 1'b1;
		#(`clock_period*50);
		data_byte = 8'haa;
		send_en = 1'd1;
		#`clock_period;
		send_en = 1'd0;
		
		@(posedge Tx_Done)
		
		#(`clock_period*5000);
		data_byte = 8'h55;
		send_en = 1'd1;
		#`clock_period;
		send_en = 1'd0;
		@(posedge Tx_Done)
		#(`clock_period*5000);
	
		$stop;
	end

endmodule

仿真结果:

仿真结果

板级验证:

关于issp调试工具ip核的创建和使用参考:【FPGA零基础学习之旅#11】数码管动态扫描。注意在本次项目中使用的是issp的探针(probe) 功能,而非源;

编写板级验证代码:

module uart_byte_rx_top(
	input Clk,
	input Rst_n,
	input data_rx
);

	reg [7:0]data_byte_r;
	wire [7:0]data_byte;
	wire Rx_Done;
	
	uart_byte_rx uart_byte_rx0(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.baud_set(3'd0),
		.data_rx(data_rx),
		.data_byte(data_byte),
		.Rx_Done(Rx_Done)
	);

	issp issp(
		.probe(data_byte_r),
		.source()
	);

	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			data_byte_r <= 8'd0;
		else if(Rx_Done)
			data_byte_r <= data_byte;
		else
			data_byte_r <= data_byte_r;
	end
	
endmodule

其中,如下部分代码是对接收到的数据进行简单的缓存操作避免出现数据读取出错的情况

always@(posedge Clk or negedge Rst_n)begin
	if(!Rst_n)
		data_byte_r <= 8'd0;
	else if(Rx_Done)
		data_byte_r <= data_byte;
	else
		data_byte_r <= data_byte_r;
end

jic文件配置完成:
配置1
在issp调试工具的界面中选择连续读取数据
连续读取数据

并将数据格式为hex格式
hex格式
验证效果:
效果

四、扩展项目练习

4.1 项目要求

FPGA通过串口通信,将接收到的数据(hex格式)显示到数码管和issp调试工具上。

4.2 实现效果

电脑串口助手发送hex数据,issp接收到数据并将数据显示到数码管上:
数码管显示

4.3 实现过程

先通过RTL视图来理清思路:
RTL
FPGA通过串口通信(uart_byte_rx),先将接收到的数据进行简单的缓存操作(Data_r),再将数据依次传递给HEX8模块issp调试模块,其中HEX8模块将数据处理好之后再传给移位寄存器模块(m74HC595_Drive)。

🔸关于HEX8模块的讲解:【FPGA零基础学习之旅#11】数码管动态扫描。
🔸关于移位寄存器模块的讲解:【FPGA零基础学习之旅#12】三线制数码管驱动(74HC595)串行移位寄存器驱动。

先将数据缓存部分的代码封装为一个模块:

Data_r.v:

module Data_r(
	input 				Clk,
	input 				Rst_n,
	input 				Rx_Done,
	input 		[7:0]	data_byte,
	output reg 	[7:0]	data_byte_r
);

	always@(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)
			data_byte_r <= 8'd0;
		else if(Rx_Done)
			data_byte_r <= data_byte;
		else
			data_byte_r <= data_byte_r;
	end

endmodule

展示顶层模块:

uart_byte_rx_hex8_top.v:

module uart_byte_rx_hex8_top(
	input 			Clk,
	input 			Rst_n,
	input 			data_rx,
	output 			SH_CP,		//shift clock---------------SCK
	output 			ST_CP,		//latch data clock----------RCK
	output 			DS			//shift serial data---------Data
);

	wire 	[7:0]	data_byte_r;
	wire 	[7:0]	data_byte;
	wire 			Rx_Done;
	
	wire 	[7:0] sel;//数码管位选(选择当前要显示的数码管)
	wire 	[7:0] seg;//数码管段选(当前要显示的内容)	
	
	uart_byte_rx uart_byte_rx(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.baud_set(3'd0),
		.data_rx(data_rx),
		.data_byte(data_byte),
		.Rx_Done(Rx_Done)
	);
	
	Data_r Data_r(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.Rx_Done(Rx_Done),
		.data_byte(data_byte),
		.data_byte_r(data_byte_r)
	);
	
	issp issp(
		.probe(data_byte_r),
		.source()
	);
	
	//由于串口目前只接收一个字节数据,只占用2个数码管,所以其余数码管显示0
	HEX8 HEX8(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.En(1'b1),
		.disp_data({24'h0,data_byte_r}),
		.sel(sel),
		.seg(seg)
	);

	m74HC595_Driver m74HC595_Driver(
		.Clk(Clk),
		.Rst_n(Rst_n),
		.Data({seg,sel}),
		.S_EN(1'b1),
		.SH_CP(SH_CP),
		.ST_CP(ST_CP),
		.DS(DS)
	);
	
endmodule

(顶层模块中其余模块的设计代码直接从上述参考文章中复制过来即可)

jic文件配置完成:
配置2
最终实现效果:
实现效果

csdn

🧸结尾


  • ❤️ 感谢您的支持和鼓励! 😊🙏
  • 📜您可能感兴趣的内容:
  • 【FPGA零基础学习之旅#14】串口发送字符串
  • 【Python】串口通信-与FPGA、蓝牙模块实现串口通信(Python+FPGA)
  • 【Arduino TinyGo】【最新】使用Go语言编写Arduino-环境搭建和点亮LED灯
  • 【全网首发开源教程】【Labview机器人仿真与控制】Labview与Solidworks多路支配关系-四足爬行机器人仿真与控制
    遇见未来

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

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

相关文章

【ArcGIS微课1000例】0075:将AutoCAD(Dwg、Dxf)文件转换为shp、KML(kml、kmz)文件

文章目录 1. 加载DWG2. 导出为shp3. 投影变换4. 转为kml1. 加载DWG 打开ArcMap,点击添加符号: 选择地形图dwg数据,全选图层,也可以选择需要的图层。 提示位置的空间参考,点击确定即可。 加载效果。 2. 导出为shp 接下来我们演示将面状数据转为shp,选择Polygon图层,右键…

SD卡与NAND flash的差异

SD卡与普通的NAND Flash相比&#xff0c;具有以下优势和劣势&#xff1a; 优势&#xff1a; 可移动性&#xff1a;SD卡是一种可移动存储介质&#xff0c;可以轻松插入和拔出支持SD卡接口的设备&#xff0c;如相机、手机、笔记本电脑等。这使得SD卡成为方便携带和共享数据的理想…

maven构建拉依赖Malformed \uxxxx encoding

文章目录 简介踩坑原因解决方法一(不推荐)方法二(推荐)其他疑问简介 我在 mac 端本地拉项目下来,第一次点击 import pom 来产生第一次 build,发现能够拉依赖下来,在左侧也能看到依赖(jdk1.8 下的) 但是当我第二次 import pom 时候发现左侧依赖全消失了,而且提示错误…

Filebeat+Kafka+ELK日志分析架构

目录 一、zookeeper&#xff1a; 1. zookeeper 定义&#xff1a; 2. Zookeeper 工作机制: 3. Zookeeper 特点: 4. Zookeeper 数据结构: 5. Zookeeper 应用场景: 5.1 统一命名服务: 5.2 统一配置管理: 5.3 统一集群管理: 5.4 服务器动态上下线: 5.5 软负载均衡: 6. Zookeeper 选…

TCP/IP(二十一)TCP 实战抓包分析(五)TCP 第三次握手 ACK 丢包

一 实验三&#xff1a;TCP 第三次握手 ACK 丢包 第三次握手丢失了,会发生什么? 注意: ACK 报文是不会有重传的,当 ACK 丢失了,就由对方重传对应的报文 ① 实验环境 ② 模拟方式 1、 服务端配置防火墙iptables -t filter -I INPUT -s 172.25.2.157 -p tcp --tcp-flag ACK…

模拟面试

‍ 一、成功案例 “面试官说我的回答精准打击到他们的规划点”—— 为何能有这样得效果呢&#xff1f;除了常规的模拟面试流程&#xff0c;我还能提供一些—— 二、核心差异化价值 1、模拟面试前&#xff0c;我的用心准备 根据职位JD、公司/部门信息&#xff0c;我会梳理出面试…

攻防世界web篇-PHP2

直接点击进入到http网页中&#xff0c;会得到这样一个界面 这里&#xff0c;我最开始使用了burp什么包也没有抓到&#xff0c;然后接着又用nikto进行探测&#xff0c;得到的只有两个目录&#xff0c;当时两个目录打开后&#xff0c;一个是fond界面&#xff0c;一个是这个网页的…

Vue3响应式原理初探

vue3响应式原理初探 为什么要使用proxy取代defineProperty使用proxy如何完成依赖收集呢&#xff1f; 为什么要使用proxy取代defineProperty 原因1&#xff1a;defineproperty无法检测到原本不存在的属性。打个&#x1f330; new Vue({data(){return {name:wxs,age:25}}})在vue…

MSQL系列(五) Mysql实战-索引最左侧匹配原则分析及实战

Mysql实战-索引最左侧匹配原则分析及实战 前面我们讲解了索引的存储结构&#xff0c;BTree的索引结构&#xff0c;以及索引最左侧匹配原则&#xff0c;Explain的用法&#xff0c;今天我们来实战一下 最左侧匹配原则 1.联合索引最左侧匹配原则 联合索引有一个最左侧匹配原则 …

一文了解什么是数字孪生

数字孪生&#xff0c;作为数字化时代的新兴技术&#xff0c;正日益引领着未来的发展方向。它并非一种独立的工具或软件&#xff0c;而是一种理念&#xff0c;一种将实体与虚拟世界紧密结合的方法。本文将详细介绍数字孪生的本质、应用领域以及对未来的影响。 数字孪生的本质 …

Redis:Feed流之Timeline的实现

当我们关注了用户后&#xff0c;这个用户发了动态&#xff0c;那么我们应该把这些数据推送给用户&#xff0c;这个需求&#xff0c;其实我们又把他叫做Feed流&#xff0c;关注推送也叫做Feed流&#xff0c;直译为投喂。为用户持续的提供“沉浸式”的体验&#xff0c;通过无限下…

多测师肖sir_高级金牌讲师___python之模块openpyxl

python之模块openpyxl 一、用python读写excel的强大工具&#xff1a;openpyxl &#xff08;一&#xff09;下载openpyxl的方式 方式一&#xff1a;python -m pip install openpyxl 或 pip install openpyxl 方式二&#xff1a;在pycharm中安装 &#xff08;二&#xff09;…

《优化接口设计的思路》系列:第五篇—接口发生异常如何统一处理

系列文章导航 第一篇—接口参数的一些弯弯绕绕 第二篇—接口用户上下文的设计与实现 第三篇—留下用户调用接口的痕迹 第四篇—接口的权限控制 第五篇—接口发生异常如何统一处理 本文参考项目源码地址&#xff1a;summo-springboot-interface-demo 前言 大家好&#xff01;…

VScode运行SVN拉下来的项目

安装依赖包 pnpm install 启动程序 查看package.json文件中的serve&#xff0c;根据这个启动 pnpm dev 在浏览器使用http://localhost:8848/访问

论文阅读:Point-to-Voxel Knowledge Distillation for LiDAR Semantic Segmentation

来源&#xff1a;CVPR 2022 链接&#xff1a;https://arxiv.org/pdf/2206.02099.pdf 0、Abstract 本文解决了将知识从大型教师模型提取到小型学生网络以进行 LiDAR 语义分割的问题。由于点云的固有挑战&#xff0c;即稀疏性、随机性和密度变化&#xff0c;直接采用以前的蒸馏…

【算法设计与分析】第6章02 分支限界法

目录 分支限界法的设计技术 分支限界法&#xff1a;  约束条件  剪枝  分支限界法的设计步骤 思考题&#xff1a; 【例6-6】装载问题。  计算模型 【例6-7】背包  问题分析  问题分析 计算模型  计算模型  算法设计与描述 代码&#xff1a; 思…

文件打包下载excel导出和word导出

0.文件下载接口 请求 GET /pm/prj/menu/whsj/download/{affixId} 文件affixId多个id以逗号隔开。多个文件会以打包得形式。 1.Excel导出 1.0接口 POST 127.0.0.1:8400/pm/io/exportExcel/year-plan-table-workflow/report 参数 [{"org":"011","re…

C#快速排序算法

快速排序实现原理 快速排序&#xff08;Quick Sort&#xff09;是一种常用的排序算法&#xff0c;它基于分治的思想&#xff0c;通过将一个无序的序列分割成两个子序列&#xff0c;并递归地对子序列进行排序&#xff0c;最终完成整个序列的排序。 其基本思路如下&#xff1a; 选…

056:mapboxGL中layer的layout,paint,filter的属性值表达式说明总结

第056个 点击查看专栏目录 本篇文章是mapbox的layer中layout,paint,filter的表达式说明总结。 mapbox中 Expressions 是什么 Expressions:表达式集合(并非 style 的属性,只是 layer 的任何 layout布局属性和 paint绘制属性,以及 filter 属性等,它们的值都可以指定成一…

【NV GPU限制出口】昇腾能否接住滔天富贵

如何评价刘庆峰所言华为GPU已可对标英伟达A100&#xff1f; 国家超级计算济南中心&#xff1a; https://www.nsccjn.cn/