热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

串口多字节数据的接收

这次设计一个可以接收多字节(通过修改例化时的位宽实现)的串口接收模块。 当接收到9个字节的数据,但是我们只需要8个字节的数据时候,我们需要的是前八位的数据还是后八位的数

这次设计一个可以接收多字节(通过修改例化时的位宽实现)的串口接收模块。

 

当接收到9个字节的数据,但是我们只需要8个字节的数据时候,我们需要的是前八位的数据还是后八位的数据我们无法确定。

image

 

所以我们需要设定一种传输协议,这种协议我们可以自定义规则。我们就设定前缀为8'h55+8'hA5,后缀为8'hF0的一串数据即为我们需要的数据。

image


1、状态机的设定

 

image

 


2、需要的模块


(1) 8位串口接收模块

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: Lclone
//
// Create Date: 2022/12/16 15:37:44
// Design Name: uart_byte_rx
// Module Name: uart_byte_rx
// Project Name: uart_byte_rx
// Target Devices:
// Tool Versions:
// Description: 8位串口接收模块
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_byte_rx
# (
parameter RX_BAUD = 9600, //波特率
parameter CLK_FQC = 50_000_000, //模块时钟频率
parameter BAUD_CNT = CLK_FQC/RX_BAUD) //模块每波特需要计数的次数(设置此端口方便仿真用)
(
input Clk, //时钟频率接口
input Rst_n, //复位接口
input Uart_rx, //串口接收接口
output reg [7:0] Data, //接收到的数据接口
output reg Rx_done //接收完成信号
);

reg uart_rx_r; //延一拍
reg uart_rx_rr; //延两拍
reg receiv_begin; //接收开始信号
reg receiv_flag; //接收状态信号
reg [ 3:0] state; //状态机寄存器
reg [15:0] baud_cnt; //波及计数器
reg [ 3:0] sampel_cnt; //采样计数器
reg sampel_en; //采样使能
reg sampel_ref; //样本寄存器
reg [ 3:0] acc; //累加寄存器
reg [ 3:0] bit_cnt; //数据位寄存器

always @(posedge Clk) begin //延两拍为下降沿捕获
uart_rx_r <= Uart_rx;
uart_rx_rr <= uart_rx_r;
end

always @(posedge Clk or negedge Rst_n) begin //接收信号发生
if(Rst_n == 0)
receiv_begin <= 0;
else if(state == 0 & uart_rx_rr & ~uart_rx_r)
receiv_begin <= 1'b1;
else
receiv_begin <= 0;
end

always @(posedge Clk or negedge Rst_n) begin //状态机
if(Rst_n == 0) begin
state <= 0;
sampel_ref <= 8'b0;
acc <= 8'b0;
Data <= 8'b0;
end
else case(state)
0: //空闲状态
if(receiv_begin == 1)
state <= 3'd1;
else
state <= 0;

1: begin //抽样状态
if(sampel_en == 1) begin
sampel_ref <= Uart_rx;
state <= 3'd2;
end
else
state <= 3'b1;
end
2: begin //数据判断状态
acc <= acc + sampel_ref;

if(sampel_cnt == 7) begin
if(acc >= 4)
begin Data[7] <= 1'b1; state <= 3'd3;acc <= 8'b0; end
else
begin Data[7] <= 0; state <= 3'd3;acc <= 8'b0; end
end
else
state <= 3'd1;
end
3: begin //数据移位状态
if(bit_cnt <8) begin
Data <= Data >> 1;
state <= 3'd1;
end
else
state <= 0;
end

default:;
endcase
end

always @(posedge Clk or negedge Rst_n) begin //接收进行标志
if(Rst_n == 0)
receiv_flag <= 0;
else if(receiv_begin == 1)
receiv_flag <= 1'b1;
else if(bit_cnt == 9 & baud_cnt == BAUD_CNT/9*8) //这里设置为记到BAUD_CNT/9*8是为了让Rx_done信号提前一点产生,避免因为Rx_done出现过晚,导致错过下一个起始位的下降沿。后面和其相同的条件判断,也是因为相同原因设置的。
receiv_flag <= 1'b0;
end

