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

news/2024/4/20 12:05:01/文章来源:https://blog.csdn.net/weixin_46741734/article/details/129151266

小梅哥串口部分学习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)beginuart_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;endcasewire bps_clk_16x;assign bps_clk_16x = (div_cnt == Bps_DR / 2);   reg [8:0]div_cnt;always@(posedge Clk or negedge Reset)beginif(!Reset)div_cnt<=0;else if(RX_EN)beginif(div_cnt==Bps_DR)div_cnt<=0;elsediv_cnt<=div_cnt+1;endelsediv_cnt<=0;    end//每位被分成16次频率采样,所以一共检测10位则需要160位reg [7:0]bps_cnt;always@(posedge Clk or negedge Reset)beginif(!Reset)bps_cnt<=0;else if(RX_EN)beginif(bps_clk_16x)beginif(bps_cnt==159)bps_cnt<=0;elsebps_cnt<=bps_cnt+1;endelsebps_cnt<=bps_cnt;  endelsebps_cnt<=0;endreg[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)beginif(!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)beginif(!Reset)beginsta_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;endelse if(bps_clk_16x)//中间位置取结果16次里面的5,6,7,8,9,10,11次数据begincase(bps_cnt)0:beginsta_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;end5,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:;endcaseendendalways@(posedge Clk or negedge Reset)if(!Reset) Data <= 0;        else if(bps_clk_16x && (bps_cnt == 159))beginData[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)beginif(!Reset)RxDone<=0;else if((div_cnt==Bps_DR/2)&&(bps_cnt==159))RxDone<=1;elseRxDone<=0;endendmodule

测试模块

`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 beginReset=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;endtask uart_tx_byte;input [7:0]tx_data;beginuart_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;endendtask
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))beginData[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;elsecounter <= 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;elsecounter <= 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;endcaseendmodule
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)beginuart_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;endcasewire bps_clk_16x;assign bps_clk_16x = (div_cnt == Bps_DR / 2);   reg [8:0]div_cnt;always@(posedge Clk or negedge Reset)beginif(!Reset)div_cnt<=0;else if(RX_EN)beginif(div_cnt==Bps_DR)div_cnt<=0;elsediv_cnt<=div_cnt+1;endelsediv_cnt<=0;    end//每位被分成16次频率采样,所以一共检测10位则需要160位reg [7:0]bps_cnt;always@(posedge Clk or negedge Reset)beginif(!Reset)bps_cnt<=0;else if(RX_EN)beginif(bps_clk_16x)beginif(bps_cnt==159)bps_cnt<=0;elsebps_cnt<=bps_cnt+1;endelsebps_cnt<=bps_cnt;  endelsebps_cnt<=0;endreg[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)beginif(!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)beginif(!Reset)beginsta_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;endelse if(bps_clk_16x)//中间位置取结果16次里面的5,6,7,8,9,10,11次数据begincase(bps_cnt)0:beginsta_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;end5,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:;endcaseendendalways@(posedge Clk or negedge Reset)if(!Reset) Data <= 0;        else if(bps_clk_16x && (bps_cnt == 159))beginData[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)beginif(!Reset)RxDone<=0;else if((div_cnt == Bps_DR/2)&&(bps_cnt==159))RxDone<=1;elseRxDone<=0;endendmodule
//这里养成一个习惯,在模块内部的信号用小写
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)beginif(rx_done)beginreg_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];endendreg rx_rx_done;always@(posedge clk)rx_rx_done<=rx_done;always@(posedge clk or negedge reset)beginif(!reset)begintime_set<=0;ctrl<=0;endelse if(rx_rx_done)beginif((reg_data[0]==8'h55)&&(reg_data[1]==8'ha5)&&(reg_data[7]==8'hf0))begintime_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];endendend
endmodule

测试文件

`timescale 1ns / 1psmodule 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 beginreset = 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;endtask uart_tx_byte;input [7:0]tx_data;beginuart_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;         endendtask    
endmodule

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

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 红帽9.0 本地源 与 网络源 搭建

本次我们使用的是 redhat 9.0 版本&#xff0c;是redhat 的最新版本&#xff0c;我们一起来对其进行 本地仓库 和 网络仓库的搭建部署~&#xff01;&#xff01;关于 本地仓库&#xff08; 本地源 &#xff09;&#xff0c;和 网络仓库 &#xff08; 网络源 &#xff09;&#…

ESP32蓝牙配网

注意********menuconfig 配置&#xff08;必须打开蓝牙我这是C2所以使用NimBLE &#xff09;可以直接从demo的配置文件拷贝 Component config ---> Bluetooth ---> NimBLE - BLE only Component config ---> Bluetooth ---> NimBLE Options ---> Enable blufi…

计算结构体大小

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

Vue下载安装步骤的详细教程(亲测有效) 1

目录 一、【准备工作】nodejs下载安装(npm环境) 1 下载安装nodejs 2 查看环境变量是否添加成功 3、验证是否安装成功 4、修改模块下载位置 &#xff08;1&#xff09;查看npm默认存放位置 &#xff08;2&#xff09;在 nodejs 安装目录下&#xff0c;创建 “node_global…

Java查漏补缺(14)数据结构剖析、一维数组、链表、栈、队列、树与二叉树、List接口分析、Map接口分析、Set接口分析、HashMap的相关问题

Java查漏补缺&#xff08;14&#xff09;数据结构剖析、一维数组、链表、栈、队列、树与二叉树、List接口分析、Map接口分析、Set接口分析、HashMap的相关问题本章专题与脉络1. 数据结构剖析1.1 研究对象一&#xff1a;数据间逻辑关系1.2 研究对象二&#xff1a;数据的存储结构…

