09 AB 10串口通信发送原理

news2024/9/25 9:13:02

        通用异步收发传输器( Universal Asynchronous Receiver/Transmitter, UART)是一种异步收发传输器,其在数据发送时将并行数据转换成串行数据来传输, 在数据接收时将接收到的串行数据转换成并行数据, 可以实现全双工传输和接收。它包括了 RS232、 RS449、 RS423、RS422 和 RS485 等接口标准规范和总线标准规范。 换句话说, UART 是异步串行通信的总称。而 RS232、 RS449、 RS423、 RS422 和 RS485 等,是对应各种异步串行通信口的接口标准和总线标准,它们规定了通信口的电气特性、传输速率、连接特性和接口的机械特性等内容。

1. 09AB 基于FPGA的串口(UART)发送实验

  1. 串口通信模块设计的目的是用来发送数据的,因此需要有一个数据输入端口。
  2. 串口通信,支持不同的波特率,所以需要有一个波特率设置端口。
  3. 串口通信的本质就是将8位的并行数据,在不同的时刻传输并行数据的不同位,通过一根信号线将八位并行数据全部传出。
  4. 串口通信以1位的低电平标志串行传输的开始,待8位数据传输完成之后,再以1位的高电平标志传输的结束。
  5. 控制信号,控制并转串模块什么时候开始工作,什么时候一个数据发送完成?所以需要一个发送开始信号,以及一个发送完成信号