always @(posedge Clk or negedge Rst_n) begin //波特计数
if(Rst_n == 0)
baud_cnt <= 0;
else if(receiv_flag == 1) begin
if(baud_cnt == BAUD_CNT - 1)
baud_cnt <= 0;
else
baud_cnt <= baud_cnt + 1'b1;
end
else
baud_cnt <= 0;
end

always @(posedge Clk or negedge Rst_n) begin //采样计数
if(Rst_n == 0) begin
sampel_cnt <= 0;
sampel_en <= 0;
end
else if(receiv_flag == 1) begin
case(baud_cnt)
BAUD_CNT/9*1-1 : begin sampel_cnt <= 0; sampel_en <=1; end
BAUD_CNT/9*2-1 : begin sampel_cnt <= 1; sampel_en <=1; end
BAUD_CNT/9*3-1 : begin sampel_cnt <= 2; sampel_en <=1; end
BAUD_CNT/9*4-1 : begin sampel_cnt <= 3; sampel_en <=1; end
BAUD_CNT/9*5-1 : begin sampel_cnt <= 4; sampel_en <=1; end
BAUD_CNT/9*6-1 : begin sampel_cnt <= 5; sampel_en <=1; end
BAUD_CNT/9*7-1 : begin sampel_cnt <= 6; sampel_en <=1; end
BAUD_CNT/9*8-1 : begin sampel_cnt <= 7; sampel_en <=1; end
BAUD_CNT/9*9-1 : sampel_cnt <= 0;
default:sampel_en <=0;
endcase
end
end

always @(posedge Clk or negedge Rst_n) begin //数据位计数
if(Rst_n == 0)
bit_cnt <= 0;
else if(bit_cnt == 9 & baud_cnt == BAUD_CNT/9*8)
bit_cnt <= 0;
else if(baud_cnt == BAUD_CNT - 1)
bit_cnt <= bit_cnt + 1'b1;
end

always @(posedge Clk or negedge Rst_n) begin //接收完成信号产生
if(Rst_n == 0)
Rx_done <= 0;
else if(bit_cnt == 9 & baud_cnt == BAUD_CNT/9*8)
Rx_done <= 1'b1;
else
Rx_done <= 0;
end
endmodule

3、设计的模块代码

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2022/12/25 00:26:10
// Design Name:
// Module Name: uart_bytes_rx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_bytes_rx
#( parameter DATA_WIDTH = 64,//数据位宽
parameter PREFIX1 = 8'h55,//前缀1
parameter PREFIX2 = 8'hA5,//前缀2
parameter ENDINGS = 8'hF0)//后缀
(
input Clk, //时钟信号
input Rst_n, //复位信号
input Uart_rx, //串口接收端口
output reg[DATA_WIDTH-1-8*3:0] Bytes_data, //多字节数据端口
output reg Bytes_Rx_done //多字节接收完成
);

reg [2:0] state; //状态机寄存器
reg [DATA_WIDTH-1:0] bytes_data_reg; //多字节数据接收寄存器
wire [7:0] rx_data_reg; //8位数据接收寄存器
wire Rx_done; //8位数据接收完成信号

uart_byte_rx
# (
.RX_BAUD (115200), //波特率
.CLK_FQC (50_000_000)) //时钟频率
uart_byte_rx_inst
(
.Clk (Clk), //时钟
.Rst_n (Rst_n), //复位
.Uart_rx (Uart_rx), //串口接收端口
.Data (rx_data_reg), //8位数据端口
.Rx_done (Rx_done) //8位数据接收完成
);

always @(posedge Clk or negedge Rst_n) begin//状态机
if(Rst_n == 0) begin
state <= 0;
bytes_data_reg <= 0;
Bytes_Rx_done <= 0;
Bytes_data <= 0;
end else case(state)
0:begin
if(Rx_done) begin
bytes_data_reg[DATA_WIDTH-1:DATA_WIDTH-1-7] <= rx_data_reg;//数据装载
state <= 3'd1;
end else begin
state <= 0;
Bytes_Rx_done <= 0;
end
end

