前言

在此我就不对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通信协议模块实现相关推荐

  1. 基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结

    基于FPGA实现uart串口模块(Verilog)--------接收模块及思路总结 uart通信协议简单理解为串转并和并转串的两个模块.同时必须保证数据的正确性.且输入输出端为串行. 此次实现uar ...

  2. 频率统计表用c语言_空间矢量脉宽调制建模与仿真(基于C语言的SIMULINK仿真模型 | 基于SVPWM模块的仿真)...

    文末有仿真模型下载方式 1.1 基于C语言的SIMULINK仿真模型 使用C语言在MATLAB/SIMULINK中仿真,需要借助s-function builder模块实现.七段式SVPWM仿真模型如 ...

  3. 基于FPGA实现uart串口模块(Verilog)--------发送模块及整合

    基于FPGA实现uart串口模块(Verilog)--------发送模块及整合 当接收模块接收到数据后,需要重新发送形成回环验证模块正确性.思路和结束模块有一点点的小差异.接收模块最终输出的是一个并 ...

  4. 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)

    本文转载,其来源在参考中:1,稍加修改,因为近期使用到这个模块,故而加以整理! 1.平台 首先我使用的是 奋斗 STM32 开发板 MINI板 基于STM32单片机光学指纹识别模块(FPM10A)全教 ...

  5. 基于SIMULINK的空间矢量脉宽调制SVPWM的建模与仿真(基于C语言的SIMULINK仿真模型 | 基于SVPWM模块的仿真)

    文中涉及的仿真模型可在公众号 iFTrue未来已来 中获取: 请扫描下方二维码关注微信公众号:iFTrue 未来已来 在公众号后台回复以下关键字获取SVPWM仿真模型:SVPWM模型 「 iFTrue ...

  6. 人工智能-推荐系统-模块01:离线统计模块【使用SparkSQL(基于Scala语言/Python语言)进行离线统计分析:历史热门商品统计、近期热门商品统计、商品平均评分统计...】

    一.基于scala语言的SparkSQL离线统计分析 1.将数据导入MongoDB数据库 DataLoader.scala import com.mongodb.casbah.commons.Mong ...

  7. java毕业设计——基于Java+sqlserver的通用安全模块设计与实现(毕业论文+程序源码)——安全模块

    基于Java+sqlserver的通用安全模块设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于Java+sqlserver的通用安全模块设计与实现,文章末尾附有本毕业设计的论文和源码下载地 ...

  8. 基于Erlang语言的视频相似推荐系统 | 深度

    作者丨gongyouliu 来源 | 转载自大数据与人工智能(ID:ai-big-data) [导语]:作者在上一篇文章<基于内容的推荐算法>中介绍了基于内容的推荐算法的实现原理.在本篇文 ...

  9. 基于python的界面自动化测试-基于Python语言的自动化测试实战第二章(上)

    原标题:基于Python语言的自动化测试实战第二章(上) 测试环境搭建 2.1 Windows 下的环境搭建 如果想要学习一门编程语言,对于新手来说只需到其官方网站上去下载最新版本安装即可,但对于想要 ...

最新文章

  1. C++ Primer 5th笔记(chap 13 拷贝控制)交换操作
  2. Luogu P3321 [SDOI2015]序列统计
  3. 卸载linux 上Java的正确方式
  4. java方法生命周期_java – Servlet的生命周期及其方法
  5. 剑指-二维数组中的查找
  6. 1.App瘦身经验总结
  7. 【java】java JVM问题定位的典型案例分析 笔记 finalizer
  8. Ayla 物联网平台全面支持主流智能语音系统
  9. 使用LINQ to SQL更新数据库(中):几种解决方案
  10. 《数据算法:Hadoop_Spark大数据处理技巧》艾提拉笔记.docx 第1章二次排序:简介 19 第2章二次排序:详细示例 42 第3章 Top 10 列表 54 第4章左外连接 96 第5
  11. Windows程序设计--起步
  12. 中国范围NPP-VIIRS逐年夜间灯光数据(2013-2020年)
  13. SMART原则助你设定有效目标
  14. 正则验证汽车车牌号,包括新能源
  15. 进击的Objective-C -------------------NSSting,NSSMutableString和NSArray,NSMutableArray
  16. java普通分隔符,懂得java的文件4种分隔符
  17. C# 通过UDP 远程监控摄像头
  18. HashMap集合(高级)
  19. Hadoop经典案例——单词统计
  20. Odoo权限详解一张图

热门文章

  1. 使用Matlab hist函数大体估计一组随机数的概率分布
  2. 名画87 刘松年《罗汉图七幅》
  3. TP-LINK路由端口映射图文教程 【路由器建主】
  4. Python练习--字符串的操作习题
  5. rTorrent使用方法
  6. 【NLP】基于GAN的文本生成综述
  7. C语言 经典结论题第一篇
  8. 找工作之深信服科技笔试
  9. 哪个洗脱一体机好用?性能好洗地机排名
  10. Ubuntu 20.04 服务器的R中安装 Rtools / devtools