Xilinx FPGA:vivado关于真双端口的串口传输数据的实验

一、实验内容

      用一个真双端RAM,端口A和端口B同时向RAM里写入数据0-99,A端口读出单数并存入单端口RAM1中,B端口读出双数并存入但端口RAM2中,当检测到按键1到来时将RAM1中的单数读出显示到PC端,当检测到按键2到来时,将RAM2中的双数显示到pc端。

二、信号流向图

TIPS:这里我本来想将single_ram_1和single_ram_2分成两个单独的模块,但是经过实验后发现,如果分成两个单独的模块的话会导致:

       ①两个单端RAM模块的tx_start(0或1)都会有值给uart_tx模块,即使是RAM1给【1】,RAM2中没有值【0】,uart_tx模块是无法判断 tx_start 到底来自于哪个模块,所以此时uart_tx模块只是能接收到一个tx_start的脉冲信号,但是无法判断信号来自哪个RAM模块,无法获取到相应的uart_data ,最终导致tx_flag都无法变成高电平,那就更不会返回给RAM模块tx_done信号了。

       ②如果单独为了正确信号能赋值给tx_start而重新去写一个ctrl模块的话,那么在ctrl模块中将无法使用判断条件,因为我们将状态作为了赋值条件而不仅仅是key_flag信号。

       那么我的解决方法就是把single_ram_2例化到single_ram_1当中,将single_ram_2输出的数据(uart_data_b及tx_start_b)和single_ram_1输出的数据(douta即tx_start_a)全部放在一个模块即single_ram_1中去做判断,但是我们仍然无法将single_ram_2的状态作为赋值的条件,所以只能采用这种比较粗暴的方式,也就是除了( cur_state == REG || cur_state == READ )时候tx_start <= tx_start_a ;那么其他情况就是tx_start <= tx_start_b ; uart_data的处理也是同样。详见后面程序。

       其实最好的方式是将single_ram_2和single_ram_1写在同一个模块中,程序放在文章最后了。

三、程序设计

(1)按键消抖模块:

这里注意key1和key2不能使用同一个计数器,不然在同一个模块中也会判断出问题。

`timescale 1ns / 1ps
module key_debounce(input           sys_clk    ,input           rst_n      ,input           key1        ,input           key2        ,output          key_flag_1   ,output          key_flag_2);
//    parameter              delay = 100_000_0   ; //20msparameter              delay = 100;// 测试用reg[19:0]               cnt1   ;reg[19:0]               cnt2   ;key_flag_1  always@(posedge sys_clk )if(!rst_n)cnt1 <= 0 ;else if ( key1 == 0 )beginif ( cnt1 == delay -1 )cnt1 <= cnt1 ;else cnt1 <= cnt1 +1 ;endelsecnt1 <= 0 ;assign  key_flag_1 = ( cnt1 == delay -2 )?1:0 ;///key_flag_2always@(posedge sys_clk )if(!rst_n)cnt2 <= 0 ;else if ( key2 == 0 )beginif ( cnt2 == delay -1 )cnt2 <= cnt2 ;else cnt2 <= cnt2 +1 ;endelsecnt2 <= 0 ;assign  key_flag_2 = ( cnt2 == delay -2 )?1:0 ;  endmodule

(2)真双端模块:

IP参数:

`timescale 1ns / 1ps
module the_true_ram(input                 sys_clk     ,input                 rst_n       ,output  [7:0]         ram_odd_data  ,output  [7:0]         ram_even_data);A端口reg          wea     ;reg  [6 : 0] addra   ;reg  [7 : 0] dina    ;wire [7 : 0] douta   ;always@(posedge sys_clk )if(!rst_n)wea <= 0 ;else if ( addra >= 99 )wea <= 0 ;elsewea <= 1 ;always@(posedge sys_clk )if(!rst_n)addra <= 0 ;else if ( addra >= 99 )addra <= 99 ;elseaddra <= addra +1 ;always@(posedge sys_clk )if(!rst_n)dina <= 0 ;else if (dina >= 99)dina <= 99 ;elsedina <= dina +1 ;wire [7:0]        data_a  ;assign       data_a = douta ;assign       ram_odd_data = (data_a%2 == 1)?data_a : ram_odd_data ;///b端口reg          web    ; reg  [6 : 0] addrb  ;reg  [7 : 0] dinb   ;wire [7 : 0] doutb  ;always@(posedge sys_clk )if(!rst_n)web <= 0 ;else if ( addrb >= 99 )web <= 0 ;elseweb <= 1 ;always@(posedge sys_clk )if(!rst_n)addrb <= 0 ;else if ( addrb >= 99 )addrb <= 99 ;elseaddrb <= addrb +1 ;always@(posedge sys_clk )if(!rst_n)dinb <= 0 ;else if ( dinb >= 99 )dinb <= 99 ;elsedinb <= dinb +1 ;wire[7:0]   data_b  ;assign      data_b = doutb ;assign      ram_even_data = (data_b %2 == 0 )? data_b : ram_even_data ;//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
true_ram your_instance_name (.clka(sys_clk ),    // input wire clka.ena(1),      // input wire ena.wea(wea),      // input wire [0 : 0] wea.addra(addra),  // input wire [6 : 0] addra.dina(dina),    // input wire [7 : 0] dina.douta(douta),  // output wire [7 : 0] douta.clkb(sys_clk ),    // input wire clkb.enb(1),      // input wire enb.web(web),      // input wire [0 : 0] web.addrb(addrb),  // input wire [6 : 0] addrb.dinb(dinb),    // input wire [7 : 0] dinb.doutb(doutb)  // output wire [7 : 0] doutb
);
// INST_TAG_END ------ End INSTANTIATION Template ---------endmodule