Laravel框架04:视图与CSRF攻击

Laravel框架04&#xff1a;视图与CSRF攻击一、视图概述二、变量分配与展示三、模板中直接使用函数四、循环与分支语法标签五、模板继承、包含1. 继承2. 包含六、外部静态文件引入七、CSRF攻击概述八、从CSRF验证中排除例外路由一、视图概述 视图存放在 resources/views 目录下…

MyBatis学习笔记(七) —— 特殊SQL的执行

7、特殊SQL的执行 7.1、模糊查询 模糊查询的三种方式&#xff1a; 方式1&#xff1a;select * from t_user where username like ‘%${mohu}%’ 方式2&#xff1a;select * from t_user where username like concat(‘%’,#{mohu},‘%’) 方式3&#xff1a;select * from t_u…

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

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

2.27 junit5常用语法

一.了解junitjunit是一个开源的java单元测试框架,java方向使用最广泛的单元测试框架.所需要的依赖<dependencies><!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --><dependency><groupId>org.seleniumhq.selenium&l…

笔记本触摸板没反应怎么办?处理方法看这些

触摸板在笔记本电脑中是非常重要的一部分&#xff0c;很多用户都会选择使用触摸板代替鼠标。然而&#xff0c;有时你可能会发现&#xff0c;你的笔记本电脑触摸板没反应&#xff0c;无法正常使用。这对于日常使用来说是非常困扰的&#xff0c;但不用担心&#xff0c;我们将在这…

react源码解析10.commit阶段

在render阶段的末尾会调用commitRoot(root);进入commit阶段&#xff0c;这里的root指的就是fiberRoot&#xff0c;然后会遍历render阶段生成的effectList&#xff0c;effectList上的Fiber节点保存着对应的props变化。之后会遍历effectList进行对应的dom操作和生命周期、hooks回…

【数据结构】知识点总结(C语言)

线性表、栈和队列、串、数组和广义表、树和二叉树、图、查找、排序线性表线性表&#xff08;顺序表示&#xff09;线性表是具有相同特性元素的一个有限序列&#xff0c;数据元素之间是线性关系&#xff0c;起始元素称为线性起点&#xff0c;终端元素称为线性终点。线性表的顺序…

sed 功能详解

介绍sedsed是一种流编辑器&#xff0c;它一次处理一行内容&#xff0c;把当前处理的行存储在临时缓冲区中&#xff08;buffer&#xff09;,称为"模式空间"&#xff0c;接着sed命令处理缓冲区中的内容&#xff0c;处理完成后&#xff0c;把缓冲区的内容送往屏幕&#…

RCEE: Event Extraction as Machine Reading Comprehension 论文解读

RCEE: Event Extraction as Machine Reading Comprehension 论文&#xff1a;Event Extraction as Machine Reading Comprehension (aclanthology.org) 代码&#xff1a;jianliu-ml/EEasMRC (github.com) 期刊/会议&#xff1a;EMNLP 2020 摘要 事件提取(Event extraction,…

哪个品牌蓝牙耳机性价比高?性价比高的平价蓝牙耳机推荐

现如今&#xff0c;随着蓝牙技术的进步&#xff0c;蓝牙耳机在人们日常生活中的便捷性更胜从前。越来越多的蓝牙耳机品牌被大众看见、认可。那么&#xff0c;哪个品牌的蓝牙耳机性价比高&#xff1f;接下来&#xff0c;我给大家推荐几款性价比高的平价蓝牙耳机&#xff0c;一起…

软件测试面试问答

笔试 笔试的话我们需要揣测具体会考什么内容&#xff0c;我们可以通过招聘信息去了解该公司需要什么样的技能&#xff0c;以此来准备笔试。一般必考的内容会有编程&#xff0c;测试用例设计&#xff0c;工作流程&#xff0c;逻辑思维等内容&#xff0c;除此之外每个公司可能还会…

移动端监听物理返回

业务场景&#xff1a;用户没有填完数据却不小心点到了回退按钮&#xff0c;此时需要展示确认弹框项目场景&#xff1a;vue2 uni-app Chrome Dev调试工具代码片段&#xff1a;onLoad(options){// 将当前url地址添加到浏览器的历史记录中window.history.pushState(null, null, …

OSI和TCP/IP网络模型细讲

文章目录一、OSI七层参考模型二、TCP/IP体系结构三、TCP/IP参考模型四、沙漏计时器形状的TCP/IP协议族五、两种国际标准对比相似之处不同之处一、OSI七层参考模型 OSI参考模型共分为7层&#xff0c;低三层面向通信&#xff0c;可用软硬件实现&#xff1b;高三层面向信息处理&am…

一个基于 LKM 的 Linux 内核级 rootkit 的实现

博客已迁移至&#xff1a;https://gls.show/ GitHub链接 演示Slides overview rootkit是一种恶意软件&#xff0c;攻击者可以在获得 root 或管理员权限后安装它&#xff0c;从而隐藏入侵并保持root权限访问。rootkit可以是用户级的&#xff0c;也可以是内核级的。关于rootk…

Android 实现菜单拖拽排序

效果图简介本文主角是ItemTouchHelper。它是RecyclerView对于item交互处理的一个「辅助类」&#xff0c;主要用于拖拽以及滑动处理。以接口实现的方式&#xff0c;达到配置简单、逻辑解耦、职责分明的效果&#xff0c;并且支持所有的布局方式。功能拆解功能实现4.1、实现接口自…