基于verlog语言的UART通信协议模块实现
前言
在此我就不对UART协议细节部分做介绍,网上相关的介绍太多了。目前通过串口调试助手成功实现板载时钟50MHz情况下最大波特率3000000 bit/s通信。
模块组成
顶层:uart_modu
底层:uart_tx_modu、uart_rx_modu
模块接口
顶层
uart_modu #(.CLK_FRE (50) , //模块时钟,单位MHz.BAUD_RATE(115200) //通信波特率
)
your_instance_name(.clk (clk ) , //input[0:0]模块时钟输入.rst (rst ) , //input[0:0]模块复位输入,高电平有效.i_tx_begin (i_tx_begin ) , //input[0:0]开始发送信号输入.i_tx_data (i_tx_data ) , //input[7:0]待发送数据输入.o_tx_done (o_tx_done ) , //output[0:0]发送完成标志输出.o_tx_busy (o_tx_busy ) , //output[0:0]模块忙碌标志.o_tx_pin (o_tx_pin ) , //output[0:0]发送引脚.o_rx_data (o_rx_data ) , //output[7:0]接收数据输出.o_rx_vald (o_rx_vald ) , //output[0:0]接收数据有效标志.o_rx_done (o_rx_done ) , //output[0:0]接收完成标志.o_rx_busy (o_rx_busy ) , //output[0:0]模块忙碌标志.i_rx_pin (i_rx_pin ) //input[0:0]接收引脚);
底层
uart_tx_modu #(.CLK_FRE (50) , //模块时钟,单位MHz.BAUD_RATE(115200) //通信波特率
)
your_instance_name(.clk (clk ), //input[0:0]模块时钟输入.rst (rst ), //input[0:0]模块复位输入,高电平有效.tx_begin (tx_begin ), //input[0:0]开始发送信号输入.tx_data (tx_data ), //input[7:0]待发送数据输入.tx_done (tx_done ), //output[0:0]发送完成标志输出.tx_busy (tx_busy ), //output[0:0]模块忙碌标志.tx_pin (tx_pin ) //output[0:0]发送引脚);
uart_rx_modu #(.CLK_FRE (50) , //模块时钟,单位MHz.BAUD_RATE(115200) //通信波特率
)
your_instance_name(.clk (clk ), //input[0:0]模块时钟输入.rst (rst ), //input[0:0]模块复位输入,高电平有效.rx_data (rx_data ), //output[7:0]接收数据输出.rx_vald (rx_vald ), //output[0:0]接收数据有效标志.rx_done (rx_done ), //output[0:0]接收完成标志.rx_busy (rx_busy ), //output[0:0]模块忙碌标志.rx_pin (rx_pin ) //input[0:0]接收引脚
);
时许仿真
tx_modu
测试代码
module tx_debug();localparam CUN = 10;always #(CUN) clk = ~clk;reg [0:0] clk = 1'b0;
reg [0:0] rst = 1'b0;
reg [0:0] tx_begin = 1'b0;
reg [7:0] tx_data = 8'hA5;
wire [0:0] tx_done ;
wire [0:0] tx_busy ;
wire [0:0] tx_pin ;initial begin #(CUN*4) rst = 1'b1;#(CUN*2) rst = 1'b0;#(CUN*4) tx_begin = 1'b1;#(CUN*2) tx_begin = 1'b0;enduart_tx_modu #(.CLK_FRE (50) , //模块时钟,单位MHz.BAUD_RATE(115200) //通信波特率
)
uart_tx_debug(.clk (clk ) , //input[0:0]模块时钟输入.rst (rst ) , //input[0:0]模块复位输入,高电平有效.tx_begin (tx_begin ) , //input[0:0]开始发送信号输入.tx_data (tx_data ) , //input[7:0]待发送数据输入.tx_done (tx_done ) , //output[0:0]发送完成标志输出.tx_busy (tx_busy ) , //output[0:0]模块忙碌标志.tx_pin (tx_pin ) //output[0:0]发送引脚);
endmodule
仿真截图
rx_modu
仿真源代码
module rx_debug();localparam CUN = 10;always #(CUN) clk = ~clk;reg [0:0] clk = 1'b0; //模块时钟输入
reg [0:0] rst = 1'b0; //模块复位输入,高电平有效
wire [7:0] rx_data; //接收数据输出
wire [0:0] rx_vald; //接收数据有效标志
wire [0:0] rx_done; //接收完成标志
wire [0:0] rx_busy; //模块忙碌标志
reg [0:0] rx_pin = 1'b1; //接收引脚initial begin #(CUN*4) rst = 1'b1;#(CUN*2) rst = 1'b0;#(CUN*4) rx_pin = 1'b0; //#8680 rx_pin = 1'b1; //1#8680 rx_pin = 1'b0; //2#8680 rx_pin = 1'b1; //3 #8680 rx_pin = 1'b0; //4 #8680 rx_pin = 1'b1; //5 #8680 rx_pin = 1'b0; //6 #8680 rx_pin = 1'b1; //7 #8680 rx_pin = 1'b0; //8 #8680 rx_pin = 1'b1; //
enduart_rx_modu #(.CLK_FRE (50) , //模块时钟,单位MHz.BAUD_RATE(3000000) //通信波特率
)
uart_tx_debug(.clk (clk ), //input[0:0]模块时钟输入.rst (rst ), //input[0:0]模块复位输入,高电平有效.rx_data (rx_data ), //output[7:0]接收数据输出.rx_vald (rx_vald ), //output[0:0]接收数据有效标志.rx_done (rx_done ), //output[0:0]接收完成标志.rx_busy (rx_busy ), //output[0:0]模块忙碌标志.rx_pin (rx_pin ) //input[0:0]接收引脚);
endmodule
仿真截图
源码
顶层
/*===============================================
//----------- Begin Cut here for uart_modu Template ---//
uart_modu #(.CLK_FRE (50) , //模块时钟,单位MHz.BAUD_RATE(115200) //通信波特率
)
your_instance_name(.clk (clk ) , //input[0:0]模块时钟输入.rst (rst ) , //input[0:0]模块复位输入,高电平有效.i_tx_begin (i_tx_begin ) , //input[0:0]开始发送信号输入.i_tx_data (i_tx_data ) , //input[7:0]待发送数据输入.o_tx_done (o_tx_done ) , //output[0:0]发送完成标志输出.o_tx_busy (o_tx_busy ) , //output[0:0]模块忙碌标志.o_tx_pin (o_tx_pin ) , //output[0:0]发送引脚.o_rx_data (o_rx_data ) , //output[7:0]接收数据输出.o_rx_vald (o_rx_vald ) , //output[0:0]接收数据有效标志.o_rx_done (o_rx_done ) , //output[0:0]接收完成标志.o_rx_busy (o_rx_busy ) , //output[0:0]模块忙碌标志.i_rx_pin (i_rx_pin ) //input[0:0]接收引脚);
// INST_TAG_END ------ End uart_modu Template ---------
===============================================*/module uart_modu#(parameter [7:0] CLK_FRE = 50, //The clock frequency at which the module works, in MHzparameter [23:0] BAUD_RATE = 115200 //Communication baud rate
)(input wire[0:0] clk , //模块时钟,单位MHzinput wire[0:0] rst , //通信波特率input wire[0:0] i_tx_begin , //input[0:0]开始发送信号输入input wire[7:0] i_tx_data , //input[7:0]待发送数据输入output wire[0:0] o_tx_done , //output[0:0]发送完成标志输出output wire[0:0] o_tx_busy , //output[0:0]模块忙碌标志output wire[0:0] o_tx_pin , //output[0:0]发送引脚output wire[7:0] o_rx_data , //output[7:0]接收数据输出output wire[0:0] o_rx_vald , //output[0:0]接收数据有效标志output wire[0:0] o_rx_done , //output[0:0]接收完成标志output wire[0:0] o_rx_busy , //output[0:0]模块忙碌标志input wire[0:0] i_rx_pin //input[0:0]接收引脚);wire [0:0] clk_i ;wire [0:0] rst_i ;wire [0:0] tx_begin; wire [0:0] tx_data ;wire [0:0] tx_done ;wire [0:0] tx_busy ;wire [0:0] tx_pin ; wire [0:0] rx_data ;wire [0:0] rx_vald ;wire [0:0] rx_done ;wire [0:0] rx_busy ;wire [0:0] rx_pin ; assign clk_i = clk ;assign rst_i = rst ;assign tx_begin = i_tx_begin; assign tx_data = i_tx_data ;assign o_tx_done = tx_done ;assign o_tx_busy = tx_busy ;assign o_tx_pin = tx_pin ;assign o_rx_data = rx_data ;assign o_rx_done = rx_done ;assign o_rx_busy = rx_busy ;assign rx_pin = i_rx_pin ;uart_tx_modu #(.CLK_FRE (CLK_FRE ), //模块时钟,单位MHz.BAUD_RATE (BAUD_RATE ) //通信波特率
)
uart_tx_modu_u(.clk (clk_i ), //input[0:0]模块时钟输入.rst (rst_i ), //input[0:0]模块复位输入,高电平有效.tx_begin (tx_begin ), //input[0:0]开始发送信号输入.tx_data (tx_data ), //input[7:0]待发送数据输入.tx_done (tx_done ), //output[0:0]发送完成标志输出.tx_busy (tx_busy ), //output[0:0]模块忙碌标志.tx_pin (tx_pin ) //output[0:0]发送引脚);uart_rx_modu #(.CLK_FRE (CLK_FRE ), //模块时钟,单位MHz.BAUD_RATE (BAUD_RATE ) //通信波特率
)
uart_rx_modu_u(.clk (clk ), //input[0:0]模块时钟输入.rst (rst ), //input[0:0]模块复位输入,高电平有效.rx_data (rx_data ), //output[7:0]接收数据输出.rx_vald (rx_vald ), //output[0:0]接收数据有效标志.rx_done (rx_done ), //output[0:0]接收完成标志.rx_busy (rx_busy ), //output[0:0]模块忙碌标志.rx_pin (rx_pin ) //input[0:0]接收引脚);
endmodule
底层
rx_modu
/*===============================================
//----------- Begin Cut here for usrt_rx_modu Template ---//
uart_rx_modu #(.CLK_FRE (50) , //模块时钟,单位MHz.BAUD_RATE(115200) //通信波特率
)
your_instance_name(.clk (clk ), //input[0:0]模块时钟输入.rst (rst ), //input[0:0]模块复位输入,高电平有效.rx_data (rx_data ), //output[7:0]接收数据输出.rx_vald (rx_vald ), //output[0:0]接收数据有效标志.rx_done (rx_done ), //output[0:0]接收完成标志.rx_busy (rx_busy ), //output[0:0]模块忙碌标志.rx_pin (rx_pin ) //input[0:0]接收引脚);
// INST_TAG_END ------ End usrt_rx_modu Template ---------
===============================================*/module uart_rx_modu #(parameter [7:0] CLK_FRE = 50, //The clock frequency at which the module works, in MHzparameter [23:0] BAUD_RATE = 115200 //Communication baud rate
)(input wire[0:0] clk , //input[0:0]模块时钟输入input wire[0:0] rst , //input[0:0]模块复位输入,高电平有效output wire[7:0] rx_data , //output[7:0]接收数据输出output wire[0:0] rx_vald , //output[0:0]接收数据有效标志output wire[0:0] rx_done , //output[0:0]接收完成标志output wire[0:0] rx_busy , //output[0:0]模块忙碌标志input wire[0:0] rx_pin //input[0:0]接收引脚
);/*===========计算当前时钟与波特率下bit持续时钟周期==========*/localparam [15:0] BIT_CYCLE1 = CLK_FRE * 1_000_000 / BAUD_RATE;localparam [15:0] BIT_CYCLE2 = CLK_FRE * 1_000_000 / BAUD_RATE/2;
/************************************************************//*=========================定义状态=========================*/localparam [1:0] S_IDLE = 2'd0; //空闲状态localparam [1:0] S_START = 2'd1; //接收开始信号localparam [1:0] S_SEND = 2'd2; //接收数据localparam [1:0] S_STOP = 2'd3; //接收结束信号
/************************************************************//*=========================定义寄存器=========================*/wire [0:0] start ; //开始信号上升沿标志reg [1:0] start_r2 = 2'd3 ; //检测寄存器reg [2:0] now_state = 3'd0 ; //当前状态寄存器reg [2:0] nex_state = 3'd0 ; //下一状态寄存器reg [31:0] time_cnt = 32'd0 ; //bit周期计时器reg [2:0] bit_cnt = 3'd0 ; //bit计数器reg [2:0] rx_bit_reg = 3'd0 ; //reg [7:0] rx_data_reg = 8'd0 ;
/************************************************************//*=========================输出信号=========================*/assign rx_busy = (now_state == S_IDLE) ? 1'b0 : 1'b1;assign rx_done = (now_state == S_STOP && time_cnt == BIT_CYCLE2- 'd1) ? 1'b1 : 1'b0;assign rx_data = (bit_cnt == 3'd7 && time_cnt >= BIT_CYCLE2 + 'd4) ? rx_data_reg : 8'd0;assign rx_vald = (bit_cnt == 3'd7 && (time_cnt == BIT_CYCLE1 - 'd4 || time_cnt == BIT_CYCLE1 - 'd3)) ? 1'b1 : 1'b0;
/************************************************************//*=========================捕获开始信号=========================*/always@ (posedge clk)begin if(now_state == S_IDLE)start_r2 <= {start_r2[0],rx_pin};else start_r2 <= 2'd3;end assign start = start_r2[1] & ~start_r2[0];
/************************************************************//*======================bit周期计时器=======================*/always@ (posedge clk)beginif(now_state == S_IDLE)time_cnt <= 32'd0;else if(time_cnt == BIT_CYCLE1 - 1'b1 || (now_state == S_START && time_cnt == BIT_CYCLE1 - 'd2))time_cnt <= 32'd0;elsetime_cnt <= time_cnt + 1'b1;end
/************************************************************//*========================bit计数器=========================*/always@ (posedge clk)begin if(now_state != S_SEND)bit_cnt <= 3'd0;else if(time_cnt == BIT_CYCLE1 - 1'b1)bit_cnt <= bit_cnt + 1'b1;end
/************************************************************//*=================接收单bit数据并均值滤波==================*/always@ (posedge clk)begin if(now_state == S_IDLE)rx_bit_reg <= 3'd0;else if(now_state == S_SEND && time_cnt == BIT_CYCLE1 - 'd2)rx_bit_reg <= 3'd0;else if(now_state == S_SEND && (time_cnt == BIT_CYCLE2 - 'd4 || time_cnt == BIT_CYCLE2 - 'd3 || time_cnt == BIT_CYCLE2 - 'd2 || time_cnt == BIT_CYCLE2 - 'd1 || time_cnt == BIT_CYCLE2 || time_cnt == BIT_CYCLE2 + 'd1 || time_cnt == BIT_CYCLE2 + 'd2))rx_bit_reg <= rx_bit_reg + rx_pin;else rx_bit_reg <= rx_bit_reg;end
/************************************************************//*=====================寄存接收到的数据=====================*/always@ (posedge clk)begin if(now_state == S_IDLE)rx_data_reg <= 8'd0;else if(now_state == S_SEND && time_cnt == BIT_CYCLE2 + 'd4)rx_data_reg[bit_cnt] <= rx_bit_reg[2];else rx_data_reg <= rx_data_reg;end
/************************************************************//*=========================状态转换=========================*/always@ (posedge clk or posedge rst)begin if(rst)now_state <= S_IDLE;else now_state <= nex_state;end
/************************************************************//*=========================下一状态=========================*/always@ (*)begin case(now_state)S_IDLE :begin if(start)nex_state = S_START;else nex_state = S_IDLE;end S_START :begin if(time_cnt == BIT_CYCLE1 - 'd2)nex_state = S_SEND;else nex_state = S_START;end S_SEND :begin if(time_cnt == BIT_CYCLE1 - 1'b1 && bit_cnt == 3'd7)nex_state = S_STOP;else nex_state = S_SEND;end S_STOP :begin if(time_cnt == BIT_CYCLE2)nex_state = S_IDLE;else nex_state = S_STOP;end default :nex_state = S_IDLE;endcaseend
/************************************************************/
endmodule
tx_modu
/*===============================================
//----------- Begin Cut here for uart_tx_modu Template ---//
uart_tx_modu #(.CLK_FRE (50) , //模块时钟,单位MHz.BAUD_RATE(115200) //通信波特率
)
your_instance_name(.clk (clk ), //input[0:0]模块时钟输入.rst (rst ), //input[0:0]模块复位输入,高电平有效.tx_begin (tx_begin ), //input[0:0]开始发送信号输入.tx_data (tx_data ), //input[7:0]待发送数据输入.tx_done (tx_done ), //output[0:0]发送完成标志输出.tx_busy (tx_busy ), //output[0:0]模块忙碌标志.tx_pin (tx_pin ) //output[0:0]发送引脚);
// INST_TAG_END ------ End uart_tx_modu Template ---------
===============================================*/module uart_tx_modu#(parameter [7:0] CLK_FRE = 50, //The clock frequency at which the module works, in MHzparameter [23:0] BAUD_RATE = 115200 //Communication baud rate
)(input wire[0:0] clk , //input[0:0]模块时钟输入input wire[0:0] rst , //input[0:0]模块复位输入,高电平有效input wire[0:0] tx_begin , //input[0:0]开始发送信号输入input wire[7:0] tx_data , //input[7:0]待发送数据输入output wire[0:0] tx_done , //output[0:0]发送完成标志输出output wire[0:0] tx_busy , //output[0:0]模块忙碌标志output wire[0:0] tx_pin //output[0:0]发送引脚
);/*===========计算当前时钟与波特率下bit持续时钟周期==========*/localparam [15:0] BIT_CYCLE = CLK_FRE * 1_000_000 / BAUD_RATE;
/************************************************************//*=========================定义状态=========================*/localparam [1:0] S_IDLE = 2'd0; //空闲状态localparam [1:0] S_START = 2'd1; //发送开始信号localparam [1:0] S_SEND = 2'd2; //发送数据localparam [1:0] S_STOP = 2'd3; //发送结束信号
/************************************************************//*========================定义寄存器========================*/reg [1:0] start_r2 = 2'd0 ; //开始信号缓存器wire [0:0] start ; //开始信号上升沿标志reg [2:0] now_state = 3'd0 ; //当前状态寄存器reg [2:0] nex_state = 3'd0 ; //下一状态寄存器reg [31:0] time_cnt = 32'd0 ; //bit周期计时器reg [2:0] bit_cnt = 3'd0 ; //bit计数器reg [7:0] tx_data_reg = 8'd0 ; //待发送数据寄存器reg [0:0] tx_reg = 1'd1 ; //待发送bit寄存器
/************************************************************//*===================-=====输出端口=========================*/assign tx_done = (now_state == S_STOP && time_cnt == BIT_CYCLE-1) ? 1'b1 : 1'b0;assign tx_busy = (now_state == S_IDLE) ? 1'b0 : 1'b1;assign tx_pin = (now_state == S_IDLE) ? 1'b1 : tx_reg;
/************************************************************//*====================产生开始信号上升沿====================*/always@ (posedge clk)begin if(now_state == S_IDLE)start_r2 <= {start_r2[0],tx_begin};elsestart_r2 <= 2'd0;end assign start = ~start_r2[1] & start_r2[0];
/************************************************************//*======================bit周期计时器=======================*/always@ (posedge clk)beginif(now_state == S_IDLE)time_cnt <= 32'd0;else if(time_cnt == BIT_CYCLE - 1'b1)time_cnt <= 32'd0;elsetime_cnt <= time_cnt + 1'b1;end
/************************************************************//*========================bit计数器=========================*/always@ (posedge clk)begin if(now_state != S_SEND)bit_cnt <= 3'd0;else if(time_cnt == BIT_CYCLE - 1'b1)bit_cnt <= bit_cnt + 1'b1;end
/************************************************************//*======================寄存待发送数据======================*/always@ (posedge clk)begin if(now_state == S_IDLE && nex_state == S_IDLE)tx_data_reg <= 8'd0;else if(now_state == S_IDLE && nex_state != S_IDLE)tx_data_reg <= tx_data;else tx_data_reg <= tx_data_reg;end
/************************************************************//*=========================产生输出=========================*/always@ (posedge clk)begin if(now_state == S_IDLE)tx_reg <= 1'b1;else if(now_state == S_START)tx_reg <= 1'b0;else if(now_state == S_SEND)tx_reg <= tx_data_reg[bit_cnt];else if(now_state == S_STOP)tx_reg <= 1'b1;end
/************************************************************//*=========================状态切换=========================*/always@ (posedge clk or posedge rst)begin if(rst)now_state <= S_IDLE;else now_state <= nex_state;end
/************************************************************//*=======================产生下一状态=======================*/always@ (*)begin case(now_state)S_IDLE :begin if(start)nex_state = S_START;else nex_state = S_IDLE;endS_START :begin if(time_cnt == BIT_CYCLE - 1'b1)nex_state = S_SEND;else nex_state = S_START;endS_SEND :begin if(time_cnt == BIT_CYCLE - 1'b1 && bit_cnt == 3'd7)nex_state = S_STOP;else nex_state = S_SEND;endS_STOP :begin if(time_cnt == BIT_CYCLE - 1'b1)nex_state = S_IDLE;else nex_state = S_STOP;enddefault :begin nex_state = S_IDLE; endendcaseend
/************************************************************/
endmodule
结束语
本人刚刚入坑FPGA 不久,在代码风格,设计逻辑上还有很多不足之处。欢迎各位大佬指出我的不住之处。
基于verlog语言的UART通信协议模块实现相关推荐
- 基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结
基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结 uart通信协议简单理解为串转并和并转串的两个模块.同时必须保证数据的正确性.且输入输出端为串行. 此次实现uar ...
- 频率统计表用c语言_空间矢量脉宽调制建模与仿真(基于C语言的SIMULINK仿真模型 | 基于SVPWM模块的仿真)...
文末有仿真模型下载方式 1.1 基于C语言的SIMULINK仿真模型 使用C语言在MATLAB/SIMULINK中仿真,需要借助s-function builder模块实现.七段式SVPWM仿真模型如 ...
- 基于FPGA实现uart串口模块(Verilog)--------发送模块及整合
基于FPGA实现uart串口模块(Verilog)--------发送模块及整合 当接收模块接收到数据后,需要重新发送形成回环验证模块正确性.思路和结束模块有一点点的小差异.接收模块最终输出的是一个并 ...
- 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)
本文转载,其来源在参考中:1,稍加修改,因为近期使用到这个模块,故而加以整理! 1.平台 首先我使用的是 奋斗 STM32 开发板 MINI板 基于STM32单片机光学指纹识别模块(FPM10A)全教 ...
- 基于SIMULINK的空间矢量脉宽调制SVPWM的建模与仿真(基于C语言的SIMULINK仿真模型 | 基于SVPWM模块的仿真)
文中涉及的仿真模型可在公众号 iFTrue未来已来 中获取: 请扫描下方二维码关注微信公众号:iFTrue 未来已来 在公众号后台回复以下关键字获取SVPWM仿真模型:SVPWM模型 「 iFTrue ...
- 人工智能-推荐系统-模块01:离线统计模块【使用SparkSQL(基于Scala语言/Python语言)进行离线统计分析:历史热门商品统计、近期热门商品统计、商品平均评分统计...】
一.基于scala语言的SparkSQL离线统计分析 1.将数据导入MongoDB数据库 DataLoader.scala import com.mongodb.casbah.commons.Mong ...
- java毕业设计——基于Java+sqlserver的通用安全模块设计与实现(毕业论文+程序源码)——安全模块
基于Java+sqlserver的通用安全模块设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于Java+sqlserver的通用安全模块设计与实现,文章末尾附有本毕业设计的论文和源码下载地 ...
- 基于Erlang语言的视频相似推荐系统 | 深度
作者丨gongyouliu 来源 | 转载自大数据与人工智能(ID:ai-big-data) [导语]:作者在上一篇文章<基于内容的推荐算法>中介绍了基于内容的推荐算法的实现原理.在本篇文 ...
- 基于python的界面自动化测试-基于Python语言的自动化测试实战第二章(上)
原标题:基于Python语言的自动化测试实战第二章(上) 测试环境搭建 2.1 Windows 下的环境搭建 如果想要学习一门编程语言,对于新手来说只需到其官方网站上去下载最新版本安装即可,但对于想要 ...
最新文章
- C++ Primer 5th笔记(chap 13 拷贝控制)交换操作
- Luogu P3321 [SDOI2015]序列统计
- 卸载linux 上Java的正确方式
- java方法生命周期_java – Servlet的生命周期及其方法
- 剑指-二维数组中的查找
- 1.App瘦身经验总结
- 【java】java JVM问题定位的典型案例分析 笔记 finalizer
- Ayla 物联网平台全面支持主流智能语音系统
- 使用LINQ to SQL更新数据库(中):几种解决方案
- 《数据算法:Hadoop_Spark大数据处理技巧》艾提拉笔记.docx 第1章二次排序:简介 19 第2章二次排序:详细示例 42 第3章 Top 10 列表 54 第4章左外连接 96 第5
- Windows程序设计--起步
- 中国范围NPP-VIIRS逐年夜间灯光数据(2013-2020年)
- SMART原则助你设定有效目标
- 正则验证汽车车牌号,包括新能源
- 进击的Objective-C -------------------NSSting,NSSMutableString和NSArray,NSMutableArray
- java普通分隔符,懂得java的文件4种分隔符
- C# 通过UDP 远程监控摄像头
- HashMap集合(高级)
- Hadoop经典案例——单词统计
- Odoo权限详解一张图