(3)单端RAM2模块:

但其实深度在50就够用了。(100里面的奇数和偶数50)

`timescale 1ns / 1ps
module single_ram_2_FMS(input               sys_clk        ,input               rst_n          ,input               key_flag_2     ,input               tx_done        ,input    [7:0]      ram_even_data  ,output   reg        tx_start_b       ,output   reg[7:0]   uart_data_b);存双数的RAMreg          ena           ;reg  [0 : 0] wea           ;reg  [6 : 0] addra         ;reg  [7 : 0] dina          ;wire [7 : 0] douta         ;//先写再读出localparam         IDLE  = 3'd0 ;localparam         WRITE = 3'd1 ;localparam         REG   = 3'd2 ;localparam         READ  = 3'd3 ;reg[2:0]           cur_state    ;reg[2:0]           next_state   ;//state1always@(posedge sys_clk )if(!rst_n)cur_state <= IDLE ;else cur_state <= next_state ;//state2always@(*)case(cur_state)IDLE  :beginnext_state = WRITE ;endWRITE :beginif ( key_flag_2 )next_state = REG ;elsenext_state = cur_state ;endREG   :beginnext_state = READ ;endREAD  :beginif(addra == 49)next_state = IDLE ;elsenext_state <= cur_state ;enddefault:;endcase//state3always@(posedge sys_clk )if(!rst_n)beginena   <= 0 ;wea   <= 0 ;addra <= 0 ;dina  <= 0 ;tx_start_b <= 0 ;endelsecase(cur_state)IDLE   :beginena   <= 0 ;wea   <= 0 ;addra <= 0 ;dina  <= ram_even_data ;endWRITE  :beginena <= 1 ;wea <= 1 ;if(addra == 49)addra <= 49 ;elseaddra <= addra +1 ;dina <= ram_even_data ;endREG    :beginaddra <= 0 ;ena   <= 0 ;wea   <= 0 ;dina  <= 0 ;tx_start_b <= 1 ;endREAD   :beginena <= 1 ;wea <= 0 ;dina<= 0 ;if(tx_done)begintx_start_b <= 1 ;addra <= addra +1 ;endelse begintx_start_b <= 0 ;addra <= addra ;endenddefault:;endcase//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
single_ram ram2 (.clka(sys_clk ),    // input wire clka.ena(ena),      // input wire ena.wea(wea),      // input wire [0 : 0] wea.addra(addra),  // input wire [6 : 0] addra.dina(dina),    // input wire [7 : 0] dina .douta(douta)  // output wire [7 : 0] douta
);
// INST_TAG_END ------ End INSTANTIATION Template ---------always@(posedge sys_clk )if(!rst_n)uart_data_b <= 0 ;else if ( cur_state == READ )uart_data_b <= douta ;elseuart_data_b <= uart_data_b ;always@(posedge sys_clk )if(!rst_n)tx_start_b <= 0 ;else if ( cur_state == REG || cur_state == READ  )tx_start_b <= 1 ;elsetx_start_b <= tx_start_b ;  endmodule

(4)单端RAM1模块

配置和前面一样

`timescale 1ns / 1ps
module single_ram_1_FMS(input                 sys_clk      ,input                 rst_n        ,input                 key_flag_1   ,input                 key_flag_2   ,input                 tx_done      ,input[7:0]            ram_odd_data ,input[7:0]            ram_even_data,output      reg       tx_start     ,output   reg[7:0]     uart_data        );/读单数的RAMreg          ena     ;       reg          wea     ;reg  [6 : 0] addra   ;reg  [7 : 0] dina    ;wire [7 : 0] douta   ;reg           tx_start_a  ;wire           tx_start_b     ; wire[7:0]      uart_data_b    ; 先写再读出localparam             IDLE   = 3'd0 ;localparam             ERITE  = 3'd1 ;localparam             REG    = 3'd2 ;localparam             READ   = 3'd3 ;reg[2:0]        cur_state    ;reg[2:0]        next_state   ;//state1always@(posedge sys_clk )if(!rst_n)cur_state <= IDLE  ;elsecur_state <= next_state ;//state2always@(*)case(cur_state)IDLE  :beginnext_state = ERITE ;endERITE :beginif(key_flag_1)next_state = REG ;elsenext_state <= cur_state ;endREG   :beginnext_state = READ ;//用来发送tx_startendREAD  :beginif(addra == 49)//100内的单数是50next_state = IDLE ;elsenext_state = cur_state ;enddefault:;endcase//state3always@(posedge sys_clk )if(!rst_n)beginena  <= 0 ;wea  <= 0 ;addra<= 127 ;dina <= 0 ;tx_start_a <= 0 ;endelsecase(cur_state)IDLE  :beginena  <= 0 ;wea  <= 0 ;addra<= 7'd127 ;dina <= ram_odd_data ;endERITE :beginena <= ~ena ;wea <= ~wea ;if( addra == 49 && wea)addra <= 49 ;else if(wea)addra <= addra +1 ;dina <= ram_odd_data ;endREG   :beginena  <= 0 ;         wea  <= 0 ;         addra<= 0 ;         dina <= 0 ;   tx_start_a <= 1 ;                            endREAD  :beginena <= 1 ;wea <= 0 ;dina<= 0 ;if(tx_done)begintx_start_a <= 1 ;addra <= addra +1 ;endelse begintx_start_a <= 0 ;addra <= addra ;endenddefault:;endcase//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
single_ram ram1 (.clka(sys_clk ),    // input wire clka.ena(ena),      // input wire ena.wea(wea),      // input wire [0 : 0] wea.addra(addra),  // input wire [6 : 0] addra.dina(dina),    // input wire [7 : 0] dina.douta(douta)  // output wire [7 : 0] douta
);
// INST_TAG_END ------ End INSTANTIATION Template ---------always@(posedge sys_clk )if(!rst_n)uart_data <= 0;else if ( cur_state == READ )uart_data <= douta ;elseuart_data <= uart_data_b ;always@(posedge sys_clk )if(!rst_n)tx_start <= 0 ;else if ( cur_state == REG || cur_state == READ  )tx_start <= tx_start_a ;elsetx_start <= tx_start_b ; 例化ram2 single_ram_2_FMS  single_ram_2_FMS_u(.  sys_clk       (sys_clk      )    ,.  rst_n         (rst_n        )    ,.  key_flag_2    (key_flag_2   )    ,.  tx_done       (tx_done      )    ,.  ram_even_data (ram_even_data)    ,.  tx_start_b    (tx_start_b   )    ,.  uart_data_b   (uart_data_b  ));   endmodule