设计代码

  1. bps_cnt在空闲状态下保持为0,而bps_cnt为0会使得uart_tx为0,为了解决该问题,我们避开空闲状态下的bps_cnt=0,使bps_cnt从1开始判定。
  2. 但是这又会导致bps_cnt从0到1存在空闲,发送起始位时会延后一段数据位,于是我们将基础计数时间改为1时counter1开始加一。
  3. 为了出现bps_clk脉冲信号,当(div_cnt == (bps_dr - 1)成立时会输出1,我们利用该特性作为我们的脉冲信号。
  4. 我们要输入八位数据以及起始位和终止位共十位数据,为了保证十位数据完整输出,我们需要设置到第十一位停止,发送tx_done信号。
  5. 输入信号不能是reg类型,否则综合设计代码时报错:Non-net port key_in cannot be of mode input,写代码时遇到的问题。
module uart_byte_tx(
    clk,
    rstn,
    blaud_set,
    data,
    send_en,
    uart_tx,
    tx_done
);
    
    input clk;
    input rstn;
    input [2:0]blaud_set;
    input [7:0]data;
    input send_en;
    output reg uart_tx;
    output tx_done;
    
    //Blaud_set = 0时,波特率 = 9600;
    //Blaud_set = 1时,波特率 = 19200;
    //Blaud_set = 2时,波特率 = 38400;
    //Blaud_set = 3时,波特率 = 57600;
    //Blaud_set = 4时,波特率 = 115200;
    
    reg[17:0] bps_dr;
    always@(*)
        case(blaud_set)
            0: bps_dr = 1000000000/9600/20;
            1: bps_dr = 1000000000/19200/20;
            2: bps_dr = 1000000000/38400/20;
            3: bps_dr = 1000000000/57600/20;
            4: bps_dr = 1000000000/115200/20;
        endcase
    
    wire bps_clk;
    assign bps_clk = (div_cnt == (bps_dr - 1)); //3.为了出现bps_clk脉冲信号

    reg[17:0] div_cnt;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(send_en)begin
        if(bps_clk)
            div_cnt <= 0;
        else
            div_cnt <= div_cnt + 1'd1;
    end
    else
        div_cnt <= 0;    
    
    reg[3:0] bps_cnt;    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        bps_cnt <= 0;
    else if(send_en)begin
        if(bps_cnt == 11)
            bps_cnt <= 0;
        else if(div_cnt == 1) //注意2
            bps_cnt <= bps_cnt + 4'd1;
    end
    else
        bps_cnt <= 0;
    
    reg tx_done;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        uart_tx <= 1'd1;
    else 
        case(bps_cnt)
            1: begin uart_tx <= 1'd0; tx_done <= 0; end //注意1
            2: uart_tx <= data[0];
            3: uart_tx <= data[1];
            4: uart_tx <= data[2];
            5: uart_tx <= data[3];
            6: uart_tx <= data[4];
            7: uart_tx <= data[5];
            8: uart_tx <= data[6];
            9: uart_tx <= data[7];
            10: uart_tx <= 1'd1;
            11: begin uart_tx <= 1'd1; tx_done <= 1; end //注意4
            default: uart_tx <= 1'd1;
        endcase
 
endmodule

仿真代码:

`timescale 1ns/1ns

module uart_byte_tx_tb();
    
    reg clk;
    reg rstn;
    reg [2:0] blaud_set;
    reg [7:0] data;
    reg send_en;
    wire uart_tx;
    wire tx_done;    
    
    uart_byte_tx uart_byte_tx_inst(
        .clk(clk),
        .rstn(rstn),
        .blaud_set(blaud_set),
        .data(data),
        .send_en(send_en),
        .uart_tx(uart_tx),
        .tx_done(tx_done)
    );
    
    initial clk = 1;
    always #10 clk = ~clk;
    
    initial begin
        rstn = 0;
        data = 0;
        send_en = 0;
        blaud_set = 4;
        #201;
        rstn = 1;
        #100
        data = 8'h57;
        send_en = 1;
        #20;
        @(posedge tx_done);
        send_en = 0;
        #20000;
        data = 8'h75;
        send_en = 1;
        #20;
        @(posedge tx_done);
        #20000;
        send_en = 0;
        $stop;
    
    end

endmodule

仿真波形

2. 10 串口发送应用之发送数据

使用上一节课设计的串口发送模块,设计一个数据发送器,每10ms以115200的波特率发送一个数据,每次发送的数据比前一个数据大一(计数器)。

在实际应用的时候,我们不能通过counter去控制data,只能通过控制信号去控制。要求就是通过tx_done和send_en这两个控制信号,控制我要发送的数据内容。

思路:通过顶层模块调用uart_byte_tx发送模块来发送数据,将顶层模块命名为uart_tx_test。

 设计代码(第一版,不完善)

2.1 直接使用上一节的uart_byte_tx模块:

module uart_tx_test(
    clk,
    rstn,
    uart_tx
);

    input clk;
    input rstn;
    output uart_tx;
    
    reg [7:0] data;
    reg send_en;
    uart_byte_tx uart_byte_tx_inst(
        .clk(clk),
        .rstn(rstn),
        .blaud_set(3'd4),
        .data(data),
        .send_en(send_en),
        .uart_tx(uart_tx),
        .tx_done(tx_done)
    );
         
    //10ms周期计数器
    reg [18:0] counter;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        counter <= 0;
    else if(counter == 499999)
        counter <= 0;
    else
        counter <= counter + 1'd1;
      
    always@(posedge clk or negedge rstn)
    if(!rstn)
        send_en <= 0;
    else if(counter == 0)
        send_en <= 1;
    else if(tx_done)
        send_en <= 0;
        
    always@(posedge clk or negedge rstn)
    if(!rstn)
        data <= 8'b0000_0000;
    else if(tx_done)
        data <= data + 1'd1;

    
endmodule
module uart_byte_tx(
    clk,
    rstn,
    blaud_set,
    data,
    send_en,
    uart_tx,
    tx_done
);
    
    input clk;
    input rstn;
    input [2:0]blaud_set;
    input [7:0]data;
    input send_en;
    output reg uart_tx;
    output tx_done;
    
    //Blaud_set = 0时,波特率 = 9600;
    //Blaud_set = 1时,波特率 = 19200;
    //Blaud_set = 2时,波特率 = 38400;
    //Blaud_set = 3时,波特率 = 57600;
    //Blaud_set = 4时,波特率 = 115200;
    
    reg[17:0] bps_dr;
    always@(*)
        case(blaud_set)
            0: bps_dr = 1000000000/9600/20;
            1: bps_dr = 1000000000/19200/20;
            2: bps_dr = 1000000000/38400/20;
            3: bps_dr = 1000000000/57600/20;
            4: bps_dr = 1000000000/115200/20;
        endcase
    
    wire bps_clk;
    assign bps_clk = (div_cnt == (bps_dr - 1)); 

    reg[17:0] div_cnt;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(send_en)begin
        if(bps_clk)
            div_cnt <= 0;
        else
            div_cnt <= div_cnt + 1'd1;
    end
    else
        div_cnt <= 0;    
    
    reg[3:0] bps_cnt;    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        bps_cnt <= 0;
    else if(send_en)begin
        if(bps_cnt == 11)
            bps_cnt <= 0;
        else if(div_cnt == 1) 
            bps_cnt <= bps_cnt + 4'd1;
    end
    else
        bps_cnt <= 0;
    
    reg tx_done;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        uart_tx <= 1'd1;
    else 
        case(bps_cnt) //不完善
            1: begin uart_tx <= 1'd0; tx_done <= 0; end 
            2: uart_tx <= data[0];
            3: uart_tx <= data[1];
            4: uart_tx <= data[2];
            5: uart_tx <= data[3];
            6: uart_tx <= data[4];
            7: uart_tx <= data[5];
            8: uart_tx <= data[6];
            9: uart_tx <= data[7];
            10: uart_tx <= 1'd1;
            11: begin uart_tx <= 1'd1; tx_done <= 1; end
            default: uart_tx <= 1'd1;
        endcase
 
endmodule

仿真代码

`timescale 1ns / 1ps

module uart_tx_test_tb();
    
    reg clk;
    reg rstn;
    wire uart_tx;
    
    uart_tx_test uart_tx_test_inst(
        .clk(clk),
        .rstn(rstn),
        .uart_tx(uart_tx)
    );
    
    initial clk = 1;
    always #10 clk = ~clk;
    
    initial begin
        rstn = 0;
        #201;
        rstn = 1;
        #200000000
        $stop;
    end

endmodule

仿真波形

data确实在一直加一,但是data并未发出(uart_tx一直保持为1)

2.2 修改tx_done逻辑后(能运行)

设计代码

module uart_tx_test(
    clk,
    rstn,
    uart_tx
);

    input clk;
    input rstn;
    output uart_tx;
    
    reg [7:0] data;
    reg send_en;
    uart_byte_tx uart_byte_tx_inst(
        .clk(clk),
        .rstn(rstn),
        .blaud_set(3'd4),
        .data(data),
        .send_en(send_en),
        .uart_tx(uart_tx),
        .tx_done(tx_done)
    );
         
    //10ms周期计数器
    reg [18:0] counter;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        counter <= 0;
    else if(counter == 499999)
        counter <= 0;
    else
        counter <= counter + 1'd1;
      
    always@(posedge clk or negedge rstn)
    if(!rstn)
        send_en <= 0;
    else if(counter == 0)
        send_en <= 1;
    else if(tx_done)
        send_en <= 0;
        
    always@(posedge clk or negedge rstn)
    if(!rstn)
        data <= 8'b0000_0000;
    else if(tx_done)
        data <= data + 1'd1;

    
endmodule
module uart_byte_tx(
    clk,
    rstn,
    blaud_set,
    data,
    send_en,
    uart_tx,
    tx_done
);
    
    input clk;
    input rstn;
    input [2:0]blaud_set;
    input [7:0]data;
    input send_en;
    output reg uart_tx;
    output tx_done;
    
    //Blaud_set = 0时,波特率 = 9600;
    //Blaud_set = 1时,波特率 = 19200;
    //Blaud_set = 2时,波特率 = 38400;
    //Blaud_set = 3时,波特率 = 57600;
    //Blaud_set = 4时,波特率 = 115200;
    
    reg[17:0] bps_dr;
    always@(*)
        case(blaud_set)
            0: bps_dr = 1000000000/9600/20;
            1: bps_dr = 1000000000/19200/20;
            2: bps_dr = 1000000000/38400/20;
            3: bps_dr = 1000000000/57600/20;
            4: bps_dr = 1000000000/115200/20;
        endcase
    
    wire bps_clk;
    assign bps_clk = (div_cnt == 1);
    reg[17:0] div_cnt;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(send_en)begin
        if(div_cnt == (bps_dr - 1))
            div_cnt <= 0;
        else
            div_cnt <= div_cnt + 1'd1;
    end
    else
        div_cnt <= 0;    
    
    reg[3:0] bps_cnt;    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        bps_cnt <= 0;
    else if(send_en)begin
        if(bps_cnt == 11)
            bps_cnt <= 0;
        else if(div_cnt == 1)
            bps_cnt <= bps_cnt + 4'd1;
    end
    else
        bps_cnt <= 0;
    
    reg tx_done;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        uart_tx <= 1'd1;
    else 
        case(bps_cnt)
            0: tx_done <= 0;
            1: uart_tx <= 1'd0;
            2: uart_tx <= data[0];
            3: uart_tx <= data[1];
            4: uart_tx <= data[2];
            5: uart_tx <= data[3];
            6: uart_tx <= data[4];
            7: uart_tx <= data[5];
            8: uart_tx <= data[6];
            9: uart_tx <= data[7];
            10: uart_tx <= 1'd1;
            11: begin uart_tx <= 1'd1; tx_done <= 1; end
            default: uart_tx <= 1'd1;
        endcase
 
endmodule

仿真波形

 

2.3 完善串口模块,使其能接入数据采集模块

  • 数据采集模块data_gen,每采集到一个数据data result[7:0],会产生一个data_done的脉冲信号,uart串口在就接收到data_done的脉冲信号后会将data result[7:0]发送出去。
  • 思路:我们可以利用脉冲信号data_done来使能我们的send_en信号,然后将接收到的data result[7:0]通过串口发送
  • 为了模拟这个过程,我们让顶层uart_tx_test每隔10ms产生一个data[7:0]和一个send_go的单脉冲信号发送给uart_byte_tx模块。让uart_byte_tx模块根据send_go脉冲信号去发数据即可。
  • 为了防止数据发送途中data发生变化,我们在接收到send_go信号后,先将data存储起来,即声明一个r_data[7:0],使将data[7:0]的值赋值给r_data[7:0]。

 

 设计代码

module uart_tx_test1(
    clk,
    rstn,
    uart_tx
);

    input clk;
    input rstn;
    output uart_tx;
    
    reg [7:0] data;
    reg send_go;
    uart_byte_tx uart_byte_tx_inst(
        .clk(clk),
        .rstn(rstn),
        .blaud_set(3'd4),
        .data(data),
        .send_go(send_go),
        .uart_tx(uart_tx),
        .tx_done(tx_done)
    );
         
    //10ms周期计数器
    reg [18:0] counter;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        counter <= 0;
    else if(counter == 499999)
        counter <= 0;
    else
        counter <= counter + 1'd1;
      
    always@(posedge clk or negedge rstn)
    if(!rstn)
        send_go <= 0;
    else if(counter == 0)
        send_go <= 1;
    else
        send_go <= 0;
        
    always@(posedge clk or negedge rstn)
    if(!rstn)
        data <= 8'b0000_0000;
    else if(tx_done)
        data <= data + 1'd1;

    
endmodule
module uart_byte_tx(
    clk,
    rstn,
    blaud_set,
    data,
    send_go,
    uart_tx,
    tx_done
);
    
    input clk;
    input rstn;
    input [2:0]blaud_set;
    input [7:0]data;
    input send_go;
    output reg uart_tx;
    output tx_done;
    
    //Blaud_set = 0时,波特率 = 9600;
    //Blaud_set = 1时,波特率 = 19200;
    //Blaud_set = 2时,波特率 = 38400;
    //Blaud_set = 3时,波特率 = 57600;
    //Blaud_set = 4时,波特率 = 115200;
    
    reg[17:0] bps_dr;
    always@(*)
        case(blaud_set)
            0: bps_dr = 1000000000/9600/20;
            1: bps_dr = 1000000000/19200/20;
            2: bps_dr = 1000000000/38400/20;
            3: bps_dr = 1000000000/57600/20;
            4: bps_dr = 1000000000/115200/20;
        endcase
        
    reg [7:0] r_data;
    always@(posedge clk)
    if(send_go)
        r_data <= data;
    else
        r_data <= r_data;
        
    reg send_en;  
    always@(posedge clk or negedge rstn)
    if(!rstn)
        send_en <= 0;
    else if(send_go)
        send_en <= 1;
    else if(tx_done)
        send_en <= 0;
        
    
    wire bps_clk;
    assign bps_clk = (div_cnt == 1);
    reg[17:0] div_cnt;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(send_en)begin
        if(div_cnt == (bps_dr - 1))
            div_cnt <= 0;
        else
            div_cnt <= div_cnt + 1'd1;
    end
    else
        div_cnt <= 0;    
    
    reg[3:0] bps_cnt;    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        bps_cnt <= 0;
    else if(send_en)begin
        if(bps_cnt == 11)
            bps_cnt <= 0;
        else if(div_cnt == 1)
            bps_cnt <= bps_cnt + 4'd1;
    end
    else
        bps_cnt <= 0;
    
    reg tx_done;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        uart_tx <= 1'd1;
    else 
        case(bps_cnt)
            0: tx_done <= 0;
            1: uart_tx <= 1'd0;
            2: uart_tx <= r_data[0];
            3: uart_tx <= r_data[1];
            4: uart_tx <= r_data[2];
            5: uart_tx <= r_data[3];
            6: uart_tx <= r_data[4];
            7: uart_tx <= r_data[5];
            8: uart_tx <= r_data[6];
            9: uart_tx <= r_data[7];
            10: uart_tx <= 1'd1;
            11: begin uart_tx <= 1'd1; tx_done <= 1; end
            default: uart_tx <= 1'd1;
        endcase
 
endmodule

仿真代码

`timescale 1ns / 1ps

module uart_tx_test_tb();
    
    reg clk;
    reg rstn;
    wire uart_tx;
    
    uart_tx_test1 uart_tx_test_inst(
        .clk(clk),
        .rstn(rstn),
        .uart_tx(uart_tx)
    );
    
    initial clk = 1;
    always #10 clk = ~clk;
    
    initial begin
        rstn = 0;
        #201;
        rstn = 1;
        #200000000
        $stop;
    end

endmodule

仿真波形

 在开发板上跑程序

调试结果:确实按照每100ms法发一个数据

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

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

相关文章

【数据分享】1929-2023年全球站点的逐年平均降水量(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;说到常用的降水数据&#xff0c;最详细的降水数据是具体到气象监测站点的降水数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全…

训练集,验证集,测试集比例

三者的区别 训练集&#xff08;train set&#xff09; —— 用于模型拟合的数据样本。验证集&#xff08;validation set&#xff09;—— 是模型训练过程中单独留出的样本集&#xff0c;它可以用于调整模型的超参数和用于对模型的能力进行初步评估。 通常用来在模型迭代训练时…

DevOps落地笔记-17|度量指标:寻找真正的好指标?

前面几个课时端到端地介绍了软件开发全生命周期中涉及的最佳实践&#xff0c;经过上面几个步骤&#xff0c;企业在进行 DevOps 转型时技术方面的问题解决了&#xff0c;这个时候我们还缺些什么呢&#xff1f;事实上很多团队和组织在实施 DevOps 时都专注于技术&#xff0c;而忽…

【力扣】查找总价格为目标值的两个商品,双指针法

查找总价格为目标值的两个商品原题地址 方法一&#xff1a;双指针 这道题和力扣第一题“两数之和”非常像&#xff0c;区别是这道题已经把数组排好序了&#xff0c;所以不考虑暴力枚举和哈希集合的方法&#xff0c;而是利用单调性&#xff0c;使用双指针求解。 考虑数组pric…

零代码3D可视化快速开发平台

老子云平台 老子云3D可视化快速开发平台&#xff0c;集云压缩、云烘焙、云存储云展示于一体&#xff0c;使3D模型资源自动输出至移动端PC端、Web端&#xff0c;能在多设备、全平台进行展示和交互&#xff0c;是全球领先、自主可控的自动化3D云引擎。此技术已经在全球申请了专利…

力扣优选算法100道——【模板】前缀和(一维)

【模板】前缀和_牛客题霸_牛客网 (nowcoder.com) 目录 &#x1f6a9;了解题意 &#x1f6a9;算法原理 &#x1f388;设定下标为1开始 &#x1f388;取值的范围 &#x1f6a9;实现代码 &#x1f6a9;了解题意 第一行的3和2&#xff0c;3代表行数&#xff0c;2代表q次查询(…

【Java数据结构】ArrayList和LinkedList的遍历

一&#xff1a;ArrayList的遍历 import java.util.ArrayList; import java.util.Iterator; import java.util.List;/*** ArrayList的遍历*/ public class Test {public static void main(String[] args) {List<Integer> list new ArrayList<>();list.add(5);list…

MATLAB环境下生成对抗网络系列(11种)

为了构建有效的图像深度学习模型&#xff0c;数据增强是一个非常行之有效的方法。图像的数据增强是一套使用有限数据来提高训练数据集质量和规模的数据空间解决方案。广义的图像数据增强算法包括&#xff1a;几何变换、颜色空间增强、核滤波器、混合图像、随机擦除、特征空间增…

寒假作业2024.2.6

1.现有无序序列数组为23,24,12,5,33,5347&#xff0c;请使用以下排序实现编程 函数1:请使用冒泡排序实现升序排序 函数2:请使用简单选择排序实现升序排序 函数3:请使用直接插入排序实现升序排序 函数4:请使用插入排序实现升序排序 #include <stdio.h> #include <stdl…

一个坐标系查询网站python获取所有坐标系

技术路线选择 我是使用的vue 3开发的网页界面&#xff0c;element-plus构建网页组件&#xff0c;openlayer展示地图&#xff0c;express提供后端API&#xff0c;vercel进行在线部署。 python获取所有坐标系 想要展示所有坐标系&#xff0c;那需要先获取坐标系&#xff0c;怎么…

【开源】基于JAVA+Vue+SpringBoot的贫困地区人口信息管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 人口信息管理模块2.2 精准扶贫管理模块2.3 特殊群体管理模块2.4 案件信息管理模块2.5 物资补助模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 人口表3.2.2 扶贫表3.2.3 特殊群体表3.2.4 案件表3.2.5 物资补助表 四…

机器人学、机器视觉与控制 上机笔记(2.1章节)

机器人学、机器视觉与控制 上机笔记&#xff08;2.1章节&#xff09; 1、前言2、本篇内容3、代码记录3.1、新建se23.2、生成坐标系3.3、将T1表示的变换绘制3.4、完整绘制代码3.5、获取点*在坐标系1下的表示3.6、相对坐标获取完整代码 4、结语 1、前言 工作需要&#xff0c;想同…

HTTP协议笔记

HTTP协议笔记 参考&#xff1a; &#xff08;建议精读&#xff09;HTTP灵魂之问&#xff0c;巩固你的 HTTP 知识体系 《透视 HTTP 协议》——chrono 目录&#xff1a; 1、说说你对HTTP的了解吧。  1. HTTP状态码。  2. HTTP请求头和响应头&#xff0c;其中包括cookie、跨域响…

AcWing 1238 日志统计(双指针算法)

题目概述 小明维护着一个程序员论坛。现在他收集了一份”点赞”日志&#xff0c;日志共有 N 行。 其中每一行的格式是&#xff1a; ts id表示在 ts 时刻编号 id 的帖子收到一个”赞”。 现在小明想统计有哪些帖子曾经是”热帖”。 如果一个帖子曾在任意一个长度为 D 的时间段…

《MySQL 简易速速上手小册》第1章:MySQL 基础和安装(2024 最新版)

文章目录 1.1 MySQL 概览&#xff1a;版本、特性和生态系统1.1.1 基础知识1.1.2 重点案例1.1.3 拓展案例 1.2 安装和配置 MySQL1.2.1 基础知识1.2.2 安装步骤1.2.3 重点案例1.2.4 拓展案例 1.3 基础命令和操作1.3.1 基础知识1.3.2 重点案例1.3.3 拓展案例 1.1 MySQL 概览&#…

JUC ThreadLocal

文章目录 ThreadLocal ^1.2^ 的作用使用场景示例1ThreadLocal 变量初始化ThreadLocal 源码分析源码分析总结 内存泄漏问题示例说明new Thread 方式 执行结果pool 方式执行结果原因解析总结 ThreadLocal 1.2 的作用 ThreadLocal 为每个线程提供单独的变量副本。每个变量副本都是…

史上最全嵌入式(学习路线、应用开发、驱动开发、推荐书籍、软硬件基础)

废话不多说直接上思维导图&#xff01; 如果有觉得图片看不清楚的&#xff0c;有疑问的&#xff0c;可在评论区进行留言&#xff01; 群号&#xff1a; 228447240 嵌入式总括 嵌入式书籍推荐 嵌入式软件知识 嵌入式硬件知识 嵌入式应用开发 嵌入式驱动开发 嵌入式视频推荐: 韦…

WebSocket相关问题

1.WebSocket是什么&#xff1f;和HTTP的区别&#xff1f; WebSocket是一种基于TCP连接的全双工通信协议&#xff0c;客户端和服务器仅需要一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c;并且支持双向数据的传输。WebSocket和HTTP都是基于TCP的应用层协议&am…

【PyTorch][chapter 15][李宏毅深度学习][Neighbor Embedding-LLE]

前言&#xff1a; 前面讲的都是线性降维&#xff0c;本篇主要讨论一下非线性降维. 流形学习&#xff08;mainfold learning&#xff09;是一类借鉴了拓扑流行概念的降维方法. 如上图,欧式距离上面 A 点跟C点更近&#xff0c;距离B 点较远 但是从图形拓扑结构来看&#xff0c; …

书生·浦语大模型全链路开源体系

1&#xff0c;简述大模型的定义与特点&#xff1a; 大模型是指参数数量大于10亿的模型&#xff0c;它的特点包括&#xff1a;模型规模大&#xff0c;数据规模大&#xff0c;计算规模大和任务数量 2. 分析大模型成为通用人工智能的重要途径的原因&#xff1a; 大模型能够从大…