1:begin
if(bytes_data_reg[DATA_WIDTH-1:DATA_WIDTH-1-7] == ENDINGS
&& bytes_data_reg[15:8] ==PREFIX2
&& bytes_data_reg[7:0] ==PREFIX1)//数据协议判断
begin
Bytes_data <= bytes_data_reg[DATA_WIDTH-1-8:16];
state <= 1'b0;
Bytes_Rx_done <= 1'b1;
bytes_data_reg <= 0;
end
else
state <= 3'd2;
end

2:begin
bytes_data_reg <= bytes_data_reg >> 8;//数据移位
state <= 0;
end
endcase
end

endmodule

4、仿真验证


(1)仿真激励文件

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2022/12/26 16:14:35
// Design Name:
// Module Name: uart_bytes_rx_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_bytes_rx_tb();

reg CLK_50M;
reg RST_N;
wire [39:0] Bytes_data;
reg Uart_rx;
wire Bytes_Rx_done;
uart_bytes_rx
# (
.DATA_WIDTH (64))
uart_bytes_rx_inst
(
.Clk (CLK_50M),
.Rst_n (RST_N),
.Uart_rx (Uart_rx),
.Bytes_data (Bytes_data),
.Bytes_Rx_done (Bytes_Rx_done)
);

defparam uart_bytes_rx_inst.uart_byte_rx_inst.BAUD_CNT = 50;

always #10 CLK_50M <= ~CLK_50M;