(5)uart_tx模块:

`timescale 1ns / 1ps
module uart_tx(input               sys_clk   ,input               rst_n     ,input  wire[7:0]   uart_data ,input               rx_done   ,        output   reg        tx_data   , output   reg        tx_done);parameter         SYSCLK =   50_000_000  ;parameter         Baud   =   115200      ;parameter         COUNT  =   SYSCLK/Baud ;//434   传输1比特所需要的时钟周期parameter         MID    =   COUNT/2     ;wire                 start_flag ;reg                  tx_flag   ;reg                  tx_reg1   ;reg                  tx_reg2   ;reg[4:0]             cnt_bit   ;reg[10:0]            cnt       ;//tx_startalways@(posedge sys_clk)if(!rst_n)begintx_reg1 <= 0 ;tx_reg2 <= 0 ;endelse begintx_reg1 <= rx_done  ;tx_reg2 <= tx_reg1  ;endassign  start_flag = tx_reg1 & ~tx_reg2 ;///tx_flagalways@(posedge sys_clk)if(!rst_n)tx_flag <= 0 ;else if ( start_flag == 1 )tx_flag <= 1 ;else if ( cnt == COUNT -1 && cnt_bit == 10)
//         else if ( cnt == MID -1 && cnt_bit == 10)tx_flag <= 0 ;elsetx_flag <= tx_flag ;///计时器//    cnt 434  always@(posedge sys_clk )if(!rst_n)cnt <= 0;else if ( tx_flag == 1 )beginif ( cnt == COUNT -1) ///一定要减一,如果不减一,实际会计到435次,反算回去波特率就不是115200了cnt <= 0;elsecnt <= cnt +1 ;endelsecnt <= 0 ;//  /计数器always@(posedge sys_clk )if(!rst_n)cnt_bit <= 0 ;else if ( tx_flag )beginif ( cnt == COUNT -1)beginif(cnt_bit == 10)///0123456789 10cnt_bit <= 0 ;elsecnt_bit <= cnt_bit +1 ;endelsecnt_bit <= cnt_bit     ;endelsecnt_bit <= 0 ;parameter             MODE_CHECK = 0 ;always@(posedge sys_clk )if(!rst_n)tx_data <= 1 ;   //表示没有数据else if ( tx_flag )beginif (   cnt_bit > 0 && cnt_bit < 9 )///cnt_bit 0 12345678 9 ///tx_data 0123456789///uart_data 01234567tx_data <= uart_data [cnt_bit-1]; //这里uart_data是不断随着cnt_bit变化的,只有在第九位的时候才有正确的最终值else if(cnt_bit == 0)tx_data <= 0 ;else if(cnt_bit == 9)tx_data <= (MODE_CHECK == 0)? ^uart_data: ~^uart_data;/*MODE_CHECK == 0是偶校验,假如uart_data是1110_0000,其异或的结果是1,将异或的结果作为校验位,让数据位和校验位异或的结果为0,满足偶校验。假如uart_data是1110_1000,其异或的结果是0,将异或的结果作为校验位,让数据位和校验位异或的结果为0,满足偶校验。奇校验则相反。*/else if (cnt_bit == 10)///停止位tx_data <= 1 ;elsetx_data <= tx_data ;endelsetx_data <= 1 ;always@(posedge sys_clk )if(!rst_n)           tx_done <= 0 ;else if (tx_flag)beginif ( cnt_bit == 10 && cnt == COUNT -1)
//               if ( cnt_bit == 10 && cnt == MID/2 -1)tx_done <= 1 ;elsetx_done <= 0 ;       endelsetx_done <= 0 ;  
endmodule

四、仿真模块

(1)仿真true_ram模块

代码:

`timescale 1ns / 1ps
module test_the_true_ram( );reg                 sys_clk       ;reg                 rst_n         ;wire  [7:0]         ram_odd_data  ;wire  [7:0]         ram_even_data ;initialbeginsys_clk = 0 ;rst_n   = 0 ;#10  rst_n = 1 ;endalways #1 sys_clk = ~sys_clk ; the_true_ram the_true_ram_1(.   sys_clk       (sys_clk      )    ,.   rst_n         (rst_n        )    ,.   ram_odd_data  (ram_odd_data )    ,.   ram_even_data (ram_even_data));endmodule

