Verilog 学习第五节(串口接收部分)
小梅哥串口部分学习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
仿真截图

相关文章:
Verilog 学习第五节(串口接收部分)
小梅哥串口部分学习part2 串口通信接收原理串口通信接收程序设计与调试巧用位操作优化串口接收逻辑设计串口接收模块的项目应用案例串口通信接收原理 在采样的时候没有必要一直判断一个clk内全部都是高/低电平,如果采用直接对中间点进行判断的话,很有可能…...
AIX系统常见漏洞修复(exec、rlogin、rsh、ftp、telnet远端服务运行中)
漏洞:1.1 SSH 服务支持弱加密算法 1. 使用telnet 登录2.vi /etc/ssh/sshd_config 最后添加一下内容(去掉 arcfour、arcfour128、arcfour256 等弱加密算法) Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,blowfish-cbc,cast…...
IEEE SLT 2022论文丨如何利用x-vectors提升语音鉴伪系统性能?
分享一篇IEEE SLT 2022收录的声纹识别方向的论文,《HOW TO BOOST ANTI-SPOOFING WITH X-VECTORS》由AuroraLab(极光实验室)发表。 来源丨AuroraLab AuroraLab源自清华大学电子工程系与新疆大学信息科学与工程学院,以说话人识别和…...
设计模式(十三)----结构型模式之桥接模式
1 概述 现在有一个需求,需要创建不同的图形,并且每个图形都有可能会有不同的颜色。我们可以利用继承的方式来设计类的关系: 我们可以发现有很多的类,假如我们再增加一个形状或再增加一种颜色,就需要创建更多的类。 试…...
倾向得分匹配案例分析
一、倾向得分匹配法说明 倾向得分匹配模型是由Rosenbaum和Rubin在1983年提出的,首次运用在生物医药领域,后来被广泛运用在药物治疗、计量研究、政策实施评价等领域。倾向得分匹配模型主要用来解决非处理因素(干扰因素)的偏差。 …...
基于SpringCloud的可靠消息最终一致性04:项目基础代码
上一节给出了项目需求和骨架代码,这一节来接着看基础代码。骨架代码和基础代码最主要的区别是:骨架代码都是数据库脚本、POM依赖文件、配置文件内容、运维脚本等,而基础代码则是和业务有关联,但并非关键代码的部分。 这些代码不用一个个地看,主要是看看结构就行。 图二十五…...
操作系统权限提升(十八)之Linux提权-内核提权
Linux 内核提权 Linux 内核提权原理 内核提权是利用Linux内核的漏洞进行提权的,内核漏洞进行提权一般包括三个环节: 1、对目标系统进行信息收集,获取到系统内核信息及版本信息; 2、根据内核版本获取其对应的漏洞以及EXP 3、使…...
华为OD机试真题Java实现【快递运输】真题+解题思路+代码(20222023
快递运输 题目 一辆运送快递的货车,运送的快递均放在大小不等的长方体快递盒中,为了能够装载更多的快递,同时不能让货车超载,需要计算最多能装多少个快递。 注:快递的体积不受限制,快递数最多1000个,货车载重最大50000。 🔥🔥🔥🔥🔥👉👉👉👉👉�…...
java面试题-JVM问题排查
1.常见的Linux定位问题的工具?常见的 Linux 定位问题的命令可以分为以下几类:系统状态命令:包括 top、uptime、vmstat、sar 等命令,用于查看系统整体的状态,如 CPU 使用率、内存使用率、磁盘 I/O 等。进程状态命令&…...
市场上有很多低代码开发平台,不懂编程的人可以用哪些?
市场上有很多低代码开发平台,不懂编程的人可以用哪些?这个问题一看就是外行问的啦,低代码平台主打的就是一个“全民开发”,而且现在很多低代码平台都发展为零代码了,不懂编程也完全可以使用! 所谓低代码开…...
Tina_Linux打包流程说明指南_new
OpenRemoved_Tina_Linux_打包流程_说明指南_new 1 概述 1.1 编写目的 介绍Allwinner 平台上打包流程。 1.2 适用范围 Allwinner 软件平台Tina v3.0 版本以上。 1.3 相关人员 适用Tina 平台的广大客户,想了解Tina 打包流程的开发人员。 2 固件打包简介 固件…...
JVM面试题
JVM 1.jvm的组成部分 类加载器:将javac编译的class文件加载到内存中 运行时数据区:将内存划分成若干个不同的区域。 执行引擎:负责解析命令,提交操作系统执行。 本地接口:融合不同的语言为java所用 2.运行时数据区 方法区&…...
@FeignClient注解
1.在启动类上开启Feign功能 不开会提示找不到所需要的bean Consider defining a bean of type in your configuration SpringBootApplication EnableFeignClients public class AuthApplication {public static void main(String[] args) {SpringApplication.run(AuthApplic…...
一文搞懂如何在 React 中使用 防抖(Debounce)和 节流(Throttle)
在前端的日常开发中,经常会使用到两个函数防抖(Debounce)和节流(Throttle),防抖函数可以有效控制在一段时间内只执行最后一次请求,例如搜索框输入时,只在输入完成后才进行请求接口。…...
Airbyte API
Airbyte API涵盖了Airbyte功能的方方面面,主要分类:Source_definition:来源定义,实现了来源的增删改查功能。Destination_definition:目标定义,实现了目标的增删改查功能。Workspace:工作区管理…...
vue项目使用Electron开发桌面应用
添加npm配置避免安装Electron错误 请确保您的 node 版本大于等于 18. cmd运行: npm config edit 该命令会打开npm的配置文件,请在空白处添加: electron_builder_binaries_mirrorhttps://npmmirror.com/mirrors/electron-builder-binaries/ e…...
std::chrono笔记
文章目录1. radio原型作用示例2. duration原型:作用示例3. time_point原型作用示例4. clockssystem_clock示例steady_clock示例high_resolution_clock先说感觉,这个库真恶心,刚接触感觉跟shi一样,特别是那个命名空间,太…...
接收arp请求并发送回应的实例
本文简单介绍了arp协议,用一个实例查看收到的ARP请求,并对该请求发出ARP回应,实例有完整的源代码,使用C语言在Linux下实现,代码中有详细的注释。 1. ARP协议 ARP(Address Resolution Protocol),地址解析协议;在局域网上通过IP地址获取物理地址MAC的协议,该协议工作在数…...
【高性能计算】TVM使用TE手动优化矩阵乘法算法解析与代码解读
引言 注:本文主要介绍、解释TVM的矩阵优化思想、代码,需要配合代码注释一起阅读。 矩阵乘法是计算密集型运算。为了获得良好的 CPU 性能,有两个重要的优化措施: 提高内存访问的高速缓存命中率。复杂的数值计算和热点内存&#x…...
消息中间件的概念
中间件(middleware)是基础软件的一大类,属于可复用的软件范畴。中间件在操作系统软件,网络和数据库之上,应用软件之下,总的作用是为处于自己上层的应用软件提供运行于开发的环境,帮助用户灵活、高效的开发和集成复杂的…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