initial begin
CLK_50M <= 1'b0;
RST_N <= 1'b0;
Uart_rx <= 1'b1;
#100
RST_N <= 1'b1;
#20
data_deliver(8'h55);
#100
data_deliver(8'hA5);
#100
data_deliver(8'h01);
#100
data_deliver(8'h23);
#100
data_deliver(8'h45);
#100
data_deliver(8'h67);
#100
data_deliver(8'h89);
#100
data_deliver(8'hf0);
#100
$stop;
end

task data_deliver;
input [7:0] test_data;
begin
Uart_rx <= 1'b0;
#1000
Uart_rx <= test_data[0];
#1000
Uart_rx <= test_data[1];
#1000
Uart_rx <= test_data[2];
#1000
Uart_rx <= test_data[3];
#1000
Uart_rx <= test_data[4];
#1000
Uart_rx <= test_data[5];
#1000
Uart_rx <= test_data[6];
#1000
Uart_rx <= test_data[7];
#1000
Uart_rx <= 1'b1;
#1000;
end
endtask
endmodule

(2)仿真结果

image

 


5、应用实例

 

我们把它应用为一个通过接收电脑串口发送的数据从而改变8位LED每位是否闪烁闪烁的周期的程序。


top.v

`timescale 1ns / 1ps
module Top(
input Sclk,
input Rst_n,
input Uart_rx,
output [7:0] LED
);
wire [23:0] Bytes_data;
wire Bytes_Rx_done;
uart_bytes_rx
# ( .DATA_WIDTH (48),
.PREFIX1 (8'h55),
.PREFIX2 (8'hA5),
.ENDINGS (8'hF0))
uart_bytes_rx_inst
(
.Clk (Sclk),
.Rst_n (Rst_n),
.Uart_rx (Uart_rx),
.Bytes_data (Bytes_data),
.Bytes_Rx_done (Bytes_Rx_done)
);

LED_6 LED_6_inst(
.SCLK (Sclk),
.RST_N (Rst_n),
.CTRL_IN (Bytes_data[7:0]),
.Time (Bytes_data[23:8]),
.LED (LED)
);
endmodule

 


uart_bytes_rx.v

`timescale 1ns / 1ps
module uart_bytes_rx
#( parameter DATA_WIDTH = 64,//数据位宽
parameter PREFIX1 = 8'h55,//前缀1
parameter PREFIX2 = 8'hA5,//前缀2
parameter ENDINGS = 8'hF0)//后缀
(
input Clk, //时钟信号
input Rst_n, //复位信号
input Uart_rx, //串口接收端口
output reg[DATA_WIDTH-1-8*3:0] Bytes_data, //多字节数据端口
output reg Bytes_Rx_done //多字节接收完成
);

reg [2:0] state; //状态机寄存器
reg [DATA_WIDTH-1:0] bytes_data_reg; //多字节数据接收寄存器
wire [7:0] rx_data_reg; //8位数据接收寄存器
wire Rx_done; //8位数据接收完成信号

uart_byte_rx
# (
.RX_BAUD (115200), //波特率
.CLK_FQC (50_000_000)) //时钟频率
uart_byte_rx_inst
(
.Clk (Clk), //时钟
.Rst_n (Rst_n), //复位
.Uart_rx (Uart_rx), //串口接收端口
.Data (rx_data_reg), //8位数据端口
.Rx_done (Rx_done) //8位数据接收完成
);

always @(posedge Clk or negedge Rst_n) begin//状态机
if(Rst_n == 0) begin
state <= 0;
bytes_data_reg <= 0;
Bytes_Rx_done <= 0;
Bytes_data <= 0;
end else case(state)
0:begin
if(Rx_done) begin
bytes_data_reg[DATA_WIDTH-1:DATA_WIDTH-1-7] <= rx_data_reg;//数据装载
state <= 3'd1;
end else begin
state <= 0;
Bytes_Rx_done <= 0;
end
end

1:begin
if(bytes_data_reg[DATA_WIDTH-1:DATA_WIDTH-1-7] == ENDINGS
&& bytes_data_reg[15:8] ==PREFIX2
&& bytes_data_reg[7:0] ==PREFIX1)//数据协议判断
begin
Bytes_data <= bytes_data_reg[DATA_WIDTH-1-8:16];
state <= 1'b0;
Bytes_Rx_done <= 1'b1;
bytes_data_reg <= 0;
end
else
state <= 3'd2;
end

2:begin
bytes_data_reg <= bytes_data_reg >> 8;//数据移位
state <= 0;
end
endcase
end

endmodule

uart_byte_rx.v

`timescale 1ns / 1ps
module uart_byte_rx
# (
parameter RX_BAUD = 9600,
parameter CLK_FQC = 50_000_000,
parameter BAUD_CNT = CLK_FQC/RX_BAUD)
(
input Clk,
input Rst_n,
input Uart_rx,
output reg [7:0] Data,
output reg Rx_done
);

reg uart_rx_r;
reg uart_rx_rr;
reg receiv_begin;
reg receiv_flag;
reg [ 3:0] state;
reg [15:0] baud_cnt;
reg [ 3:0] sampel_cnt;
reg sampel_en;
reg sampel_ref;
reg [ 3:0] acc;
reg [ 3:0] bit_cnt;

always @(posedge Clk) begin
uart_rx_r <= Uart_rx;
uart_rx_rr <= uart_rx_r;
end

always @(posedge Clk or negedge Rst_n) begin
if(Rst_n == 0)
receiv_begin <= 0;
else if(state == 0 & uart_rx_rr & ~uart_rx_r)
receiv_begin <= 1'b1;
else
receiv_begin <= 0;
end

always @(posedge Clk or negedge Rst_n) begin
if(Rst_n == 0) begin
state <= 0;
sampel_ref <= 8'b0;
acc <= 8'b0;
Data <= 8'b0;
end
else case(state)
0:
if(receiv_begin == 1)
state <= 3'd1;
else
state <= 0;

1: begin
if(sampel_en == 1) begin
sampel_ref <= Uart_rx;
state <= 3'd2;
end
else
state <= 3'b1;
end
2: begin
acc <= acc + sampel_ref;

if(sampel_cnt == 7) begin
if(acc >= 4)
begin Data[7] <= 1'b1; state <= 3'd3;acc <= 8'b0; end
else
begin Data[7] <= 0; state <= 3'd3;acc <= 8'b0; end
end
else
state <= 3'd1;
end
3: begin
if(bit_cnt <8) begin
Data <= Data >> 1;
state <= 3'd1;
end
else
state <= 0;
end

default:;
endcase
end

always @(posedge Clk or negedge Rst_n) begin
if(Rst_n == 0)
receiv_flag <= 0;
else if(receiv_begin == 1)
receiv_flag <= 1'b1;
else if(bit_cnt == 9 & baud_cnt == BAUD_CNT/9*8)
receiv_flag <= 1'b0;
end

always @(posedge Clk or negedge Rst_n) begin
if(Rst_n == 0)
baud_cnt <= 0;
else if(receiv_flag == 1) begin
if(baud_cnt == BAUD_CNT - 1)
baud_cnt <= 0;
else
baud_cnt <= baud_cnt + 1'b1;
end
else
baud_cnt <= 0;
end

always @(posedge Clk or negedge Rst_n) begin
if(Rst_n == 0) begin
sampel_cnt <= 0;
sampel_en <= 0;
end
else if(receiv_flag == 1) begin
case(baud_cnt)
BAUD_CNT/9*1-1 : begin sampel_cnt <= 0; sampel_en <=1; end
BAUD_CNT/9*2-1 : begin sampel_cnt <= 1; sampel_en <=1; end
BAUD_CNT/9*3-1 : begin sampel_cnt <= 2; sampel_en <=1; end
BAUD_CNT/9*4-1 : begin sampel_cnt <= 3; sampel_en <=1; end
BAUD_CNT/9*5-1 : begin sampel_cnt <= 4; sampel_en <=1; end
BAUD_CNT/9*6-1 : begin sampel_cnt <= 5; sampel_en <=1; end
BAUD_CNT/9*7-1 : begin sampel_cnt <= 6; sampel_en <=1; end
BAUD_CNT/9*8-1 : begin sampel_cnt <= 7; sampel_en <=1; end
BAUD_CNT/9*9-1 : sampel_cnt <= 0;
default:sampel_en <=0;
endcase
end
end

always @(posedge Clk or negedge Rst_n) begin
if(Rst_n == 0)
bit_cnt <= 0;
else if(bit_cnt == 9 & baud_cnt == BAUD_CNT/9*8)
bit_cnt <= 0;
else if(baud_cnt == BAUD_CNT - 1)
bit_cnt <= bit_cnt + 1'b1;
end
always @(posedge Clk or negedge Rst_n) begin
if(Rst_n == 0)
Rx_done <= 0;
else if(bit_cnt == 9 & baud_cnt == BAUD_CNT/9*8)
Rx_done <= 1'b1;
else
Rx_done <= 0;
end

endmodule

LED_6.v

`timescale 1ns / 1ps
module LED_6(
input SCLK,
input RST_N,
input [ 7:0] CTRL_IN,
input [15:0] Time,
output reg [ 7:0] LED
);

parameter DELAY_10US = 500;
parameter COUNT_10MS = 1000;

reg [8:0] count_10us;
reg [15:0] count_time;
reg led_flag;

always @(posedge SCLK or negedge RST_N) begin
if(RST_N == 0)
count_10us <= 0;
else if(count_10us == DELAY_10US - 1)
count_10us <= 0;
else
count_10us <= count_10us + 1'b1;
end

always @(posedge SCLK or negedge RST_N) begin
if(RST_N == 0)
count_time <= 0;
else if(count_time == Time - 1)
count_time <= 0;
else if(count_10us == DELAY_10US - 1)
count_time <= count_time + 1'b1;
end

always @(posedge SCLK or negedge RST_N) begin
if(RST_N == 0)
led_flag <= 0;
else if(count_time == COUNT_10MS - 1)
led_flag <= ~led_flag;
end

always @(posedge SCLK or negedge RST_N) begin
if(RST_N == 0)
LED <= 0;
else if(count_time == COUNT_10MS - 1 & led_flag == 1)
LED <= CTRL_IN;
else if(count_time == COUNT_10MS - 1 & led_flag == 0)
LED <= 0;
end

endmodule


推荐阅读
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 配置IPv4静态路由实现企业网内不同网段用户互访
    本文介绍了通过配置IPv4静态路由实现企业网内不同网段用户互访的方法。首先需要配置接口的链路层协议参数和IP地址,使相邻节点网络层可达。然后按照静态路由组网图的操作步骤,配置静态路由。这样任意两台主机之间都能够互通。 ... [详细]
author-avatar
梁梁庆新
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有