仿真结果:

(2)仿真TOP:

代码:

`timescale 1ns / 1ps
module test_TOP( );reg                sys_clk   ;reg                rst_n     ;reg                key_1     ;reg                key_2     ;wire               tx_data   ;initialbeginsys_clk = 0 ;rst_n   = 0 ;key_1   = 1 ;key_2   = 1 ;#10rst_n   = 1 ;#10000key_1   = 0 ;endalways #1 sys_clk = ~sys_clk ;TOP TOP_1(.    sys_clk  (sys_clk)   ,.    rst_n    (rst_n  )   ,.    key_1    (key_1  )   ,.    key_2    (key_2  )   ,.    tx_data  (tx_data)  );endmodule

 仿真结果:

TOP:

single_ram_1 :

五、需要注意的一些问题

(1)

(2)

(3)控制模块最好这么写

`timescale 1ns / 1ps
module single_ram_2(input               sysclk          ,input               rst_n           ,input               key_flag1       ,input               key_flag2       ,input               tx_done         ,input       [7:0]   ram_odd_data    , //单数input       [7:0]   ram_even_data   , //双数output  reg         tx_start        ,output  reg [7:0]   uart_data            );
//存单数的RAM
reg          wea    ;
reg          ena    ;
reg   [6:0] addra  ;
reg   [7:0] dina   ;
wire  [7:0] douta  ;
///先写再读出
localparam      IDLE  = 3'd0;
localparam      WRITE = 3'd1; 地址加1
localparam      REG   = 3'd2;  ///缓冲状态   地址清零
localparam      READ  = 3'd3;
reg     [2:0]   cur_state,next_state;
reg             tx_start_a  ;
always@(posedge sysclk)if(!rst_n)cur_state <= IDLE;elsecur_state <= next_state;
always@(*)case(cur_state)IDLE  : beginif(key_flag1)next_state = WRITE;elsenext_state = cur_state;end   WRITE :beginif(addra >= 49)next_state = REG;elsenext_state = cur_state; endREG   :beginnext_state = READ;endREAD  :beginif(addra >= 49)next_state = IDLE;elsenext_state = cur_state;    enddefault:;endcase
always@(posedge sysclk)if(!rst_n)beginaddra <= 0;wea <= 0;ena <= 0;dina <= 0;tx_start_a <= 0;endelsecase(cur_state)IDLE  :beginaddra <= 0;wea <= 0;ena <= 0;dina <= ram_odd_data;  维持2个endWRITE :begin   ///99/48ena <= ~ena;     ///wea <= ~wea;     ///if(addra >= 49)addra <= 49;else if(wea)addra <= addra + 1; dina <= ram_odd_data;endREG   :beginaddra <= 0;ena <= 0;wea <= 0;dina <= 0;tx_start_a <= 1;   ///发送第一个数据endREAD  :begin  ena <= 1;wea <= 0;dina <= 0;if(tx_done)begintx_start_a <= 1;addra <= addra + 1;endelse begintx_start_a <= 0;addra <= addra;end     enddefault:; endcaseblk_mem_gen_2 ram_a (.clka(sysclk),    // input wire clka.ena(ena),      // input wire ena.wea(wea),      // input wire [0 : 0] wea.addra(addra),  // input wire [6 : 0] addra.dina(dina),    // input wire [7 : 0] dina.douta(douta)  // output wire [7 : 0] douta
);
/b端口    存双数
reg             web   ;
reg             enb    ;
reg  [6:0]      addrb ;
reg  [7:0]      dinb  ;
wire [7:0]      doutb;
//状态机
///先写再读出
localparam      RD_IDLE  = 3'd4;
localparam      RD_WRITE = 3'd5;
localparam      RD_REG   = 3'd6;  ///缓冲状态
localparam      RD_READ  = 3'd7;
reg     [2:0]   rd_cur_state,rd_next_state;
reg             tx_start_b      ;
always@(posedge sysclk)if(!rst_n)rd_cur_state <= RD_IDLE;elserd_cur_state <= rd_next_state;
always@(*)case(rd_cur_state)RD_IDLE  : beginif(key_flag2)rd_next_state = RD_WRITE;elserd_next_state = rd_cur_state;end   RD_WRITE :beginif(addrb >= 49)rd_next_state = RD_REG;elserd_next_state = rd_cur_state; endRD_REG   :beginrd_next_state = RD_READ;endRD_READ  :beginif(addrb >= 49)rd_next_state = RD_IDLE;elserd_next_state = rd_cur_state;    enddefault:;endcase
always@(posedge sysclk)if(!rst_n)beginaddrb <= 0;web <= 0;enb <= 0;dinb <= 0;tx_start_b <= 0;endelsecase(rd_cur_state)RD_IDLE  :beginaddrb <= 0;web <= 0;enb <= 0;dinb <= ram_even_data;  ///020406endRD_WRITE :beginenb <= ~enb;  web <= ~web;if(addrb >= 49)addrb <= 49;else if(web)addrb <= addrb + 1; dinb <= ram_even_data;endRD_REG   :beginaddrb <= 0;enb <= 0;web <= 0;dinb <= 0;tx_start_b <= 1;endRD_READ  :begin  enb <= 1;web <= 0;dinb <= 0;if(tx_done)begintx_start_b <= 1;addrb <= addrb + 1;endelse begintx_start_b <= 0;addrb <= addrb;end     enddefault:; endcase
blk_mem_gen_2 ram_b (.clka(sysclk),    // input wire clka.ena(enb),      // input wire ena.wea(web),      // input wire [0 : 0] wea.addra(addrb),  // input wire [6 : 0] addra.dina(dinb),    // input wire [7 : 0] dina.douta(doutb)  // output wire [7 : 0] douta
);
always@(posedge sysclk)if(!rst_n)uart_data <= 0;else if(cur_state == READ )uart_data <= douta  ;else if(rd_cur_state == RD_READ )uart_data <= doutb  ;elseuart_data <= uart_data;always@(posedge sysclk)if(!rst_n)tx_start <= 0;else if(cur_state == REG || cur_state == READ)tx_start <= tx_start_a;else if(rd_cur_state == RD_REG || rd_cur_state == RD_READ)tx_start <= tx_start_b;elsetx_start <= tx_start;endmodule

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

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

