当前位置:网站首页>Implementation of SPI communication protocol based on FPGA
Implementation of SPI communication protocol based on FPGA
2022-07-23 19:00:00 【qq_ forty-four million nine hundred and eighty-five thousand si】
** One . SPI Basic principles of communication
- SPI Communication introduction **
SPI(Serial Perripheral Interface, Serial peripheral interface ) yes Motorola A synchronous serial interface technology introduced by the company .SPI The bus is physically connected to the peripheral microcontroller (PICmicro) The microprocessor control unit above (MCU)
It is called synchronous serial port (Synchronous Serial Port) Module (Module) To achieve , It allows the MCU
In full duplex synchronous serial mode , High speed data communication with various peripheral devices .
SPI Mainly used in EEPROM, Flash, Real time clock (RTC), A / D converter (ADC), Digital signal processor (DSP) And digital signal decoder . It only takes up four pins in the chip (Pin) Used to control and data transmission , Save the cost of the chip pin number , Also for PCB Save space in layout . It is out of this simple and easy-to-use feature , Now more and more chips are integrated SPI technology .
SPI It mainly has the following characteristics :
1、 Adopt master - Slave mode (Master-Slave) Control mode of
SPI There are two rules SPI Communication between devices must be done by the master device (Master) To control the secondary device (Slave). One Master Equipment can be provided by Clock And right Slave Device for film selection (Slave Select) To control multiple Slave equipment , SPI The agreement also states that Slave The equipment Clock from Master Equipment passing SCK Pins are provided to Slave equipment , Slave The device itself cannot produce or control Clock, No, Clock be Slave The device is not working properly .
2、 In synchronous mode (Synchronous) To transmit data
Master The device will generate the corresponding clock pulse according to the data to be exchanged (Clock Pulse), The clock pulses make up the clock signal (Clock Signal) , The clock signal passes through the clock polarity (CPOL) and Clock phase (CPHA) Controlling two SPI When to exchange data between devices and when to sample the received data , To ensure that data is transmitted synchronously between two devices .
3、 Data exchange (Data Exchanges)
SPI Data transmission between devices is also called data exchange , Because SPI The agreement provides for a SPI The device can't just act as a “ sender (Transmitter)” perhaps “ The receiver (Receiver)”. At every Clock In cycle , SPI The device sends and receives a bit Size data , It's equivalent to that the device has a bit The size of the data is exchanged .
One Slave If the device wants to be able to receive Master The control signal coming from , Must be able to be Master Device access (Access). therefore , Master The device must first pass through SS/CS pin Yes Slave Device for film selection , Put what you want to visit Slave The device is selected .
In the process of data transmission , Each received data must be sampled before the next data transmission . If the previously received data is not read , Then the received data may be discarded , Lead to SPI The physical module eventually fails . therefore , In a program, it's usually in SPI After transmitting the data , Read out SPI The data in the device , Even if the data (Dummy Data) It's useless in our program .
2. SPI Master slave module communication rules
The picture is right SPI A simple description of communication between devices , Let's explain the components shown in the figure below (Module):
SSPBUF, Synchronous Serial Port Buffer, Generally speaking SPI The internal buffer inside the device , Generally speaking, it is based on FIFO In the form of , Save temporary data during transmission ;
SSPSR, Synchronous Serial Port Register, Generally speaking SPI The shift register in the device (Shift Regitser), Its function is based on the set data bit width (bit-width) Move data in or out of SSPBUF;
Controller, Generally speaking SPI The control register in the device , You can configure them to set up SPI Bus transmission mode .
Usually , We only need to analyze the four pins described above (pin) Programming can control the whole SPI Data communication between devices :
SCK, Serial Clock, The main function is Master The equipment goes to Slave The device transmits the clock signal , Control the timing and rate of data exchange ;
SS/CS, Slave Select/Chip Select, be used for Master Device selection Slave equipment , Make the selected Slave Devices can be Master Device access ;
SDO/MOSI, Serial Data Output/Master Out Slave In, stay Master It's also called Tx-Channel, As an export of data , It is mainly used for SPI The device sends data ;
SDI/MISO, Serial Data Input/Master In Slave Out, stay Master It's also called Rx-Channel, As an entry to data , It is mainly used for SPI The device receives data ;
SPI The device is in the process of communication , Master Equipment and Slave There will be a data link loopback between devices (Data Loop), Just like the picture above , adopt SDO and SDI Pin , SSPSR Control data moving in and out SSPBUF, Controller determine SPI Bus communication mode , SCK Transmit the clock signal .
1、timing
First , Explain two concepts here :
CPOL: Clock polarity , Express SPI In my spare time , Is the clock signal high or low . if CPOL Is set to 1, Then when the device is idle SCK The clock signal at the foot of the tube is high . When CPOL Is set to 0 It's just the opposite .
CPHA: Clock phase , Express SPI The equipment is in SCK Data sampling is triggered when the clock signal on the pin becomes the rising edge , Or trigger data sampling when the clock signal becomes the falling edge . if CPHA Set to 1, be SPI The device triggers data sampling when the clock signal becomes a falling edge , Send data at rising edge . When CPHA Is set to 0 It's just the opposite .
The... Used in this example SPI The data transmission mode is set to CPOL = 1, CPHA = 1. such , In a Clock In cycle , Each individual SPI All devices can operate in full duplex (Full-Duplex) The way , Send and receive simultaneously 1 bit data , That is, it is equivalent to exchanging 1 bit Size data . If SPI Bus Channel-Width Is set to Byte, Express SPI The minimum unit of each data transmission on the bus is Byte, Then mount in the SPI Each data transmission process of bus equipment needs at least 8 individual Clock cycle ( Ignore the physical latency of the device ). therefore , SPI The faster the frequency of the bus , Clock Shorter period , be SPI The faster the rate of data exchange between devices .
2、SSPSR
SSPSR yes SPI Shift register inside the device (Shift Register). Its main function is based on SPI Clock signal status , Go to SSPBUF To move data in or out of , The data size of each move is determined by Bus-Width as well as Channel-Width Determined by .
Bus-Width The function of the is to specify the address of the bus to Master The unit of data transmission between devices .
for example , We want to go to Master In the equipment SSPBUF write in 16 Byte Size data : First , to Master Device configuration register settings Bus-Width by Byte; Then go to Master The equipment Tx-Data The shift register writes data at the entrance of the address bus , Every time you write 1 Byte Size data ( Use writeb function ); finish writing sth. 1 Byte After the data , Master In the equipment Tx-Data The shift register will automatically transfer from the address bus 1 Byte Data moved into SSPBUF in ; The above actions need to be repeated 16 Time .
Channel-Width The purpose of this is to specify Master Equipment and Slave The unit of data transmission between devices . And Bus-Width be similar , Master The shift register inside the device will be based on Channel-Width Automatically transfer data from Master-SSPBUF Pass through Master-SDO The pins are transported to Slave In the device Slave-SDI Pin , Slave-SSPSR Then move the received data into the Slave-SSPBUF in .
Usually , Bus-Width It's always greater than or equal to Channel-Width, This will ensure that there will be no cause of Master And Slave The frequency of data exchange between address bus and Master The frequency of data exchange between them should be fast , Lead to SSPBUF The data stored in it is invalid .
3、SSPBUF
We know , In every clock cycle , Master And Slave The data exchanged between them is actually SPI Internal shift register from SSPBUF It's a copy of . We can go to SSPBUF The corresponding register (Tx-Data / Rx-Data register) Read and write data in the library , Control indirectly SPI Inside the equipment SSPBUF.
for example , Before sending data , We should go to Master Of Tx-Data Register writes the data to be sent out , The data will be Master-SSPSR The shift register is based on Bus-Width Automatically move in Master-SSPBUF in , And then the data will be Master-SSPSR according to Channel-Width from Master-SSPBUF To remove from , adopt Master-SDO The pin passes to Slave-SDI Pin , Slave-SSPSR From Slave-SDI The received data is moved into Slave-SSPBUF in . meanwhile , Slave-SSPBUF The data in it depends on the size of the data received each time (Channel-Width), adopt Slave-SDO Sent to Master-SDI, Master-SSPSR And then take it from Master-SDI The received data is moved into Master-SSPBUF. After a single data transfer , User programs can be accessed from Master The equipment Rx-Data Register read Master Data from device data exchange .
4、Controller
Master In the equipment Controller Mainly through the clock signal (Clock Signal) And the chip selection signal (Slave Select Signal) To control Slave equipment . Slave The device will be waiting , Until received Master The chip selection signal from the device , Then it works according to the clock signal .
Master The chip selection operation of the device must be realized by the program . for example : By the program SS/CS The clock signal of the pin is pulled down , complete SPI The preliminary work of equipment data communication ; When the program wants SPI When the device ends data communication , And then SS/CS The clock signal on the pin is pulled high .
** Two . SPI Master slave module cases and FPGA Realization
- Case description **
Design 4 Line SPI master Module and slave modular , Requirements are as follows :
1、 Host module (master) Interface definition :
module spi_master(
input clk_40k, // Clock signal ,40kHz
input rst_n, // Reset signal , Low efficiency
input [7:0] data_in, // The master prepares the data to be output to the slave ,8 A wide
input send_start, // Communication enable signal , Highly effective , Width is 1 Clock cycles (40kHz), After receiving this signal, start a master-slave device communication .
output [7:0] data_out, // Data received by the host from the slave ,8 A wide
output data_out_vld, // Output data valid flag , High active , Width is 1 Clock cycles (40kHz)
output cs_n, // Select the enable signal from the device chip , Low efficiency , At low power level, select the slave device to communicate with the master device , Maintain low level when in communication state .
output sclk, // Synchronous clock ,1kHz, Set low level when idle
input miso, // The serial data that the master currently receives from the slave
output mosi // The serial data currently sent by the master to the slave
);
2、 Slave module (slave) Interface definition :
module spi_slave(
input rst_n, // Reset signal , Low efficiency
input cs_n, // Select the enable signal from the device chip
input sclk, //SPI The clock ,1kHz Set low level when idle ,
input mosi, // Serial data received by the slave from the host
output miso, // Serial data to be sent from the slave to the host
output [7:0] reg0_out, // Internal register 0 Value
output [7:0] reg1_out, // Internal register 1 Value
output [7:0] reg2_out, // Internal register 2 Value
output [7:0] reg3_out // Internal register 3 Value
);
3、 Circuit function description :
Slave There are four eight bit internal registers in the module (reg0、reg1、reg2、reg3), The addresses are 0~3,master Module through SPI Bus configuration slave The values of the four registers in the module ,slave The value of the register is output directly through its port .
Master Module received send_start After the signal , Put the data data_in adopt spi The bus is sent to slave Modular reg0, And then data_in Rotate two bits to the right and send to slave Modular reg1, And then data_in Rotate two bits to the right and send to reg2, The final will be data_in Recirculation shift right two bits sent to reg3. thus ,master Finish right slave Configuration of all registers in . then master Re pass spi The bus will slave in reg3 Read the data , adopt data_out Output , At the same time, a cycle width of data_out_vld.
4、SPI Transmission format :
SPI Each frame of data contains 16 position , The first to send 0 Bit is the read / write control bit , This bit is 0 representative master towards slave Writing data , by 1 Then represent master from slave Reading data ; Then send the 1-7 Bit is address bit , Send the high address first and then the low address ,9-16 Bits are data bits , High data first . All data are in sclk The rising edge of produces , Falling edge sampling .
SPI Write data format as shown in the figure 1 Shown :
SPI The read data format is shown in the figure 2 Shown :
2. Design thinking
1、SPI The agreement shall be determined by both parties , Here, the main module is required to send 5 Group number , The first four groups of slave modules are used to send data to different addresses , The fifth group is used to send the address and read the last data received from the module , Therefore, as required mosi Just send it out ;
2、 From the module slave Data to be read mosi Judge , If read 1, Judge later 7 Whether the bit is address , If yes, the address will be slave From module data through miso send out ; If read 0, Judge later 7 Whether the bit is address , Yes, it will mosi The sent data is received at the address slave From the register of the module .
3. FPGA Source code
1.SPI_master: The main module
module spi_master(
input clk_40k,
input rst_n,
input [7:0] data_in,
input send_start,
output reg [7:0] data_out,
output reg data_out_vld,
output reg cs_n,
output reg sclk,
input miso,
output reg mosi
);
reg flag; //recieve&transfer part
reg addr_flag; //mosi address output
reg data_flag; //mosi data output
reg [4:0] bit_cnt; //bit count
reg [6:0] clk_cnt; //40 count
reg [2:0] cs_n_cnt; //data transform count
reg [7:0] data_in_m0; //shifting input data
reg [7:0] data_in_m1; //shifting input data
reg [7:0] data_in_m2; //shifting input data
reg [7:0] data_in_m3; //shifting input data
reg [7:0] rx_data_out; //output data
reg [7:0] addr0;
reg [7:0] addr1;
reg [7:0] addr2;
reg [7:0] addr3;
reg [7:0] read;
parameter reg0_address = 7'b0000000; //address of reg0
parameter reg1_address = 7'b0000001; //address of reg1
parameter reg2_address = 7'b0000010; //address of reg2
parameter reg3_address = 7'b0000011; //address of reg3
localparam idle = 1'b0;
localparam work = 1'b1;
localparam transfer = 1'b0;
localparam recieve = 1'b1;
//set address of reg
always @ *
begin
if(~rst_n)
begin
addr0 <= {
1'b0, reg0_address};
addr1 <= {
1'b0, reg1_address};
addr2 <= {
1'b0, reg2_address};
addr3 <= {
1'b0, reg3_address};
read <= {
1'b1, reg3_address};
end
end
//cs_n
always @ (posedge clk_40k or negedge rst_n)
begin
if(~rst_n)
cs_n <= 1'b1;
else if(send_start == 1'b1)
cs_n <= 1'b0;
else if(clk_cnt == 7'd39 && bit_cnt == 5'd15 && cs_n_cnt == 3'b100)
cs_n <= 1'b1;
end
//clk_cnt 20 count
always @ (posedge clk_40k or negedge rst_n)
begin
if(~rst_n)
clk_cnt <= 7'b0;
else if(cs_n == 1'b0 && clk_cnt != 7'd39)
clk_cnt <= clk_cnt + 1'b1;
else if(cs_n == 1'b0 && clk_cnt == 7'd39)
clk_cnt <= 7'b0;
end
//sclk
always @ (posedge clk_40k or negedge rst_n)
begin
if(~rst_n)
sclk <= 1'b0;
else if(send_start == 1'b1)
sclk <= 1'b1;
else if(clk_cnt == 7'd19 || clk_cnt == 7'd39)
sclk <= ~sclk;
end
//bit_cnt 16 count
always @ (posedge clk_40k or negedge rst_n)
begin
if(~rst_n || cs_n)
bit_cnt <= 5'b0;
else if(bit_cnt != 5'd15 && cs_n == 1'b0 && clk_cnt == 7'd39)
bit_cnt <= bit_cnt + 1'b1;
else if(bit_cnt == 5'd15 && cs_n == 1'b0 && clk_cnt == 7'd39)
bit_cnt <= 5'b0;
else if(cs_n == 1'b1)
bit_cnt <= 5'b0;
end
//cs_n_cnt 4 salve count
always @ (posedge clk_40k or negedge rst_n)
begin
if(~rst_n || cs_n)
cs_n_cnt <= 3'b0;
else if(bit_cnt == 5'd15 && cs_n_cnt != 3'b100 && clk_cnt == 7'd39)
cs_n_cnt <= cs_n_cnt + 1'b1;
else if(bit_cnt == 5'd15 && cs_n_cnt == 3'b100 && clk_cnt == 7'd39)
cs_n_cnt <= 3'b0;
else if(cs_n == 1'b1)
cs_n_cnt <= 3'b0;
end
//input data shifting
always @ (posedge sclk or negedge rst_n)
begin
if(send_start == 1'b1)
begin
data_in_m0 <= data_in;
data_in_m1 <= {
data_in[1:0],data_in[7:2]};
data_in_m2 <= {
data_in[3:0],data_in[7:4]};
data_in_m3 <= {
data_in[5:0],data_in[7:6]};
end
end
//send part mosi
//flag of transfering address and data
always @ (negedge sclk or negedge rst_n)
begin
if(~rst_n)
begin
addr_flag <= work;
data_flag <= idle;
end
else if(bit_cnt == 5'd7)
begin
addr_flag <= idle;
data_flag <= work;
end
else if(bit_cnt == 5'd15 || send_start == 1'b1)
begin
addr_flag <= work;
data_flag <= idle;
end
end
//output mosi address and data
always @ (posedge sclk or negedge rst_n)
begin
if(addr_flag == work && cs_n == 1'b0)
begin
case(cs_n_cnt)
3'b000:
begin
mosi <= addr0[7];
addr0 <= {
addr0[6:0],addr0[7]};
end
3'b001:
begin
mosi <= addr1[7];
addr1 <= {
addr1[6:0],addr1[7]};
end
3'b010:
begin
mosi <= addr2[7];
addr2 <= {
addr2[6:0],addr2[7]};
end
3'b011:
begin
mosi <= addr3[7];
addr3 <= {
addr3[6:0],addr3[7]};
end
3'b100:
begin
mosi <= read[7];
read <= {
read[6:0],read[7]};
end
endcase
end
else if(data_flag == work && cs_n == 1'b0)
begin
case(cs_n_cnt)
3'b000:
begin
mosi <= data_in_m0[7];
data_in_m0 <= {
data_in_m0[6:0],data_in_m0[7]};
end
3'b001:
begin
mosi <= data_in_m1[7];
data_in_m1 <= {
data_in_m1[6:0],data_in_m1[7]};
end
3'b010:
begin
mosi <= data_in_m2[7];
data_in_m2 <= {
data_in_m2[6:0],data_in_m2[7]};
end
3'b011:
begin
mosi <= data_in_m3[7];
data_in_m3 <= {
data_in_m3[6:0],data_in_m3[7]};
end
3'b100:
begin
mosi <= 1'bz;
end
endcase
end
else if(cs_n == 1'b1)
mosi <= 1'bz;
end
//recieve part miso
//recieve data
always @ (negedge sclk or negedge rst_n)
begin
if(~rst_n)
rx_data_out <= 8'b0;
else if(flag == 1'b1)
rx_data_out <= {
rx_data_out[6:0],miso};
end
//output & valid
always @ (posedge clk_40k or negedge rst_n)
begin
if(~rst_n)
data_out_vld <= 1'b0;
else if(bit_cnt == 5'd15 && clk_cnt== 7'd39 && cs_n == 1'b0 && cs_n_cnt == 3'b100)
begin
data_out_vld <= 1'b1;
data_out <= rx_data_out;
end
else
data_out_vld <= 1'b0;
end
//recieve/transfer switch
always @ (posedge clk_40k or negedge rst_n)
begin
if(~rst_n)
flag <= 1'b0;
else if(clk_cnt == 7'd39 && bit_cnt == 5'd7 && cs_n_cnt == 3'b100 && flag == 1'b0)
flag <= 1'b1;
else if(clk_cnt == 7'd0 && bit_cnt == 5'd0 && flag == 1'b1)
flag <= 1'b0;
end
endmodule
2.SPI_slave: From the module
module spi_slave
(
input rst_n,
input cs_n,
input sclk,
input mosi,
output reg miso,
output reg [7:0] reg0_out,
output reg [7:0] reg1_out,
output reg [7:0] reg2_out,
output reg [7:0] reg3_out
);
reg [6:0] bit_cnt;
reg state;
reg n_state;
reg [6:0] address;
reg token;
localparam idle = 1'b0;
localparam transmit = 1'b1;
//bit_cnt
always @ (posedge sclk or negedge rst_n)
if(~rst_n || cs_n)
bit_cnt <= 7'd0;
else if(bit_cnt == 7'd15)
bit_cnt <= 7'd0;
else if(state || n_state)
bit_cnt <= bit_cnt + 1'b1;
//n_state
always @ *
if(cs_n)
n_state <= idle;
else
n_state <= transmit;
//state
always @ (posedge sclk or negedge rst_n)
if(~rst_n)
state <= idle;
else
state <= n_state;
//reg_out
always @ (negedge sclk or negedge rst_n)
if(~rst_n)
begin
reg0_out <= 8'd0;
reg1_out <= 8'd0;
reg2_out <= 8'd0;
reg3_out <= 8'd0;
end
else if(bit_cnt >= 'd8 && token == 'b0)
begin
case(address)
7'd0:
reg0_out <= {
reg0_out[6:0], mosi};
7'd1:
reg1_out <= {
reg1_out[6:0], mosi};
7'd2:
reg2_out <= {
reg2_out[6:0], mosi};
7'd3:
reg3_out <= {
reg3_out[6:0], mosi};
endcase
end
//address
always @ (negedge sclk or negedge rst_n)
if(~rst_n)
address <= 7'd0;
else if(bit_cnt >= 7'd1 && bit_cnt <= 7'd7)
address <= {
address[5:0], mosi};
//token
always @ (negedge sclk or negedge rst_n)
if(~rst_n)
token <= 1'b0;
else if(state == transmit && bit_cnt == 7'b0)
token <= mosi;
//miso
always @ (posedge sclk or negedge rst_n)
if(~rst_n || state == idle || cs_n)
miso <= 1'b0;
else if(state == transmit && token == 1'b1 && bit_cnt >= 7'd7)
begin
case(address)
7'd0: miso <= reg0_out[14-bit_cnt];
7'd1: miso <= reg1_out[14-bit_cnt];
7'd2: miso <= reg2_out[14-bit_cnt];
7'd3: miso <= reg3_out[14-bit_cnt];
endcase
end
else
miso <= 1'b0;
endmodule
3.testbench: The test file
`timescale 1us/1us
module tb();
reg clk_40k;
reg rst_n;
reg [7:0] data_in;
reg send_start;
wire sclk;
wire cs_n;
wire mosi;
wire miso;
wire [7:0] data_out;
wire data_out_vld;
wire [7:0] reg0_out;
wire [7:0] reg1_out;
wire [7:0] reg2_out;
wire [7:0] reg3_out;
spi_master i_spi_master(
.clk_40k (clk_40k ),
.rst_n (rst_n ),
.data_in (data_in ),
.send_start (send_start),
.sclk (sclk ),
.cs_n (cs_n ),
.mosi (mosi ),
.miso (miso ),
.data_out (data_out ),
.data_out_vld (data_out_vld )
);
spi_slave i_spi_slave(
.rst_n (rst_n ),
.cs_n (cs_n ),
.sclk (sclk ),
.mosi (mosi ),
.miso (miso ),
.reg0_out (reg0_out ),
.reg1_out (reg1_out ),
.reg2_out (reg2_out ),
.reg3_out (reg3_out )
);
initial
begin
rst_n = 1'b0;
#10 rst_n = 1'b1;
end
initial
begin
clk_40k = 1'b0;
forever
#1 clk_40k = ~clk_40k;
end
initial
begin
send_start = 1'b0;
data_in = 8'd0;
forever
begin
#200;
data_in = $random()%256;
send_start = 1'b1;
#2
send_start = 1'b0;
#8000;
end
end
endmodule
Waveform output results :

边栏推荐
- Analysis on the implementation of Flink exactly once delivery
- [2020] [paper notes] Based on Rydberg atom——
- MySQL [knowing and mastering one article is enough]
- 基于 softether 搭建虚拟私有网络
- Redis [super superfine introductory tutorial]
- C#启动程序传递参数丢失双引号,如何解决?
- [sharing game modeling model making skills] how ZBrush adjusts the brush size
- ZigBee integrated development environment IAR installation
- integer 和==比较
- What is the use of tampermonkey?
猜你喜欢

【2022】【论文笔记】太赫兹量子阱——

1259. Programmation dynamique de poignée de main disjointe
![[heavyweight] focusing on the terminal business of securities companies, Borui data released a new generation of observable platform for the core business experience of securities companies' terminals](/img/28/8d9f33ad6f54d6344429a687a7d1d7.png)
[heavyweight] focusing on the terminal business of securities companies, Borui data released a new generation of observable platform for the core business experience of securities companies' terminals
![[whole process of game modeling model production] ZBrush weapon model production: Crossbow](/img/b0/d63f1760dc0d7b5d342858848ae3b8.png)
[whole process of game modeling model production] ZBrush weapon model production: Crossbow

11. Basic concepts of neural network
[paper reading] gettext: trajectory flow map enhanced transformer for next POI recommendation

How does the NiO mechanism of jetty server cause out of heap memory overflow

【2013】【论文笔记】太赫兹波段纳米颗粒表面增强拉曼——

Redis【超强超细 入门教程】
![[2018] [paper notes] graphene FET and [1] - Types and principles of gfets, characteristics of gfets, applications and principles of gfets in terahertz](/img/df/bc757c7f6f6b801fafdd5a99352ddd.png)
[2018] [paper notes] graphene FET and [1] - Types and principles of gfets, characteristics of gfets, applications and principles of gfets in terahertz
随机推荐
EmguCV 常用函数功能说明「建议收藏」
日志框架【详解学习】
PCL:多直线拟合(RANSAC)
[2018] [paper notes] graphene FET and [1] - Types and principles of gfets, characteristics of gfets, applications and principles of gfets in terahertz
Cell array processing
1、 Reptile concept and basic process
Three things programmers want to do most | comics
Spark installation and startup
图的存储结构与方法(二)
The first layer of OSI model: physical layer, the cornerstone of existence!
ros(27):rosparam简单使用与一种通过launch传递参数不成功与解决
deepstream学习笔记(二):gstreamer与deepstream-test1说明
【2022】【论文笔记】太赫兹量子阱——
Building virtual private network based on softther
【2020】【论文笔记】基于Rydberg原子的——
代码整洁,高效的系统方法
什么是堆栈以及堆栈的区别
建模刚开始学习很迷茫,次世代角色建模该怎么学习?
基于FPGA的SPI通讯协议实现
How does the NiO mechanism of jetty server cause out of heap memory overflow