Verilog 学习第五节(串口接收部分)

news2024/11/19 1:30:01

小梅哥串口部分学习part2

  • 串口通信接收原理
  • 串口通信接收程序设计与调试
  • 巧用位操作优化串口接收逻辑设计
  • 串口接收模块的项目应用案例

串口通信接收原理

在这里插入图片描述
在这里插入图片描述
在采样的时候没有必要一直判断一个clk内全部都是高/低电平,如果采用直接对中间点进行判断的话,很有可能出现中间点恰好电力失常等等,因此可以采集多次样本,其中样本数据频率高的值就是该段电平的值
**基本原理:**采样
**技巧是:**一位数据采多次,统计得到高电平出现的次数,次数多的就是该位的电平值。采样8次,0,1,2,3低电平,4,5,6,7为高电平
**起始位检测:**通过边沿检测电路
在这里插入图片描述

串口通信接收程序设计与调试

波特率是指串口通信中,单位时间传输的二进制位数eg:115200对应的就是1s传输115200位,即传输一位需要1000000000/115200,若进行采样频率为波特率的16倍则需要再除以16对应于每次的采样的时间,由于内部时钟20ns的频率进行变化,所以想要计算对应的采样次数就需要再除以20~
源代码


module uart_byte_rx(
     input Clk,
     input Reset,
     input [2:0]Baud_Set,
     input uart_rx,
     output reg[7:0] Data,
     output reg RxDone
    );
    
    //边沿检测
    reg [1:0]uart_rx_r;
    always@(posedge Clk)
    begin
          uart_rx_r[0]<=uart_rx;
          uart_rx_r[1]<=uart_rx_r[0];
    end
    //上升沿
    wire pedge_uart_rx;
    //assign pedge_uart_rx=((uart_rx_r[0]==0)&&(uart_rx_r[1]==1));
    assign pedge_uart_rx=(uart_rx_r==2'b01);
    //下降沿
    wire nedge_uart_rx;
    //assign pedge_uart_rx=((uart_rx_r[0]==1)&&(uart_rx_r[1]==0));
    assign nedge_uart_rx=(uart_rx_r==2'b10);
    
    //采样需要计数的位数
    reg [8:0]  Bps_DR;
        always@(*)
            case(Baud_Set)
                0:Bps_DR = 1000000000/9600/16/20 - 1;
                1:Bps_DR = 1000000000/19200/16/20 - 1;
                2:Bps_DR = 1000000000/38400/16/20 - 1;
                3:Bps_DR = 1000000000/57600/16/20 - 1;
                4:Bps_DR = 1000000000/115200/16/20 - 1;
                default:Bps_DR = 1000000000/9600/16/20 - 1;
            endcase
   
   wire bps_clk_16x;
   assign bps_clk_16x = (div_cnt == Bps_DR / 2);   
   
   
   reg [8:0]div_cnt;
   always@(posedge Clk or negedge Reset)begin
        if(!Reset)
        div_cnt<=0;
        else if(RX_EN)begin
        if(div_cnt==Bps_DR)
        div_cnt<=0;
        else
        div_cnt<=div_cnt+1;
        end
        else
        div_cnt<=0;    
   end
   
   //每位被分成16次频率采样,所以一共检测10位则需要160位
   reg [7:0]bps_cnt;
   always@(posedge Clk or negedge Reset)begin
           if(!Reset)
           bps_cnt<=0;
           else if(RX_EN)begin
                if(bps_clk_16x)begin
                    if(bps_cnt==159)
                      bps_cnt<=0;
                      else
                      bps_cnt<=bps_cnt+1;
                    end
                else
                bps_cnt<=bps_cnt;  
                end
           else
           bps_cnt<=0;
           
   end
   
   reg[2:0]r_data[7:0];
   reg [2:0]sta_bit;
   reg [2:0]sto_bit;
   reg RX_EN;  
   always@(posedge Clk or negedge Reset)begin
        if(!Reset)
        RX_EN<=0;
        else if(nedge_uart_rx)
        RX_EN<=1;
        else if(RxDone || (sta_bit >= 4))
        RX_EN<=0;
        end
    
    //用于对数据赋值   
    always@(posedge Clk or negedge Reset)begin
        if(!Reset)begin
        sta_bit<=0;
        sto_bit<=0;
        r_data[0]<=0;
        r_data[1]<=0;
        r_data[2]<=0;
        r_data[3]<=0;
        r_data[4]<=0;
        r_data[5]<=0;
        r_data[6]<=0;
        r_data[7]<=0;
        end
        else if(bps_clk_16x)//中间位置取结果16次里面的5,6,7,8,9,10,11次数据
        begin
        case(bps_cnt)
        0:begin
                sta_bit<=0;
                sto_bit<=0;
                r_data[0]<=0;
                r_data[1]<=0;
                r_data[2]<=0;
                r_data[3]<=0;
                r_data[4]<=0;
                r_data[5]<=0;
                r_data[6]<=0;
                r_data[7]<=0;
                end
        5,6,7,8,9,10,11:sta_bit<=sta_bit+uart_rx;
        21,22,23,24,25,26,27: r_data[0] <= r_data[0] + uart_rx;
        37,38,39,40,41,42,43: r_data[1] <= r_data[1] + uart_rx;
        53,54,55,56,57,58,59: r_data[2] <= r_data[2] + uart_rx;
        69,70,71,72,73,74,75: r_data[3] <= r_data[3] + uart_rx;
        85,86,87,88,89,90,91: r_data[4] <= r_data[4] + uart_rx;
        101,102,103,104,105,106,107: r_data[5] <= r_data[5] + uart_rx;
        117,118,119,120,121,122,123: r_data[6] <= r_data[6] + uart_rx;
        133,134,135,136,137,138,139: r_data[7] <= r_data[7] + uart_rx;
        149,150,151,152,153,154,155: sto_bit <= sto_bit + uart_rx;
        default:;
        endcase
        end
        end
        
        always@(posedge Clk or negedge Reset)
            if(!Reset) 
                Data <= 0;        
            else if(bps_clk_16x && (bps_cnt == 159))begin
                Data[0] <= (r_data[0] >= 4)?1'b1:1'b0;
                Data[1] <= (r_data[1] >= 4)?1'b1:1'b0;
                Data[2] <= (r_data[2] >= 4)?1'b1:1'b0;
                Data[3] <= (r_data[3] >= 4)?1'b1:1'b0;
                Data[4] <= (r_data[4] >= 4)?1'b1:1'b0;
                Data[5] <= (r_data[5] >= 4)?1'b1:1'b0;
                Data[6] <= (r_data[6] >= 4)?1'b1:1'b0;
                Data[7] <= (r_data[7] >= 4)?1'b1:1'b0;
            end 
        
       always@(posedge Clk or negedge Reset)begin
       if(!Reset)
        RxDone<=0;
        else if((div_cnt==Bps_DR/2)&&(bps_cnt==159))
        RxDone<=1;
        else
        RxDone<=0;
        end
        
endmodule

测试模块

`timescale 1ns / 1ns
module uart_byte_rx_tb(
    );
    reg Clk;
    reg Reset;
    wire [2:0]Baud_Set;
    reg uart_rx;
    wire[7:0] Data;
    wire RxDone;
    assign Baud_Set=4;
    uart_byte_rx uart_byte_rx(
         Clk,
         Reset,
         Baud_Set,
         uart_rx,
         Data,
         RxDone
        );
     initial Clk=0;
     always #10 Clk=!Clk;
     
     initial begin
     Reset=0;
     uart_rx=1;
     #201;
//     Reset=1;
//     uart_tx_byte(8'h54);
//     @(posedge RxDone);
//     #50000;
//     uart_tx_byte(8'h32);
//     @(posedge RxDone);
//     #50000;
//     uart_tx_byte(8'h89);
//     @(posedge RxDone);
//     #50000;
       Reset = 1;
       #200; 
       uart_tx_byte(8'h5a);
       #90000;
       uart_tx_byte(8'ha5);
       #90000;
       uart_tx_byte(8'h86);
       #90000;
       $stop;
     $stop;
     end
     
     task uart_tx_byte;
     input [7:0]tx_data;
     begin
     uart_rx=1;
     #20;
     uart_rx=0;
     #8680;
     uart_rx=tx_data[0];
     #8680;
     uart_rx=tx_data[1];
     #8680;
     uart_rx=tx_data[2];
     #8680;
     uart_rx=tx_data[3];
     #8680;
     uart_rx=tx_data[4];
     #8680;
     uart_rx=tx_data[5];
     #8680;
     uart_rx=tx_data[6];
     #8680;
     uart_rx=tx_data[7];
     #8680;
     uart_rx=1;
     #8680;
     end
     endtask
endmodule

仿真截图
在这里插入图片描述

巧用位操作优化串口接收逻辑设计

解释:3’b000 3’b001 3’b010 3’b011 3’b100 3’b101 3’b110 3’b111判断是否大于等于4可以直接对第2位进行判断,为1则大于等于,为0则不大于

        always@(posedge Clk or negedge Reset)
            if(!Reset) 
                Data <= 0;        
            else if(bps_clk_16x && (bps_cnt == 159))begin
                Data[0] <= (r_data[0] >= 4)?1'b1:1'b0;
                Data[1] <= (r_data[1] >= 4)?1'b1:1'b0;
                Data[2] <= (r_data[2] >= 4)?1'b1:1'b0;
                Data[3] <= (r_data[3] >= 4)?1'b1:1'b0;
                Data[4] <= (r_data[4] >= 4)?1'b1:1'b0;
                Data[5] <= (r_data[5] >= 4)?1'b1:1'b0;
                Data[6] <= (r_data[6] >= 4)?1'b1:1'b0;
                Data[7] <= (r_data[7] >= 4)?1'b1:1'b0;
            end 
            
//可以达到和上面同样的功能
//       always@(posedge Clk or negedge Reset)
//            if(!Reset) 
//                Data <= 0;        
//            else if(bps_clk_16x && (bps_cnt == 159))begin
//                Data[0] <= r_data[0][2];
//                Data[1] <= r_data[1][2];
//                Data[2] <= r_data[2][2];
//                Data[3] <= r_data[3][2];
//                Data[4] <= r_data[4][2];
//                Data[5] <= r_data[5][2];
//                Data[6] <= r_data[6][2];
//                Data[7] <= r_data[7][2];
//            end 
    

串口接收模块的项目应用案例

使用串口来控制LED工作状态
题目:使用串口发送指令到FPGA开发板,来控制第7课第4个实验的开发板上的LED灯的工作状态
让LED灯按照指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。8个变化状态为一个循环,每个变化状态的时间值可以根据不同的应用场景选择
如何使用串口接收8个字节的数据
在这里插入图片描述
在这里插入图片描述
收获:
1:上板调试时,对于时钟计时问题,最初counter=0,发现不满足,counter就会一直自加,直到加到32位的’hFFFFFFFF’才会清零
在实际板级运行的时候,当我们的time值更新时(25000000),counter的值已经大于该值,所以无法通过计数比较的方式清零,只能一直自加下去,直到32位计满了,溢出清零,然后才能正常的循环计数清零
这里涉及到一种编写技巧判断
if(i>=32)
a=0;
和if(i==32)
a=0;
虽然结界点都是32,但是对于第一种情况可以有效地避免当不满足条件时的及时清零,对于第二种有的时候或许会有些小问题
2:对于reset这种外部模块最好全部都定义成大写,并且统一这样赋值的时候不容易出错,模块内部的变量定义成小写
3:在顶层模块中几乎除了输入输出以外的内部变量都要定义成wire类型,代表内部的连线,输入输出还是采用和以往相同的方法,若底层是reg型,则上层直接定义成output就可,不用再定义成reg,测试文件直接写出wire~

//counter_led_4中
always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter <= 0;
    else if(counter >= Time - 1)//这里由==改成了>=
        counter <= 0;
    else
        counter <= counter + 1'b1;

源代码


module uart_rx_ctrl_led(
    input Clk,
    input reset,
    input uart_rx,
    output Led
    );
    
    wire [7:0]Ctrl;
    wire [31:0]Time;
    wire [7:0]Data;
    wire RxDone;
    
    counter_led_4 counter_led_4(
        .Clk(Clk),
        .Reset_n(reset),
        .Ctrl(Ctrl),
        .Time(Time),
        .Led(Led)
    );
    
    uart_byte_rx uart_byte_rx(
           .Clk(Clk),
           .Reset(reset),
           .Baud_Set(3'd4),
           .uart_rx(uart_rx),
           .Data(Data),
           .RxDone(RxDone)
    );
    
    uart_cmd uart_cmd(
       .clk(Clk),
       .reset(reset),
       .rx_data(Data),
       .rx_done(RxDone),
       .ctrl(Ctrl),
       .time_set(Time)
        );
endmodule

module counter_led_4(
    Clk,
    Reset_n,
    Ctrl,
    Time,
    Led
);
    input Clk;
    input Reset_n;
    input [7:0]Ctrl;
    input [31:0]Time;
    output reg Led;

    reg [31:0]counter;
    
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter <= 0;
    else if(counter >= Time - 1)
        counter <= 0;
    else
        counter <= counter + 1'b1;
    
    reg [2:0]counter2;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n) 
        counter2 <= 0; 
    else if(counter == Time - 1)
        counter2 <= counter2 + 1'b1;

    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        Led <= 0;
    else case(counter2)
        0:Led <= Ctrl[0];
        1:Led <= Ctrl[1];
        2:Led <= Ctrl[2];
        3:Led <= Ctrl[3];
        4:Led <= Ctrl[4];
        5:Led <= Ctrl[5];
        6:Led <= Ctrl[6];
        7:Led <= Ctrl[7];
        default:Led <= Led;
    endcase
            
endmodule
module uart_byte_rx(
     input Clk,
     input Reset,
     input [2:0]Baud_Set,
     input uart_rx,
     output reg[7:0] Data,
     output reg RxDone
    );
    
    //边沿检测
    reg [1:0]uart_rx_r;
    always@(posedge Clk)
    begin
          uart_rx_r[0]<=uart_rx;
          uart_rx_r[1]<=uart_rx_r[0];
    end
    //上升沿
    wire pedge_uart_rx;
    //assign pedge_uart_rx=((uart_rx_r[0]==0)&&(uart_rx_r[1]==1));
    assign pedge_uart_rx=(uart_rx_r==2'b01);
    //下降沿
    wire nedge_uart_rx;
    //assign pedge_uart_rx=((uart_rx_r[0]==1)&&(uart_rx_r[1]==0));
    assign nedge_uart_rx=(uart_rx_r==2'b10);
    
    //采样需要计数的位数
    reg [8:0]  Bps_DR;
        always@(*)
            case(Baud_Set)
                0:Bps_DR = 1000000000/9600/16/20 - 1;
                1:Bps_DR = 1000000000/19200/16/20 - 1;
                2:Bps_DR = 1000000000/38400/16/20 - 1;
                3:Bps_DR = 1000000000/57600/16/20 - 1;
                4:Bps_DR = 1000000000/115200/16/20 - 1;
                default:Bps_DR = 1000000000/9600/16/20 - 1;
            endcase
   
   wire bps_clk_16x;
   assign bps_clk_16x = (div_cnt == Bps_DR / 2);   
   
   
   reg [8:0]div_cnt;
   always@(posedge Clk or negedge Reset)begin
        if(!Reset)
        div_cnt<=0;
        else if(RX_EN)begin
        if(div_cnt==Bps_DR)
        div_cnt<=0;
        else
        div_cnt<=div_cnt+1;
        end
        else
        div_cnt<=0;    
   end
   
   //每位被分成16次频率采样,所以一共检测10位则需要160位
   reg [7:0]bps_cnt;
   always@(posedge Clk or negedge Reset)begin
           if(!Reset)
           bps_cnt<=0;
           else if(RX_EN)begin
                if(bps_clk_16x)begin
                    if(bps_cnt==159)
                      bps_cnt<=0;
                      else
                      bps_cnt<=bps_cnt+1;
                    end
                else
                bps_cnt<=bps_cnt;  
                end
           else
           bps_cnt<=0;
           
   end
   
   reg[2:0]r_data[7:0];
   reg [2:0]sta_bit;
   reg [2:0]sto_bit;
   reg RX_EN;  
   always@(posedge Clk or negedge Reset)begin
        if(!Reset)
        RX_EN<=0;
        else if(nedge_uart_rx)
        RX_EN<=1;
        else if(RxDone || (sta_bit >= 4))
        RX_EN<=0;
        end
    
    //用于对数据赋值   
    always@(posedge Clk or negedge Reset)begin
        if(!Reset)begin
        sta_bit<=0;
        sto_bit<=0;
        r_data[0]<=0;
        r_data[1]<=0;
        r_data[2]<=0;
        r_data[3]<=0;
        r_data[4]<=0;
        r_data[5]<=0;
        r_data[6]<=0;
        r_data[7]<=0;
        end
        else if(bps_clk_16x)//中间位置取结果16次里面的5,6,7,8,9,10,11次数据
        begin
        case(bps_cnt)
        0:begin
                sta_bit<=0;
                sto_bit<=0;
                r_data[0]<=0;
                r_data[1]<=0;
                r_data[2]<=0;
                r_data[3]<=0;
                r_data[4]<=0;
                r_data[5]<=0;
                r_data[6]<=0;
                r_data[7]<=0;
                end
        5,6,7,8,9,10,11:sta_bit<=sta_bit+uart_rx;
        21,22,23,24,25,26,27: r_data[0] <= r_data[0] + uart_rx;
        37,38,39,40,41,42,43: r_data[1] <= r_data[1] + uart_rx;
        53,54,55,56,57,58,59: r_data[2] <= r_data[2] + uart_rx;
        69,70,71,72,73,74,75: r_data[3] <= r_data[3] + uart_rx;
        85,86,87,88,89,90,91: r_data[4] <= r_data[4] + uart_rx;
        101,102,103,104,105,106,107: r_data[5] <= r_data[5] + uart_rx;
        117,118,119,120,121,122,123: r_data[6] <= r_data[6] + uart_rx;
        133,134,135,136,137,138,139: r_data[7] <= r_data[7] + uart_rx;
        149,150,151,152,153,154,155: sto_bit <= sto_bit + uart_rx;
        default:;
        endcase
        end
        end
        
        always@(posedge Clk or negedge Reset)
            if(!Reset) 
                Data <= 0;        
            else if(bps_clk_16x && (bps_cnt == 159))begin
                Data[0] <= (r_data[0] >= 4)?1'b1:1'b0;
                Data[1] <= (r_data[1] >= 4)?1'b1:1'b0;
                Data[2] <= (r_data[2] >= 4)?1'b1:1'b0;
                Data[3] <= (r_data[3] >= 4)?1'b1:1'b0;
                Data[4] <= (r_data[4] >= 4)?1'b1:1'b0;
                Data[5] <= (r_data[5] >= 4)?1'b1:1'b0;
                Data[6] <= (r_data[6] >= 4)?1'b1:1'b0;
                Data[7] <= (r_data[7] >= 4)?1'b1:1'b0;
            end 
            
//可以达到和上面同样的功能
//       always@(posedge Clk or negedge Reset)
//            if(!Reset) 
//                Data <= 0;        
//            else if(bps_clk_16x && (bps_cnt == 159))begin
//                Data[0] <= r_data[0][2];
//                Data[1] <= r_data[1][2];
//                Data[2] <= r_data[2][2];
//                Data[3] <= r_data[3][2];
//                Data[4] <= r_data[4][2];
//                Data[5] <= r_data[5][2];
//                Data[6] <= r_data[6][2];
//                Data[7] <= r_data[7][2];
//            end 
        
       always@(posedge Clk or negedge Reset)begin
       if(!Reset)
        RxDone<=0;
        else if((div_cnt == Bps_DR/2)&&(bps_cnt==159))
        RxDone<=1;
        else
        RxDone<=0;
        end
        
endmodule
//这里养成一个习惯,在模块内部的信号用小写
module uart_cmd(
   input clk,
   input reset,
   input [7:0]rx_data,
   input rx_done,
   output reg [7:0]ctrl,
   output reg [31:0]time_set
    );
    reg [7:0] reg_data[7:0];
     always@(posedge clk)begin
     if(rx_done)begin
     reg_data[7]<=rx_data;
     reg_data[6]<=reg_data[7];
     reg_data[5]<=reg_data[6];
     reg_data[4]<=reg_data[5];
     reg_data[3]<=reg_data[4];
     reg_data[2]<=reg_data[3];
     reg_data[1]<=reg_data[2];
     reg_data[0]<=reg_data[1];
     end
     end
     
     reg rx_rx_done;
     always@(posedge clk)
          rx_rx_done<=rx_done;
     
     always@(posedge clk or negedge reset)begin
     if(!reset)begin
     time_set<=0;
     ctrl<=0;
     end
     else if(rx_rx_done)begin
      if((reg_data[0]==8'h55)&&(reg_data[1]==8'ha5)&&(reg_data[7]==8'hf0))begin
            time_set[7:0]<=reg_data[2];
            time_set[15:8]<=reg_data[3];
            time_set[23:16]<=reg_data[4];
            time_set[31:24]<=reg_data[5];
            ctrl<=reg_data[6];
        end
        end
     end
endmodule

测试文件

`timescale 1ns / 1ps

module uart_rx_ctrl_led_tb(
    );
    reg Clk;
    reg reset;
    reg uart_rx;
    wire Led;
    uart_rx_ctrl_led uart_rx_ctrl_led(
        Clk,
        reset,
        uart_rx,
        Led
        );
    initial Clk = 1;
    always#10 Clk = ~Clk;
    
    initial begin
       reset = 0;
       uart_rx = 1;
       #201;
       reset = 1;
       #200; 
       
       uart_tx_byte(8'h55);
       #90000;
       uart_tx_byte(8'ha5);
       #90000;
       uart_tx_byte(8'h55);
       #90000;
       uart_tx_byte(8'ha5);
       #90000;
       uart_tx_byte(8'h12);
       #90000;
       uart_tx_byte(8'h34);
       #90000;
       uart_tx_byte(8'h56);
       #90000;
       uart_tx_byte(8'h78);
       #90000;  
       uart_tx_byte(8'h9a);
       #90000;       
       uart_tx_byte(8'hf0);
       #90000;    
       
       
       uart_tx_byte(8'h55);
       #90000;
       uart_tx_byte(8'ha5);
       #90000;
       uart_tx_byte(8'h9a);
       #90000;
       uart_tx_byte(8'h78);
       #90000;
       uart_tx_byte(8'h56);
       #90000;
       uart_tx_byte(8'h34);
       #90000;  
       uart_tx_byte(8'h12);
       #90000;       
       uart_tx_byte(8'hf1);
       #90000;       
       $stop;
    end
    
    task uart_tx_byte;
        input [7:0]tx_data;
        begin
            uart_rx = 1;
            #20;
            uart_rx = 0;
            #8680;
            uart_rx = tx_data[0];
            #8680;
            uart_rx = tx_data[1];
            #8680;
            uart_rx = tx_data[2];
            #8680;
            uart_rx = tx_data[3];
            #8680;
            uart_rx = tx_data[4];
            #8680;
            uart_rx = tx_data[5];
            #8680;
            uart_rx = tx_data[6];
            #8680;
            uart_rx = tx_data[7];
            #8680;
            uart_rx = 1;
            #8680;         
        end
    endtask    
endmodule

仿真截图
在这里插入图片描述

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

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

相关文章

CISP注册信息安全专业人员证书

一、什么是“CISP”&#xff1f; 注册信息安全专业人员(Certified Information Security Professional&#xff0c;简称“CISP”)&#xff0c;是安全行业最为权威的安全资格认证&#xff0c;由中国信息安全测评中心统一授权组织&#xff0c;中国信息安全测评中心授权培训机构进…

学习笔记之Vue中的Ajax(四)

Vue中的Ajax&#xff08;四&#xff09;Vue中的ajax一、解决开发环境Ajax跨越问题二、github 用户搜索案例2.1 准备工作2.2 静态页面2.3 实现动态组件2.4 注意细节三、vue 项目中常用的 2 个 Ajax 库3.1 axios3.2 vue-resource四、slot插槽&#xff08;四&#xff09;Vue中的aj…

计算结构体大小

计算结构体大小 目录计算结构体大小一. 结构体内存对齐1. 简介2. 嵌套结构体二. offsetof三. 内存对齐的意义四. 修改默认对齐数一. 结构体内存对齐 以字节&#xff08;bety&#xff09;为单位 1. 简介 对于结构体成员在内存里的存储&#xff0c;存在结构体的对齐规则&#…

代码随想录算法训练营day44 | 动态规划之完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ

day44完全背包基础知识问题描述举个栗子518. 零钱兑换 II1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组377. 组合总和 Ⅳ1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例来推导dp数组完全背包基…

安全合规之CVE-2016-2183

文章目录概述分析解决补充信息概述 安全部门脆弱性扫描到如下的风险漏洞要求系统上线必须要修复完毕。 不过我仔细的看了安全部门返回的报告&#xff0c;它是针对Windows Server 2019远程桌面端口进行风险报告…这是刷存在感了吗&#xff1f;哎&#xff0c;没有办法先做调查确…

高压放大器在声波谐振电小天线收发测试系统中的应用

实验名称&#xff1a;高压放大器在声波谐振电小天线收发测试系统中的应用研究方向&#xff1a;信号传输测试目的&#xff1a;声波谐振电小天线颠覆了传统电小天线以电磁波谐振作为理论基础的天线发射和接收模式&#xff0c;它借助声波谐振实现电磁信号的辐射或接收。因为同频的…

Spring Batch 综合案例实战-项目准备

目录 案例需求 分析 项目准备 步骤1&#xff1a;新开spring-batch-example 步骤2&#xff1a;导入依赖 步骤3&#xff1a;配置文件 步骤4&#xff1a;建立employee表与employe_temp表 步骤5&#xff1a;建立基本代码体系-domain-mapper-service-controller-mapper.xml …

YMatrix + PLPython替代Spark实现车联网算法

PySpark算法开发实战 一、PySpark介绍 Spark是一种快速、通用、可扩展的大数据分析引擎&#xff0c;PySpark是Spark为Python开发者提供的API。在有非常多可视化和机器学习算法需求的应用场景&#xff0c;使用PySpark比Spark-Scala可以更好地和python中丰富的库配合使用。 使…

监听页面滚动,给页面中的节点添加动态过渡效果

效果示例图 示例代码 <template><div class"animation-wrap"><!-- header-start --><div class"animation-header">头部</div><!-- header-end --><div class"animation-subtitle animation-show">标…

工人搬砖-课后程序(JAVA基础案例教程-黑马程序员编著-第八章-课后作业)

【案例8-4】 工人搬砖 【案例介绍】 1.任务描述 在某个工地&#xff0c;需要把100块砖搬运到二楼&#xff0c;现在有工人张三和李四&#xff0c;张三每次搬运3块砖&#xff0c;每趟需要10分钟&#xff0c;李四每次搬运5块砖&#xff0c;每趟需要12分钟。本案例要求编写程序分…

收集分享一些AI工具第三期(网站篇)

感谢大家对于内容的喜欢&#xff0c;目前已经来到了AI工具分享的最后一期了&#xff0c;目前为止大部分好用的AI工具都已经介绍给大家了&#xff0c;希望大家可以喜欢。 image-to-sound-fx (https://huggingface.co/spaces/fffiloni/image-to-sound-fx) 图片转换为相对应的声音…

【unity3d】unity即时战略游戏开发2 rts engine

A 背景 经过寻找发现有unity3d的[rts engine]&#xff0c;ue4的[template 4]等rts引擎/模板。 没有搜到相关教程&#xff0c;倒是有几个老外的ue从零开发长篇教程。 rts engine有几个试玩视频&#xff0c;尝试找了一下。那就不用虚幻了。 距离[原坤争霸 genshin craft]近了…

【ChatGPT整活大赏】写论文后自动生成视频

ChatGPT国内又火了一把&#xff0c;功能很强大&#xff0c;接下来就带大家感受一下它的强大之处&#xff0c;通过ChatGPT写一篇论文并自动生成视频&#xff0c;增加内容的可读性。 话不多说&#xff0c;先上成果&#xff1a; …

MySQL管理表

在创建表时需要提前了解mysql里面的数据类型 常见的数据类型 创建表 创建表方式1&#xff1a; 格式&#xff1a; CREATE TABLE [IF NOT EXISTS] 表名( 字段1, 数据类型 [约束条件] [默认值], 字段2, 数据类型 [约束条件] [默认值], 字段3, 数据类型 [约束条件] [默认值], ………

以FGSM算法为例的对抗训练的实现(基于Pytorch)

1. 前言 深度学习虽然发展迅速,但是由于其线性的特性,受到了对抗样本的影响,很容易造成系统功能的失效。 以图像分类为例子&#xff0c;对抗样本很容易使得在测试集上精度很高的模型在对抗样本上的识别精度很低。 对抗样本指的是在合法数据上添加了特定的小的扰动&#xff0c;…

聚类算法(下):10个聚类算法的评价指标

上篇文章我们已经介绍了一些常见的聚类算法&#xff0c;下面我们将要介绍评估聚类算法的指标 1、Rand Index Rand Index&#xff08;兰德指数&#xff09;是一种衡量聚类算法性能的指标。它衡量的是聚类算法将数据点分配到聚类中的准确程度。兰德指数的范围从0到1,1的值表示两…

Python-GEE遥感云大数据分析、管理与可视化技术及多领域案例实践应用

随着航空、航天、近地空间等多个遥感平台的不断发展&#xff0c;近年来遥感技术突飞猛进。由此&#xff0c;遥感数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量也大幅增长&#xff0c;使其越来越具有大数据特征。对于相关研究而言&#xff0c;遥感大数据的出现为其提…

【阿旭机器学习实战】【37】电影推荐系统---基于矩阵分解

【阿旭机器学习实战】系列文章主要介绍机器学习的各种算法模型及其实战案例&#xff0c;欢迎点赞&#xff0c;关注共同学习交流。 电影推荐系统 目录电影推荐系统1. 问题介绍1.1推荐系统矩阵分解方法介绍1.2 数据集&#xff1a;ml-100k2. 推荐系统实现2.1 定义矩阵分解函数2.2 …

什么牌子的蓝牙耳机便宜好用?四款高品质蓝牙耳机推荐

随着时代的发展&#xff0c;蓝牙耳机的使用频率越来越高&#xff0c;不少人外出时除了带手机外&#xff0c;蓝牙耳机也成为了外出必备的数码产品之一。现在的蓝牙耳机品牌众多&#xff0c;什么牌子的蓝牙耳机便宜好用&#xff1f;下面&#xff0c;我来给大家推荐四款高品质的蓝…

ZigBee组网原理详解

关键词&#xff1a;RFD FFD ZigBee 1. 组网概述 组建一个完整的zigbee网状网络包括两个步骤&#xff1a;网络初始化、节点加入网络。其中节点加入网络又包括两个步骤&#xff1a;通过与协调器连接入网和通过已有父节点入网。 ZigBee网络中的节点主要包含三个&#xff1a;终端…