相关文章

Vim编辑器与Shell命令脚本

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 目录 一、Vim文本编辑器 二、编写Shell脚本 三、流程控制语句 四、计划任务服务程序 致谢 一、Vim文本编辑器 “在Linux系统中一切都是文件&am…

dependencyManagement的作用、nacos的学习

使用SpringCloudAlibaba注意各组件的版本适配 SpringCloudAlibaba已经包含了适配的各组件&#xff08;nacos、MQ等&#xff09;的版本号&#xff0c;也是一个版本仲裁者&#xff0c;但是可能已经有了父项目Spring-Boot-Starter-Parent这个版本仲裁者&#xff0c;又不能加多个父…

6、Redis系统-数据结构-06-跳表

六、跳表&#xff08;Skiplist&#xff09; 跳表是一种高效的动态数据结构&#xff0c;可以用于实现有序集合&#xff08;Sorted Set&#xff0c;Zset&#xff09;。与平衡树相比&#xff0c;跳表具有实现简单、效率高的优点&#xff0c;因此被 Redis 选用作为有序集合的底层数…

阶段三:项目开发---搭建项目前后端系统基础架构:任务13:实现基本的登录功能

任务描述 任务名称&#xff1a; 实现基本的登录功能 知识点&#xff1a; 了解前端Vue项目的基本执行过程 重 点&#xff1a; 构建项目的基本登陆功能 内 容&#xff1a; 通过实现项目的基本登录功能&#xff0c;来了解前端Vue项目的基本执行过程&#xff0c;并完成基…

如何让代码兼容 Python 2 和 Python 3?Future 库助你一臂之力

目录 01Future 是什么? 为什么选择 Future? 安装与配置 02Future 的基本用法 1、兼容 print 函数 2、兼容整数除法 3、兼容 Unicode 字符串 03Future 的高级功能 1. 处理字符串与字节 2. 统一异常处理…

移动校园(7)ii:uniapp路由响应拦截器处理token,以及微信小程序报错当前页面正在处于跳转状态,请稍后再进行跳转....

依据昨天的写完&#xff0c;在token过期之后&#xff0c;再次调用接口&#xff0c;会触发后端拦截&#xff0c;扔进全局错误处理中间件 前端说明提示都没有&#xff0c;只有一个这个&#xff0c;现在优化一下&#xff0c;再写一个类似全局后置守卫&#xff0c;当状态码是401的时…

增强安全防护,解读智慧校园系统的登录日志功能

在构建智慧校园系统时&#xff0c;登录日志功能扮演着不可或缺的角色&#xff0c;它不仅是系统安全的守护者&#xff0c;也是提升管理效率和确保合规性的有力工具。这一机制详细记录每次登录尝试的方方面面&#xff0c;涵盖了时间戳、用户身份、登录来源的IP地址乃至使用的设备…

phpcms 升级php8.3.8

windows 2008 server 不支持php8.3.8,需升级为windows 2012 1.下载php8.3.8 PHP8.3.9 For Windows: Binaries and sources Releases 2.配置php.ini (1.)在php目录下找到php.ini-development文件&#xff0c;把它复制一份&#xff0c;改名为php.ini (2.)修改php安装目录 根…

C++模板元编程(二)——完美转发

完美转发指的是函数模板可以将自己的参数“完美”地转发给内部调用的其它函数。所谓完美&#xff0c;即不仅能准确地转发参数的值&#xff0c;还能保证被转发参数的左、右值属性不变。 文章目录 场景旧的方法新的方法内部实现参考文献 场景 思考下面的代码&#xff1a; templ…

专业140+总分420+天津大学815信号与系统考研经验天大电子信息与通信工程,真题,大纲,参考书。

顺利上岸天津大学&#xff0c;专业课815信号与系统140&#xff0c;总分420&#xff0c;总结一些自己的复习经历&#xff0c;希望对于报考天大的同学有些许帮助&#xff0c;少走弯路&#xff0c;顺利上岸。专业课&#xff1a; 815信号与系统&#xff1a;指定教材吴大正&#xf…

2-26 基于matlab开发的制冷循环模型

基于matlab开发的制冷循环模型。Simscape两相流域中的制冷循环模型&#xff0c;在simulink中完成多循环温度控制。程序已调通&#xff0c;可直接运行。 2-26 制冷循环模型 Simscape两相流域 - 小红书 (xiaohongshu.com)

Arduino ESP8266 开发环境搭建

Arduino ESP8266 开发环境搭建 很久之前学嵌入式时&#xff0c;用过Arduino8266进行开发&#xff0c;开发成本低、难度小&#xff0c;体验很不错。 近期&#xff0c;又突然要用&#xff0c;遂再次搭建环境&#xff0c;但变动挺多&#xff0c;有些小波折&#xff0c;开贴记录。…

高考志愿填报千万要注意这四点

在高考志愿填报过程中&#xff0c;确实有很多需要留心的点。我为你总结了四个关键点&#xff0c;希望能帮助你顺利完成志愿填报&#xff1a; 1、学校提供的支持 学校作为学生志愿填报咨询服务的主阵地&#xff0c;应提供体系化和制度化的支持。包括及时关注并传达政策动向和相…

行内元素、块级元素居中

行内元素居中 水平居中 {text-align&#xff1a;center;}垂直居中 单行——行高等于盒子高度 <head><style>.father {width: 400px;height: 200px;/* 行高等于盒子高度&#xff1a;line-height: 200px; */line-height: 200px;background-color: pink;}.son {}&…

如何做好IT类的技术面试?

我们在找工作时&#xff0c;需要结合自己的现状&#xff0c;针对意向企业做好充分准备。作为程序员&#xff0c;你有哪些面试IT技术岗的技巧&#xff1f; 方向一&#xff1a;分享你面试IT公司的小技巧 我分享一些基于广泛观察和用户反馈的面试IT公司的小技巧&#xff1a; 技术准…

孟德尔随机化-痛风

写在前面 昨天看到文献&#xff0c;称饮酒与痛风无关联&#xff0c;甚是疑惑&#xff0c;今天刚好看了一篇新文献&#xff0c;虽然不是主要讲饮酒与痛风的&#xff0c;但也有牵扯到这方面内容&#xff0c;而且是相反的内容&#xff0c;特记录一下。 孟德尔随机化-受教育程度与…

vuepress创建步骤

背景 记录vuepress配置步骤&#xff0c;以便下次使用快速上手。 读此文章之前默认您已经学会了创建vuepress项目。vuepres快速开始 最终成品 doc.jeecgflow.com 配置步骤 创建.vuepress 目录。 你的文档目录下创建一个 .vuepress 目录。 创建.vuepress/config.js module.e…

Mac窗口辅助管理工具:Magnet for mac激活版

magnet mac版是一款运行在苹果电脑上的一款优秀的窗口大小控制工具&#xff0c;拖拽窗口到屏幕边缘可以自动半屏&#xff0c;全屏或者四分之一屏幕&#xff0c;还可以设定快捷键完成分屏。这款专业的窗口管理工具当您每次将内容从一个应用移动到另一应用时&#xff0c;当您需要…

注意力机制 attention Transformer 笔记

动手学深度学习 这里写自定义目录标题 注意力加性注意力缩放点积注意力多头注意力自注意力自注意力缩放点积注意力&#xff1a;案例Transformer 注意力 注意力汇聚的输出为值的加权和 查询的长度为q&#xff0c;键的长度为k&#xff0c;值的长度为v。 q ∈ 1 q , k ∈ 1 k …

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第54课-poplang语音编程控制机器人

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第54课-poplang语音编程控制机器人 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的…