基于FPGA的智能电子密码指纹锁(开源全免)

基于FPGA的智能电子密码指纹锁

  • 一、功能描述
      • 硬件资源需求
  • 二、整体框架
    • 知识准备
      • AS608指纹模块
      • 4*4数字键盘模块
  • 三、Verilog代码实现以及仿真验证
    • 1.AS608_data模块
    • 2.check_hand模块
    • 3.four_four_key模块
    • 4.check_mima模块
    • 5.change_mima模块
    • 6.seg_ctrl模块
    • 7.uart_top模块
    • 8.key_debounce模块
    • 9.TOP模块
    • 9.仿真tb文件
  • 总结

一、功能描述

1.6位密码,可修改,数码管显示输入密码过程,错误一定次数后报警
2.指纹验证,验证正确与错误对应的灯闪烁
3.4*4数字键盘,输入密码使用
4.板卡按键,负责状态切换

硬件资源需求

AS608 指纹模块
在这里插入图片描述
4*4数字键盘模块
在这里插入图片描述
再就是开发板上的一些按键、LED灯等等资源了。

二、整体框架

根据模块以及功能分别编写代码,TOP顶层模块、AS608指纹模块、串口通信模块、指纹检测模块、密码输入检测模块、修改密码模块以及数码管显示模块。如图所示,vavido根据代码调用关系自动生成的原理图。
在这里插入图片描述

知识准备

AS608指纹模块

通信方式:UART
通信速率:9600*N(N:1~12),默认57600
通信格式:遵循手册按照数据格式发送不同的指令数据,根据返回的数据包判断实际状态。
使用流程:
存指纹:读取指纹图像->生成特征1->读取指纹图像->生成特征2->对比特征->生成指纹模版
刷指纹:读取指纹图像->生成特征->搜索指纹图像
删除指纹:删除指纹/删除整个指纹库

例如:读取指纹图像
在这里插入图片描述
可以通过TTL与指纹模块连接,通过串口调试助手进行实验:
发:EF 01 FF FF FF FF 01 00 03 01 00 05
收:EF 01 FF FF FF FF 07 00 03 00 00 0A

因此后续模块代码编写就是基于功能发送不同的指令包数据

4*4数字键盘模块

如图,要明确该模块通过4+4根线控制,读取16个按键状态。其中4条行线作为output,4条列线作为input。
整体读取按键流程:给P10这一行高电平,扫描列,如果检测到P15为高电平,说明第一行第二个按键按下。也就是代码要循环给予不同行高电平,然后确定列状态,进而确定按键。output:1000,input是0100,就说明第一行第二个按键被按下。
模块

三、Verilog代码实现以及仿真验证

1.AS608_data模块

实现思想:状态机

在这里插入图片描述
一路顺利就是这么个流程,不顺利的话就回到上个可以重新开始的流程。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/12/01 21:43:28
// Design Name: 
// Module Name: AS608_data
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module AS608_data(input           clk,input           rst_n,input           WAK,input           key1,input           key2,input           key3,input           key4,input           key5,input           uart_tx_done,input  [7:0]    uart_rx_data,input           uart_rx_done,output  reg     led_hand1,output  reg     led_hand2,output  reg     led_hand3,output  reg     hand_flag_r1,output  reg     check_hand_flag,output  reg             uart_tx_en,output  reg     [7:0]   uart_tx_data);parameter IDLE              = 8'd0;parameter WAK_HAND1         = 8'd20;parameter WAK_HAND2         = 8'd21;parameter WAK_FEATURE1      = 8'd22;parameter WAK_FEATURE2      = 8'd23;parameter WAK_COMPARE       = 8'd24;         parameter WAK_SAVE          = 8'd25;parameter WAK_SEND          = 8'd26;parameter WAK_FIND          = 8'd27;parameter HAND1_LED          = 8'd28;parameter HAND2_LED          = 8'd29;parameter SAVE_LED          = 8'd30;parameter GET_HAND1         = 8'd1;parameter GET_HAND2         = 8'd2;parameter GET_HAND_DONE     = 8'd3;   parameter SEND_HAND         = 8'd4;  parameter SEND_HAND_DONE    = 8'd5;parameter MAKE_FEATURE1     = 8'd6;  parameter MAKE_FEATURE2     = 8'd7;  parameter MAKE_DONE         = 8'd8;parameter COMPARE_FEATURE   = 8'd9;parameter SEND_FEATURE      = 8'd10;parameter SAVE_FEATURE      = 8'd11;parameter FIND_HAND         = 8'd12;parameter DELDETE_FEATURE   = 8'd13;parameter DELDETE_ALL_FEATURE   = 8'd14;reg     [95:0]   cmd_state   ={8'hEF,8'h01,8'hFF,8'hFF,8'hFF,8'hFF,8'h01,8'h00,8'h03,8'h01,8'h00,8'h05};
//应答格式 EF01 FFFFFFFF 07 03 XX SUM, XX= 00success 01error 02wait 03unsuccessreg     [103:0]   cmd_make1    ={8'hEF,8'h01,8'hFF,8'hFF,8'hFF,8'hFF,8'h01,8'h00,8'h04,8'h02,8'h01,8'h00,8'h08};reg     [103:0]   cmd_make2    ={8'hEF,8'h01,8'hFF,8'hFF,8'hFF,8'hFF,8'h01,8'h00,8'h04,8'h02,8'h02,8'h00,8'h09};reg     [95:0]    cmd_compare  ={8'hEF,8'h01,8'hFF,8'hFF,8'hFF,8'hFF,8'h01,8'h00,8'h03,8'h03,8'h00,8'h07};reg     [95:0]    cmd_save     ={8'hEF,8'h01,8'hFF,8'hFF,8'hFF,8'hFF,8'h01,8'h00,8'h03,8'h05,8'h00,8'h09};reg     [119:0]   cmd_send     ={8'hEF,8'h01,8'hFF,8'hFF,8'hFF,8'hFF,8'h01,8'h00,8'h06,8'h06,8'h02,8'h00,8'h01,8'h00,8'h10};reg     [135:0]   cmd_find     ={8'hEF,8'h01,8'hFF,8'hFF,8'hFF,8'hFF,8'h01,8'h00,8'h08,8'h1B,8'h01,8'h00,8'h00,8'h00,8'h63,8'h00,8'h88};//应答格式 EF01 FFFFFFFF 07 07 XX ID MATH SUM, XX= 00success 01error 02wait 03unsuccess 16btyereg [3:0] blink_counter; // 用于计数闪烁次数reg [15:0] blink_timer;  // 用于生成 1 秒钟的闪烁周期reg [15:0] error_timer;  // 用于生成 1 秒钟的闪烁周期reg              hand_flag;reg              hand_flag_r;reg              uart_tx_vaild;reg              uart_tx_en_temp;reg     [7:0]    state;reg     [5:0]    tx_count;reg     [5:0]    rx_count;reg              return_flag;reg     [1:0]    tx_en_count;reg     [7:0]    return_data;reg              find_flag;always @(posedge clk or negedge rst_n) beginif(!rst_n)beginhand_flag_r1<=1'b0;hand_flag_r<=1'b0;end else beginhand_flag_r1<=hand_flag;hand_flag_r<=hand_flag_r1;endend//各个状态return_dataalways @(posedge clk or negedge rst_n) beginif(!rst_n) beginuart_tx_data <= 8'd0;endelse if((state==GET_HAND1 || state==GET_HAND2) && tx_count<6'd12 ) beginuart_tx_data <= cmd_state[95 - tx_count *8 -:8];endelse if((state==FIND_HAND) && tx_count<6'd17 ) beginuart_tx_data <= cmd_find[135 - tx_count *8 -:8];endelse if((state==COMPARE_FEATURE) && tx_count<6'd12 ) beginuart_tx_data <= cmd_compare[95 - tx_count *8 -:8];endelse if((state==SAVE_FEATURE) && tx_count<6'd12 ) beginuart_tx_data <= cmd_save[95 - tx_count *8 -:8];endelse if((state==SEND_FEATURE) && tx_count<6'd15 ) beginuart_tx_data <= cmd_send[119 - tx_count *8 -:8];endelse if((state==MAKE_FEATURE1) && tx_count<6'd13 ) beginuart_tx_data <= cmd_make1[103 - tx_count *8 -:8];endelse if((state==MAKE_FEATURE2) && tx_count<6'd13 ) beginuart_tx_data <= cmd_make2[103 - tx_count *8 -:8];endelse beginuart_tx_data <= uart_tx_data;end
end//各个状态return_flagalways @(posedge clk or negedge rst_n) beginif(!rst_n) beginfind_flag <= 1'b0;endelse if(key2==1'b1)beginfind_flag <= ~find_flag;endelse beginfind_flag <= find_flag;endend//各个状态return_flagalways @(posedge clk or negedge rst_n) beginif(!rst_n) beginreturn_flag <= 1'b0;endelse if((state==WAK_HAND1 ||state==WAK_HAND2) && return_data==8'h00&& rx_count==11 && uart_rx_done==1'b1)  beginreturn_flag <= 1'b1;endelse if((state==WAK_FEATURE1 ||state==WAK_FEATURE2 || state== WAK_COMPARE || state==WAK_SAVE || state==WAK_SEND ) && return_data==8'h00 && rx_count==11 && uart_rx_done==1'b1)  beginreturn_flag <= 1'b1;endelse if((state==WAK_FIND) && return_data==8'h00 && rx_count==15 && uart_rx_done==1'b1)  beginreturn_flag <= 1'b1;endelse beginreturn_flag <= 1'b0;end
end//各个状态return_dataalways @(posedge clk or negedge rst_n) beginif(!rst_n) beginreturn_data <= 8'b0;endelse if((state==WAK_HAND1 ||state==WAK_HAND2) && rx_count==10 ) beginreturn_data <= uart_rx_data;endelse if((state==WAK_FEATURE1 ||state==WAK_FEATURE2 || state== WAK_COMPARE || state==WAK_SAVE || state==WAK_FIND) && rx_count==10 ) beginreturn_data <= uart_rx_data;endelse beginreturn_data <= return_data;end
end//各个状态data_tx_enalways @(posedge clk or negedge rst_n) beginif(!rst_n) beginuart_tx_en_temp <= 1'b0;uart_tx_en <= uart_tx_en_temp;endelse if((state==GET_HAND1 || state==GET_HAND2 || state==COMPARE_FEATURE || state==SAVE_FEATURE) && tx_en_count==1) beginuart_tx_en_temp <= 1'b1;uart_tx_en <= uart_tx_en_temp;endelse if((state==MAKE_FEATURE1 || state==MAKE_FEATURE2 || state==SEND_FEATURE || state==FIND_HAND ) && tx_en_count==1) beginuart_tx_en_temp <= 1'b1;uart_tx_en <= uart_tx_en_temp;endelse if((state==GET_HAND1 || state==GET_HAND2 || state==COMPARE_FEATURE || state==SAVE_FEATURE) && tx_count<6'd11 && uart_tx_done==1)beginuart_tx_en_temp <= 1'b1;uart_tx_en <= uart_tx_en_temp;endelse if((state==MAKE_FEATURE1 || state==MAKE_FEATURE2) && tx_count<6'd12 && uart_tx_done==1)beginuart_tx_en_temp <= 1'b1;uart_tx_en <= uart_tx_en_temp;endelse if((state==SEND_FEATURE) && tx_count<6'd14 && uart_tx_done==1)beginuart_tx_en_temp <= 1'b1;uart_tx_en <= uart_tx_en_temp;endelse if((state==FIND_HAND) && tx_count<6'd16 && uart_tx_done==1)beginuart_tx_en_temp <= 1'b1;uart_tx_en <= uart_tx_en_temp;endelse beginuart_tx_en_temp <= 1'b0;uart_tx_en <= uart_tx_en_temp;end
end//各个状态rx_countalways @(posedge clk or negedge rst_n) beginif(!rst_n) beginrx_count <= 6'd0;endelse if((state==WAK_HAND1 ||state==WAK_HAND2 || state==WAK_FEATURE1 ||state==WAK_FEATURE2 || state== WAK_COMPARE || state==WAK_SAVE || state==WAK_SEND) ) beginif(uart_rx_done==1'd1)rx_count <= rx_count+1'b1;else if(rx_count==6'd12) beginrx_count <= 6'b0;endelse beginrx_count <= rx_count;endendelse if((state==WAK_FIND) ) beginif(uart_rx_done==1'd1)rx_count <= rx_count+1'b1;else if(rx_count==6'd16) beginrx_count <= 6'b0;endelse beginrx_count <= rx_count;endend
end//各个状态tx_countalways @(posedge clk or negedge rst_n) beginif(!rst_n) begintx_count <= 6'd0;endelse if((state==GET_HAND1 || state==GET_HAND2 || state==COMPARE_FEATURE || state==SAVE_FEATURE) ) beginif(uart_tx_done==1'd1)tx_count <= tx_count+1'b1;else if(tx_count==6'd12) begintx_count <= 6'b0;endelse begintx_count <= tx_count;endendelse if((state==MAKE_FEATURE1 || state==MAKE_FEATURE2) ) beginif(uart_tx_done==1'd1)tx_count <= tx_count+1'b1;else if(tx_count==6'd13) begintx_count <= 6'b0;endelse begintx_count <= tx_count;endendelse if((state==SEND_FEATURE) ) beginif(uart_tx_done==1'd1)tx_count <= tx_count+1'b1;else if(tx_count==6'd15) begintx_count <= 6'b0;endelse begintx_count <= tx_count;endendelse if((state==FIND_HAND) ) beginif(uart_tx_done==1'd1)tx_count <= tx_count+1'b1;else if(tx_count==6'd17) begintx_count <= 6'b0;endelse begintx_count <= tx_count;endend
end//tx_en timealways @(posedge clk or negedge rst_n) beginif(!rst_n) begintx_en_count <= 2'b0;endelse if((state==GET_HAND1 || state==GET_HAND2 || state==MAKE_FEATURE1 || state==MAKE_FEATURE2 || state==COMPARE_FEATURE || state==SAVE_FEATURE|| state==SEND_FEATURE || state==FIND_HAND) && tx_en_count<2'd1 && tx_count==6'd0) begintx_en_count <=tx_en_count+ 2'd1;endelse if((state==GET_HAND1 || state==GET_HAND2 || state==MAKE_FEATURE1 || state==MAKE_FEATURE2 || state==COMPARE_FEATURE || state==SAVE_FEATURE|| state==SEND_FEATURE || state==FIND_HAND) && tx_en_count==2'd1 && tx_count==6'd0) begintx_en_count <= 2'd3;endelse if((state==WAK_HAND1 ||state==WAK_HAND2 || state==WAK_FEATURE1 ||state==WAK_FEATURE2 || state==WAK_COMPARE || state==WAK_SAVE || state==WAK_SEND || state==WAK_FIND))begintx_en_count <= 2'd0;endelse begintx_en_count <= tx_en_count;end
end//state go always @(posedge clk or negedge rst_n) beginif(!rst_n) beginstate <= IDLE;hand_flag<=1'b0;led_hand1<=1'b0;led_hand2<=1'b0;led_hand3<=1'b0;check_hand_flag<=1'b0;blink_counter <= 0;endelse begincase(state)IDLE:beginblink_counter <= 0;hand_flag<=1'b0;check_hand_flag<=1'b0;if(key1==1'b1 && WAK==1'b1)beginstate <= GET_HAND1;endelse beginstate <= IDLE;endendGET_HAND1:beginif(tx_count==6'd12)beginstate <= WAK_HAND1;endelse beginstate <= GET_HAND1;endendWAK_HAND1:beginif(rx_count==6'd12 && return_flag==1'b1)beginstate <= MAKE_FEATURE1;endelse if(rx_count==6'd12 && return_flag==1'b0)beginstate <= IDLE;endelse beginstate <= WAK_HAND1;endendHAND1_LED: beginif (blink_counter < 2) beginif (blink_timer == 16'd0) beginled_hand1 = ~led_hand1; // 每秒反转一次 ledblink_counter = blink_counter + 1;endend else beginstate = MAKE_FEATURE1; // 完成 10 次闪烁后返回 IDLE 状态endendMAKE_FEATURE1:beginif(tx_count==6'd13)beginstate <= WAK_FEATURE1;endelse beginstate <= MAKE_FEATURE1;endendWAK_FEATURE1:beginif(find_flag==1'b0) beginif(rx_count==6'd12 && return_flag==1'b1)beginstate <= GET_HAND2;endelse if(rx_count==6'd12 && return_flag==1'b0)beginstate <= IDLE;endelse beginstate <= WAK_FEATURE1;endendelse beginif(rx_count==6'd12 && return_flag==1'b1)beginstate <= FIND_HAND;endelse if(rx_count==6'd12 && return_flag==1'b0)beginstate <= IDLE;endelse beginstate <= WAK_FEATURE1;endendendGET_HAND2:beginblink_counter <= 0;if(tx_count==6'd12)beginstate <= WAK_HAND2;endelse beginstate <= GET_HAND2;endendWAK_HAND2:beginif(rx_count==6'd12 && return_flag==1'b1)beginstate <= MAKE_FEATURE2;endelse if(rx_count==6'd12 && return_flag==1'b0)beginstate <= GET_HAND2;endelse beginstate <= WAK_HAND2;endendHAND2_LED: beginif (blink_counter < 2) beginif (blink_timer == 16'd0) beginled_hand2 = ~led_hand2; // 每秒反转一次 ledblink_counter = blink_counter + 1;endend else beginstate = MAKE_FEATURE2; // 完成 10 次闪烁后返回 IDLE 状态endendMAKE_FEATURE2:beginif(tx_count==6'd13)beginstate <= WAK_FEATURE2;endelse beginstate <= MAKE_FEATURE2;endendWAK_FEATURE2:beginif(rx_count==6'd12 && return_flag==1'b1)beginstate <= COMPARE_FEATURE;endelse if(rx_count==6'd12 && return_flag==1'b0)beginstate <= IDLE;endelse beginstate <= WAK_FEATURE2;endendCOMPARE_FEATURE:beginif(tx_count==6'd12)beginstate <= WAK_COMPARE;endelse beginstate <= COMPARE_FEATURE;endendWAK_COMPARE:beginif(rx_count==6'd12 && return_flag==1'b1)beginstate <= SAVE_FEATURE;endelse if(rx_count==6'd12 && return_flag==1'b0)beginstate <= IDLE;endelse beginstate <= WAK_COMPARE;endendSAVE_FEATURE:beginif(tx_count==6'd12)beginstate <= WAK_SAVE;endelse beginstate <= SAVE_FEATURE;endendWAK_SAVE:beginif(rx_count==6'd12 && return_flag==1'b1)beginstate <= SEND_FEATURE;endelse if(rx_count==6'd12 && return_flag==1'b0)beginstate <= IDLE;endelse beginstate <= WAK_SAVE;endendSEND_FEATURE:beginif(tx_count==6'd15)beginstate <= WAK_SEND;endelse beginstate <= SEND_FEATURE;endendWAK_SEND:beginif(rx_count==6'd12 && return_flag==1'b1)beginstate <= IDLE;endelse if(rx_count==6'd12 && return_flag==1'b0)beginstate <= IDLE;endelse beginstate <= WAK_SEND;endendSAVE_LED: beginif (blink_counter < 2) beginif (blink_timer == 16'd0) beginled_hand3 = ~led_hand3; // 每秒反转一次 ledblink_counter = blink_counter + 1;endend else beginstate = IDLE; // 完成 10 次闪烁后返回 IDLE 状态endendFIND_HAND:beginif(tx_count==6'd17)beginstate <= WAK_FIND;endelse beginstate <= FIND_HAND;endendWAK_FIND:beginif(rx_count==6'd16 && return_flag==1'b1)beginstate <= IDLE;check_hand_flag<=1'b1;hand_flag<=1'b1;endelse if(rx_count==6'd16 && return_flag==1'b0)beginstate <= IDLE;check_hand_flag<=1'b1;hand_flag<=1'b0;endelse beginstate <= WAK_FIND;endenddefault:state <= IDLE;endcaseend
end
// 计时器,用于实现 1 秒钟的闪烁周期
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginblink_timer <= 0;end else beginif (state == HAND2_LED ||state == HAND1_LED ||state == SAVE_LED) beginif (blink_timer == 16'd49999) // 假设时钟频率是 50MHz,每 1 秒blink_timer <= 0;elseblink_timer <= blink_timer + 1;end else beginblink_timer <= 0;endend
endendmodule

2.check_hand模块

在这里插入图片描述

通过check_hand_flag控制进入检验CHECK状态,通过hand_flag确定指纹验证是否正确。正确就led_hand_right闪,错误就led_hand_error。这两个标志是通过AS608模块传出来的。

代码如下(示例):

module check_hand(input           clk,input           rst_n,input           hand_flag,input           check_hand_flag,output  reg     led_hand_right,output  reg     led_hand_error
);// 状态定义parameter  IDLE   = 2'b00; // 等待状态parameter CHECK  = 2'b01; // 检测状态parameter BLINK  = 2'b10; // 闪烁状态parameter ERROR  = 2'b11; // 错误状态// 状态寄存器
reg [1:0] state;
reg [3:0] blink_counter; // 用于计数闪烁次数
reg [15:0] blink_timer;  // 用于生成 1 秒钟的闪烁周期
reg [15:0] error_timer;  // 用于生成 1 秒钟的闪烁周期// 计时器,用于实现 1 秒钟的闪烁周期
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginblink_timer <= 0;end else beginif (state == BLINK) beginif (blink_timer == 16'd49999) // 假设时钟频率是 50MHz,每 1 秒blink_timer <= 0;elseblink_timer <= blink_timer + 1;end else beginblink_timer <= 0;endend
end// 错误状态计时器(10秒)
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginerror_timer <= 0;end else if (state == ERROR) beginif (error_timer == 16'd49999) // 假设时钟频率是 50MHz,10秒error_timer <= 0; // 超过 10 秒后,计时器重置elseerror_timer <= error_timer + 1;end else beginerror_timer <= 0; // 不是错误状态时,计时器清零end
end// 状态转移与输出逻辑
always @(posedge clk or negedge rst_n) beginif(!rst_n)beginstate <=IDLE;led_hand_right <= 0;led_hand_error <=0;endelse begincase(state)IDLE: beginif (check_hand_flag) beginstate <=CHECK; // 如果检测标志位为1,进入检测状态endelse beginstate <=IDLE;endendCHECK: beginif (hand_flag) beginstate <= BLINK; // 如果手势正确,进入闪烁状态end else beginstate <= ERROR; // 如果手势错误,进入错误状态endendBLINK: beginif (blink_counter < 10) beginif (blink_timer == 16'd0) beginled_hand_right = ~led_hand_right; // 每秒反转一次 ledblink_counter = blink_counter + 1;endend else beginstate = IDLE; // 完成 10 次闪烁后返回 IDLE 状态endendERROR: beginif (blink_counter < 10) beginif (error_timer == 16'd0) beginled_hand_error <= ~led_hand_error; // 错误时,led_hand_error 10次blink_counter <= blink_counter + 1;endend else beginstate <= IDLE; // 完成 10 次闪烁后返回 IDLE 状态endendendcaseend
end// 控制闪烁次数
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginblink_counter <= 0;end else if (state == IDLE) beginblink_counter <= 0; // 重置闪烁计数器end
endendmodule

3.four_four_key模块

矩阵按键模块,通过给予不同行高电平,然后检测列状态,得出按键的状态。

`timescale 1ns / 1ps
//
// Company: NanJing University of Information Science & Technology
// Engineer: Yang Cheng Yu
// 
// Create Date: 2020/01/13 20:01:50
// Design Name: keyboard_4_4
// Module Name: keyboard_4_4
// Project Name: Clock
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
module four_four_key(input 					clk,//时钟input 					rst,//复位output reg[3:0] 		c_pin,//行引脚input[3:0] 				r_pin,//列引脚output reg[3:0]			key_out,//按键编号输出output wire[3:0]		key_pulse//按键编号输出
);reg[3:0]			    key_out_r;reg[15:0] 				div_cnt;//分频计数器reg[2:0]				state;reg[2:0]				state_r;reg						cnt_full;//分频计数器计满逻辑wire                    clear_flag;localparam				CHECK_R1=3'b000;//检测R1localparam				CHECK_R2=3'b001;//检测R2localparam				CHECK_R3=3'b011;//检测R3localparam				CHECK_R4=3'b010;//检测R4always @(posedge clk or negedge rst)beginif(!rst) beginstate_r <= 3'b0;endelse beginstate_r <= state;endendassign clear_flag= (state_r==state)?1:0;always @(posedge clk or negedge rst)beginif(!rst) beginkey_out_r <= 4'b0;endelse beginkey_out_r <= key_out;endend//Detect the negedge of low_sw, generate pulse
//  assign key_pulse= key_out_r & ( ~key_out);assign key_pulse= (key_out_r==key_out)?1:0;//分频计数器逻辑always@(posedge clk or negedge rst)begin//此处设计每次拉高一行时间为1msif(!rst)begindiv_cnt <= 16'd0;cnt_full <= 1'b0;endelseif(div_cnt==16'd49999)begindiv_cnt <= 16'd0;cnt_full <= 1'b1;endelse begindiv_cnt <= div_cnt + 1'b1;cnt_full <= 1'b0;endend//状态组合判断always@(posedge cnt_full or negedge rst)beginif(!rst)beginstate <= CHECK_R1;endelse begincase(state)CHECK_R1:if(cnt_full)beginstate <= CHECK_R2;endelse beginstate <= CHECK_R1;endCHECK_R2:if(cnt_full)beginstate <= CHECK_R3;endelse beginstate <= CHECK_R2;endCHECK_R3:if(cnt_full)beginstate <= CHECK_R4;endelse beginstate <= CHECK_R3;endCHECK_R4:if(cnt_full)beginstate <= CHECK_R1;endelse beginstate <= CHECK_R4;enddefault: beginstate <= state;endendcaseendend//状态机输出逻辑always@(posedge clk or negedge rst)beginif(!rst)beginc_pin <= 4'b0000;key_out <= 4'd0;endelse begincase(state)CHECK_R1:beginc_pin <= 4'b1000;case(r_pin)4'b1000:key_out <= 4'd0;4'b0100:key_out <= 4'd1;4'b0010:key_out <= 4'd2;4'b0001:key_out <= 4'd3;default:key_out <= key_out;endcaseendCHECK_R2:beginc_pin <= 4'b0100;case(r_pin)4'b1000:key_out <= 4'd4;4'b0100:key_out <= 4'd5;4'b0010:key_out <= 4'd6;4'b0001:key_out <= 4'd7;default:key_out <= key_out;endcaseendCHECK_R3:beginc_pin <= 4'b0010;case(r_pin)4'b1000:key_out <= 4'd8;4'b0100:key_out <= 4'd9;4'b0010:key_out <= 4'd10;4'b0001:key_out <= 4'd11;default:key_out <= key_out;endcaseendCHECK_R4:beginc_pin <= 4'b0001;case(r_pin)4'b1000:key_out <= 4'd12;4'b0100:key_out <= 4'd13;4'b0010:key_out <= 4'd14;4'b0001:key_out <= 4'd15;default:key_out <= key_out;endcaseend	default:beginc_pin <= 4'b0000;key_out <= 4'd0;endendcaseendend
endmodule

4.check_mima模块

key3控制进入输入密码状态,检测到6次按下后自动检测密码是否正确。正确就回到IDLE,并输出一个mima_flag 一个clk的高电平。可以根据这个标志进行操作。错误就累加,累加到一定次进入WARNING,报警状态。
在这里插入图片描述

module check_mima(input clk,           // 时钟信号input rst_n,         // 异步复位信号,低有效input key3,          // 启动密码输入的按键input [3:0] r_pin,   // 键盘输入(数字键的按下信号)input [3:0] key_out, // 键盘输出的具体数字input [23:0] correct_password,output wire [23:0] mima,    // 24位密码存储寄存器output reg mima_flag       // 密码验证标志
);// 定义状态机状态parameter    IDLE = 2'b00;     // 初始状态,等待key3按下parameter    STORE = 2'b01;   // 密码输入存储状态parameter    CHECK = 2'b10;     // 密码校验状态parameter    WARNING = 2'b11;     // 密码校验状态reg [1:0] state;reg [1:0] next_state;reg [3:0] digit_count;      // 用于记录输入密码的数字数量reg [3:0] mima_1;      reg [3:0] mima_2;  reg [3:0] mima_3;  reg [3:0] mima_4;  reg [3:0] mima_5;  reg [3:0] mima_6;  reg [2:0] mima_error_count;reg [3:0] blink_counter; // 用于计数闪烁次数reg [15:0] blink_timer;  // 用于生成 1 秒钟的闪烁周期reg [15:0] error_timer;  // 用于生成 1 秒钟的闪烁周期reg       led_warning;// 初始密码,预设为 "123456"(24位)
//    reg [23:0] correct_password = 24'h123456;// 计时器,用于实现 1 秒钟的闪烁周期always @(posedge clk or negedge rst_n) beginif (!rst_n) beginblink_timer <= 0;end else beginif (state == WARNING) beginif (blink_timer == 16'd20) // 假设时钟频率是 50MHz,每 1 秒blink_timer <= 0;elseblink_timer <= blink_timer + 1;end else beginblink_timer <= 0;endendend// 状态机逻辑always @(posedge clk or negedge rst_n) beginif (~rst_n)state <= IDLE;  // 异步复位时,状态机回到IDLE状态elsestate <= next_state;  // 按时钟更新状态end// 下一个状态的逻辑always @(posedge clk) begincase(state)IDLE: beginif (key3)           // 按下key3启动密码输入next_state <=  STORE;elsenext_state <= IDLE;endSTORE: beginif (digit_count == 6)  // 密码输入6位后,进入校验状态next_state <=  CHECK;elsenext_state <=  STORE;endCHECK: beginif((mima_error_count==2) && (mima != correct_password))beginnext_state <= WARNING;  // 校验完成后回到IDLE状态end else beginnext_state <=  IDLE;endendWARNING: beginif (blink_counter == 10) beginnext_state <=  IDLE;endelse beginnext_state <=  WARNING;endenddefault: next_state <= IDLE;endcaseend// 密码输入存储逻辑always @(posedge clk or negedge rst_n) beginif (~rst_n) beginmima_1<=4'd0;mima_2<=4'd0;mima_3<=4'd0;mima_4<=4'd0;mima_5<=4'd0;mima_6<=4'd0;digit_count <= 0;     // 清空输入的位数mima_flag <= 0;       // 初始时密码校验标志为低led_warning<=1'b0;blink_counter<=0;mima_error_count<=0;end else begincase(state)IDLE: beginmima_flag <= 0;digit_count <= 0;     // 清空输入的位数led_warning<=1'b0;blink_counter<=0;mima_1<=4'd0;mima_2<=4'd0;mima_3<=4'd0;mima_4<=4'd0;mima_5<=4'd0;mima_6<=4'd0;endSTORE: beginif (r_pin != 4'b0000 && digit_count < 6) begindigit_count <= digit_count + 1;endcase(digit_count)6:beginmima_6<=key_out;end1:beginmima_1<=key_out;end2:beginmima_2<=key_out;end3:beginmima_3<=key_out;end4:beginmima_4<=key_out;end5:beginmima_5<=key_out;enddefault:beginmima_1<=4'd0;mima_2<=4'd0;mima_3<=4'd0;mima_4<=4'd0;mima_5<=4'd0;mima_6<=4'd0;endendcaseendCHECK: beginmima_1<=4'd0;mima_2<=4'd0;mima_3<=4'd0;mima_4<=4'd0;mima_5<=4'd0;mima_6<=4'd0;if (mima == correct_password)  // 密码正确mima_flag <= 1;   // 密码验证通过,设置mima_flag为高else if(mima_error_count<3)beginmima_error_count<=mima_error_count+1;mima_flag <= 0;   // 密码验证失败,保持mima_flag为低endendWARNING: beginmima_error_count<=0;if (blink_counter < 10) beginif (blink_timer == 16'd0) beginled_warning = ~led_warning; // 每秒反转一次 ledblink_counter = blink_counter + 1;endend enddefault: beginmima_flag <= 0;       // 在其他状态下,密码标志保持低endendcaseendendassign mima={mima_1,mima_2,mima_3,mima_4,mima_5,mima_6};endmodule

5.change_mima模块

类似check_mima模块

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/12/07 15:23:36
// Design Name: 
// Module Name: change_mima
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module change_mima(input       clk,input       rst_n,input       key4, input [3:0] r_pin,   // 键盘输入(数字键的按下信号)input [3:0] key_out, // 键盘输出的具体数字output reg        led_change,output wire [23:0] correct_password);parameter    IDLE = 2'b00;     // 初始状态,等待key3按下parameter    STORE = 2'b01;   // 新密码存储状态parameter    CHANGE_OK = 2'b10;     // 密码修改完毕状态reg [3:0] blink_counter; // 用于计数闪烁次数reg [15:0] blink_timer;  // 用于生成 1 秒钟的闪烁周期reg [1:0] state;reg [1:0] next_state;reg [3:0] digit_count;      // 用于记录输入密码的数字数量reg [3:0] mima_1;      reg [3:0] mima_2;  reg [3:0] mima_3;  reg [3:0] mima_4;  reg [3:0] mima_5;  reg [3:0] mima_6;  assign correct_password={mima_1,mima_2,mima_3,mima_4,mima_5,mima_6};// 计时器,用于实现 1 秒钟的闪烁周期
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginblink_timer <= 0;end else beginif (state == CHANGE_OK) beginif (blink_timer == 16'd100) // 假设时钟频率是 50MHz,每 1 秒blink_timer <= 0;elseblink_timer <= blink_timer + 1;end else beginblink_timer <= 0;endend
end// 状态机逻辑always @(posedge clk or negedge rst_n) beginif (~rst_n)state <= IDLE;  // 异步复位时,状态机回到IDLE状态elsestate <= next_state;  // 按时钟更新状态end// 下一个状态的逻辑always @(posedge clk) begincase(state)IDLE: beginif (key4)           // 按下key3启动密码输入next_state = STORE;elsenext_state = IDLE;endSTORE: beginif (digit_count == 6)  // 密码输入6位后,进入校验状态next_state <= CHANGE_OK;elsenext_state <= STORE;endCHANGE_OK: beginif(blink_counter == 10)next_state <=  IDLE;  // 校验完成后回到IDLE状态else beginnext_state <=  CHANGE_OK; endenddefault: next_state <=  IDLE;endcaseend// 密码输入存储逻辑always @(posedge clk or negedge rst_n) beginif (~rst_n) beginmima_1<=4'd1;mima_2<=4'd2;mima_3<=4'd3;mima_4<=4'd4;mima_5<=4'd5;mima_6<=4'd6;led_change<=1'b0;blink_counter<=0;digit_count <= 0;     // 清空输入的位数end else begincase(state)IDLE: beginmima_1<=mima_1;mima_2<=mima_2;mima_3<=mima_3;mima_4<=mima_4;mima_5<=mima_5;mima_6<=mima_6;led_change<=1'b0;digit_count <= 0;     // 清空输入的位数endSTORE: beginif (r_pin != 4'b0000 && digit_count < 6) begindigit_count <= digit_count + 1;endcase(digit_count)6:beginmima_6<=key_out;end1:beginmima_1<=key_out;end2:beginmima_2<=key_out;end3:beginmima_3<=key_out;end4:beginmima_4<=key_out;end5:beginmima_5<=key_out;enddefault:beginmima_1<=mima_1;mima_2<=mima_2;mima_3<=mima_3;mima_4<=mima_4;mima_5<=mima_5;mima_6<=mima_6;endendcaseendCHANGE_OK: beginif (blink_counter < 10) beginif (blink_timer == 16'd0) beginled_change<= ~led_change; // 每秒反转一次 ledblink_counter <= blink_counter + 1;endend else beginblink_counter <= blink_counter;endenddefault: beginstate<=IDLE;endendcaseendendendmodule

6.seg_ctrl模块

数码管显示模块

/**************************************功能介绍***********************************
Date	: 2023年10月1日 11:54:18
Author	: Yang.
Project : 密码锁
Require : 用verliog实现密码锁,且具有以下功能:1、六位密码,且用数码管显示。2、用按键键入每一位密码,可以加减。3、密码正确时,led灯以300ms频率闪烁10s,且蜂鸣器播放音乐。4、密码错误时,led灯以100ms频率闪烁10s,且蜂鸣器报警。
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module seg_ctrl( input				clk		,input				rst_n	,input		[23:0]	din		,//输入6位数码管显示数据,每位数码管占4位input       [5:0]   point_n ,//输入小数点控制位output	reg	[5:0]	sel	,//输出位选output	reg	[7:0]	dig  //输出段选
);								 
//---------<参数定义>--------------------------------------------------------- parameter TIME_1MS = 50_000;//1ms//数码管显示字符编码localparam NUM_0 = 7'b100_0000,//0NUM_1 = 7'b111_1001,//1NUM_2 = 7'b010_0100,//NUM_3 = 7'b011_0000,//NUM_4 = 7'b001_1001,//NUM_5 = 7'b001_0010,//NUM_6 = 7'b000_0010,//NUM_7 = 7'b111_1000,//NUM_8 = 7'b000_0000,//NUM_9 = 7'b001_0000,//A     = 7'b000_1000,//B     = 7'b000_0011,//bC     = 7'b100_0110,//OFF   = 7'b111_1111,//全灭CROSS = 7'b011_1111,//横杠//D     = 7'b010_0001,//d//E     = 7'b000_0110,//F     = 7'b000_1110;////---------<内部信号定义>-----------------------------------------------------reg			[15:0]	cnt_1ms	   	;//1ms计数器(扫描间隔计数器)wire				add_cnt_1ms	;wire				end_cnt_1ms	;reg         [3:0]   disp_data   ;//每一位数码管显示的数值reg                 point_n_r   ;//每一位数码管显示的小数点//****************************************************************
//--cnt_1ms
//****************************************************************always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_1ms <= 'd0;end else if(add_cnt_1ms)begin if(end_cnt_1ms)begin cnt_1ms <= 'd0;endelse begin cnt_1ms <= cnt_1ms + 1'b1;end endend assign add_cnt_1ms = 1'b1;//数码管一直亮assign end_cnt_1ms = add_cnt_1ms && cnt_1ms == TIME_1MS - 1;//****************************************************************
//--seg_sel
//****************************************************************always @(posedge clk or negedge rst_n)begin if(!rst_n)beginsel <= 6'b111_110;//循环移位实现时,需要给位选赋初值end else if(end_cnt_1ms)begin sel <= {sel[4:0],sel[5]};//循环左移end end//****************************************************************
//--disp_data
//****************************************************************always @(posedge clk or negedge rst_n)begin if(!rst_n)begindisp_data <= 'd0;point_n_r <= 1'b1;end else begin case (sel)6'b111_110 : begin disp_data <= din[3:0]  ; point_n_r <= point_n[0]; end//第一位数码管显示的数值6'b111_101 : begin disp_data <= din[7:4]  ; point_n_r <= point_n[1]; end6'b111_011 : begin disp_data <= din[11:8] ; point_n_r <= point_n[2]; end6'b110_111 : begin disp_data <= din[15:12]; point_n_r <= point_n[3]; end6'b101_111 : begin disp_data <= din[19:16]; point_n_r <= point_n[4]; end6'b011_111 : begin disp_data <= din[23:20]; point_n_r <= point_n[5]; enddefault: disp_data <= 'd0;endcaseend end//****************************************************************
//--seg_dig
//****************************************************************always @(*)begin case (disp_data)0 :  dig = {point_n_r,NUM_0};1 :  dig = {point_n_r,NUM_1};2 :  dig = {point_n_r,NUM_2};3 :  dig = {point_n_r,NUM_3};4 :  dig = {point_n_r,NUM_4};5 :  dig = {point_n_r,NUM_5};6 :  dig = {point_n_r,NUM_6};7 :  dig = {point_n_r,NUM_7};8 :  dig = {point_n_r,NUM_8};9 :  dig = {point_n_r,NUM_9};10 : dig = {point_n_r,A    };11 : dig = {point_n_r,B    };12 : dig = {point_n_r,C    };13 : dig = {point_n_r,CROSS};14 : dig = {point_n_r,OFF  };15 : dig = {point_n_r,F    };default: dig = 8'hff;endcaseendendmodule

7.uart_top模块

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:http://www.openedv.com/forum.php
//淘宝店铺:https://zhengdianyuanzi.tmall.com
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2023-2033
//All rights reserved                                  
//----------------------------------------------------------------------------------------
// File name:           uart_loopback
// Created by:          正点原子
// Created date:        2023年2月16日14:20:02
// Version:             V1.0
// Descriptions:        串口回环实验
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//module uart_top(input            sys_clk  ,   //外部50MHz时钟input            sys_rst_n,   //系外部复位信号,低有效//UART端口   input            uart_rxd ,   //UART接收端口output           uart_txd ,    //UART发送端口output wire         uart_tx_en,    //UART接收完成信号output wire         uart_rx_done,    //UART接收完成信号  output wire         uart_tx_done,    //UART接收完成信号  output wire  [7:0]  uart_tx_data,    //UART接收数据     output wire  [7:0]  uart_rx_data    //UART接收数据         );//parameter define
parameter CLK_FREQ = 50000000;    //定义系统时钟频率
parameter UART_BPS = 576000  ;    //定义串口波特率//wire define
//wire         uart_rx_done;    //UART接收完成信号
//wire  [7:0]  uart_rx_data;    //UART接收数据//*****************************************************
//**                    main code
//*****************************************************//串口接收模块
uart_rx #(.CLK_FREQ  (CLK_FREQ),.UART_BPS  (UART_BPS))    u_uart_rx(.clk           (sys_clk     ),.rst_n         (sys_rst_n   ),.uart_rxd      (uart_rxd    ),.uart_rx_done  (uart_rx_done),.uart_rx_data  (uart_rx_data));//串口发送模块
uart_tx #(.CLK_FREQ  (CLK_FREQ),.UART_BPS  (UART_BPS))    u_uart_tx(.clk          (sys_clk     ),.rst_n        (sys_rst_n   ),.uart_tx_en   (uart_tx_en),.uart_tx_data (uart_tx_data),.uart_tx_done (uart_tx_done),.uart_txd     (uart_txd    ),.uart_tx_busy (            ));endmodule

//uart_rx//
//uart_rx//
//uart_rx//

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:http://www.openedv.com/forum.php
//淘宝店铺:https://zhengdianyuanzi.tmall.com
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2023-2033
//All rights reserved                                  
//----------------------------------------------------------------------------------------
// File name:           uart_rx
// Created by:          正点原子
// Created date:        2023年2月16日14:20:02
// Version:             V1.0
// Descriptions:        UART串口接收模块
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//module uart_rx(input               clk         ,  //系统时钟input               rst_n       ,  //系统复位,低有效input               uart_rxd    ,  //UART接收端口output  reg         uart_rx_done,  //UART接收完成信号output  reg  [7:0]  uart_rx_data  //UART接收到的数据);//parameter define
parameter CLK_FREQ = 50000000;               //系统时钟频率
parameter UART_BPS = 576000  ;               //串口波特率
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS; //为得到指定波特率,对系统时钟计数BPS_CNT次//reg define
reg          uart_rxd_d0;
reg          uart_rxd_d1;
reg          uart_rxd_d2;
reg          rx_flag    ;  //接收过程标志信号
reg  [3:0 ]  rx_cnt     ;  //接收数据计数器
reg  [15:0]  baud_cnt   ;  //波特率计数器
reg  [7:0 ]  rx_data_t  ;  //接收数据寄存器//wire define
wire        start_en;//*****************************************************
//**                    main code
//*****************************************************
//捕获接收端口下降沿(起始位),得到一个时钟周期的脉冲信号
assign start_en = uart_rxd_d2 & (~uart_rxd_d1) & (~rx_flag);//针对异步信号的同步处理
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginuart_rxd_d0 <= 1'b0;uart_rxd_d1 <= 1'b0;uart_rxd_d2 <= 1'b0;endelse beginuart_rxd_d0 <= uart_rxd;uart_rxd_d1 <= uart_rxd_d0;uart_rxd_d2 <= uart_rxd_d1;end
end//给接收标志赋值
always @(posedge clk or negedge rst_n) beginif(!rst_n) rx_flag <= 1'b0;else if(start_en)    //检测到起始位rx_flag <= 1'b1; //接收过程中,标志信号rx_flag拉高//在停止位一半的时候,即接收过程结束,标志信号rx_flag拉低else if((rx_cnt == 4'd9) && (baud_cnt == BAUD_CNT_MAX/2 - 1'b1))rx_flag <= 1'b0;elserx_flag <= rx_flag;
end        //波特率的计数器赋值
always @(posedge clk or negedge rst_n) beginif(!rst_n) baud_cnt <= 16'd0;else if(rx_flag) begin     //处于接收过程时,波特率计数器(baud_cnt)进行循环计数if(baud_cnt < BAUD_CNT_MAX - 1'b1)baud_cnt <= baud_cnt + 16'b1;else baud_cnt <= 16'd0; //计数达到一个波特率周期后清零end    elsebaud_cnt <= 16'd0;     //接收过程结束时计数器清零
end//对接收数据计数器(rx_cnt)进行赋值
always @(posedge clk or negedge rst_n) beginif(!rst_n) rx_cnt <= 4'd0;else if(rx_flag) begin                  //处于接收过程时rx_cnt才进行计数if(baud_cnt == BAUD_CNT_MAX - 1'b1) //当波特率计数器计数到一个波特率周期时rx_cnt <= rx_cnt + 1'b1;        //接收数据计数器加1elserx_cnt <= rx_cnt;endelserx_cnt <= 4'd0;                     //接收过程结束时计数器清零
end        //根据rx_cnt来寄存rxd端口的数据
always @(posedge clk or negedge rst_n) beginif(!rst_n) rx_data_t <= 8'b0;else if(rx_flag) begin                           //系统处于接收过程时if(baud_cnt == BAUD_CNT_MAX/2 - 1'b1) begin  //判断baud_cnt是否计数到数据位的中间case(rx_cnt)4'd1 : rx_data_t[0] <= uart_rxd_d2;   //寄存数据的最低位4'd2 : rx_data_t[1] <= uart_rxd_d2;4'd3 : rx_data_t[2] <= uart_rxd_d2;4'd4 : rx_data_t[3] <= uart_rxd_d2;4'd5 : rx_data_t[4] <= uart_rxd_d2;4'd6 : rx_data_t[5] <= uart_rxd_d2;4'd7 : rx_data_t[6] <= uart_rxd_d2;4'd8 : rx_data_t[7] <= uart_rxd_d2;   //寄存数据的高低位default : ;endcase  endelserx_data_t <= rx_data_t;endelserx_data_t <= 8'b0;
end        //给接收完成信号和接收到的数据赋值
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginuart_rx_done <= 1'b0;uart_rx_data <= 8'b0;end//当接收数据计数器计数到停止位,且baud_cnt计数到停止位的中间时else if(rx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX/2 - 1'b1) beginuart_rx_done <= 1'b1     ;  //拉高接收完成信号uart_rx_data <= rx_data_t;  //并对UART接收到的数据进行赋值end    else beginuart_rx_done <= 1'b0;uart_rx_data <= uart_rx_data;end
endendmodule

//uart_tx//
//uart_tx//
//uart_tx//

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:http://www.openedv.com/forum.php
//淘宝店铺:https://zhengdianyuanzi.tmall.com
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2023-2033
//All rights reserved                                  
//----------------------------------------------------------------------------------------
// File name:           uart_tx
// Created by:          正点原子
// Created date:        2023年2月16日14:20:02
// Version:             V1.0
// Descriptions:        UART串口发送模块
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//module uart_tx(input               clk         , //系统时钟input               rst_n       , //系统复位,低有效input               uart_tx_en  , //UART的发送使能input     [7:0]     uart_tx_data, //UART要发送的数据output  reg         uart_txd    , //UART发送端口output  reg  [3:0]  tx_cnt      ,  //发送数据计数器output  reg  [15:0] baud_cnt    ,  //波特率计数器output  reg         uart_tx_done,output  reg         uart_tx_busy  //发送忙状态信号);//parameter define
parameter CLK_FREQ = 50000000;               //系统时钟频率
parameter UART_BPS = 576000  ;               //串口波特率
localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS; //为得到指定波特率,对系统时钟计数BPS_CNT次//reg define
reg  [7:0]  tx_data_t;  //发送数据寄存器
//波特率的计数器赋值
always @(posedge clk or negedge rst_n) beginif(!rst_n) uart_tx_done<=1'b0;else if(tx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX - 1) beginuart_tx_done<=1'b1;end    elseuart_tx_done<=1'b0;     //发送过程结束时计数器清零
end//*****************************************************
//**                    main code
//*****************************************************//当uart_tx_en为高时,寄存输入的并行数据,并拉高BUSY信号
always @(posedge clk or negedge rst_n) beginif(!rst_n) begintx_data_t <= 8'b0;uart_tx_busy <= 1'b0;end//发送使能时,寄存要发送的数据,并拉高BUSY信号else if(uart_tx_en) begintx_data_t <= uart_tx_data;uart_tx_busy <= 1'b1;end//当计数到停止位结束时,停止发送过程else if(tx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX - 1) begintx_data_t <= 8'b0;     //清空发送数据寄存器uart_tx_busy <= 1'b0;  //并拉低BUSY信号endelse begintx_data_t <= tx_data_t;uart_tx_busy <= uart_tx_busy;end
end//波特率的计数器赋值
always @(posedge clk or negedge rst_n) beginif(!rst_n) baud_cnt <= 16'd0;else if(uart_tx_en)  baud_cnt <= 16'd0;      //当处于发送过程时,波特率计数器(baud_cnt)进行循环计数else if(uart_tx_busy) beginif(baud_cnt < BAUD_CNT_MAX - 1'b1)baud_cnt <= baud_cnt + 16'b1;else baud_cnt <= 16'd0; //计数达到一个波特率周期后清零end    elsebaud_cnt <= 16'd0;     //发送过程结束时计数器清零
end//tx_cnt进行赋值
always @(posedge clk or negedge rst_n) beginif(!rst_n) tx_cnt <= 4'd0;else if(uart_tx_en)  tx_cnt <= 16'd0;         else if(uart_tx_busy) begin             //处于发送过程时tx_cnt才进行计数if(baud_cnt == BAUD_CNT_MAX - 1'b1) //当波特率计数器计数到一个波特率周期时tx_cnt <= tx_cnt + 1'b1;        //发送数据计数器加1elsetx_cnt <= tx_cnt;endelsetx_cnt <= 4'd0;                     //发送过程结束时计数器清零
end//根据tx_cnt来给uart发送端口赋值
always @(posedge clk or negedge rst_n) beginif(!rst_n) uart_txd <= 1'b1;else if(uart_tx_busy) begincase(tx_cnt) 4'd0 : uart_txd <= 1'b0        ; //起始位4'd1 : uart_txd <= tx_data_t[0]; //数据位最低位4'd2 : uart_txd <= tx_data_t[1];4'd3 : uart_txd <= tx_data_t[2];4'd4 : uart_txd <= tx_data_t[3];4'd5 : uart_txd <= tx_data_t[4];4'd6 : uart_txd <= tx_data_t[5];4'd7 : uart_txd <= tx_data_t[6];4'd8 : uart_txd <= tx_data_t[7]; //数据位最高位4'd9 : uart_txd <= 1'b1        ; //停止位default : uart_txd <= 1'b1;endcaseendelseuart_txd <= 1'b1;                    //空闲时发送端口为高电平
endendmodule

8.key_debounce模块

仿真用不到,按键消抖模块

//
//                                                                              //
//                                                                              //
//  Author: lhj                                                                 ////                                                                             //
//          ALINX(shanghai) Technology Co.,Ltd                                  //
//          heijin                                                              //
//     WEB: http://www.alinx.cn/                                                //
//     BBS: http://www.heijin.org/                                              //
//                                                                              //
//
//                                                                              //
// Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd                        //
//                    All rights reserved                                       //
//                                                                              //
// This source file may be used and distributed without restriction provided    //
// that this copyright statement is not removed from the file and that any      //
// derivative work contains the original copyright notice and the associated    //
// disclaimer.                                                                  //
//                                                                              //
////===============================================================================
//  Revision History:
//  Date          By            Revision    Change Description
//-------------------------------------------------------------------------------
//  2018/01/03    lhj        1.0         Original
//*******************************************************************************/
module key_debounce
(
input        sys_clk,
input        rst_n,
input        key,
output wire        button_negedge //Key falling edge);
wire [3:0] led;ax_debounce ax_debounce_m0
(.clk             (sys_clk       ),.rst             (~rst_n        ),.button_in       (key           ),.button_posedge  (              ),.button_negedge  (button_negedge),.button_out      (              )
);wire[3:0]   count;counter count_m0
(.clk             (sys_clk       ),.rst_n           (rst_n         ),.en              (button_negedge),.clr             (1'b0          ),.data            (count         )
);
assign led = ~count;
endmodule 

9.TOP模块

//****************************************Copyright (c)***********************************//
//原子哥在线教学平台:www.yuanzige.com
//技术支持:http://www.openedv.com/forum.php
//淘宝店铺:https://zhengdianyuanzi.tmall.com
//关注微信公众平台微信号:"正点原子",免费获取ZYNQ & FPGA & STM32 & LINUX资料。
//版权所有,盗版必究。
//Copyright(C) 正点原子 2023-2033
//All rights reserved                                  
//----------------------------------------------------------------------------------------
// File name:           uart_loopback
// Created by:          正点原子
// Created date:        2023年2月16日14:20:02
// Version:             V1.0
// Descriptions:        串口回环实验
//
//----------------------------------------------------------------------------------------
//****************************************************************************************//module top(input            sys_clk  ,   //外部50MHz时钟input            rst_n,   //系外部复位信号,低有效input            WAK,input            key1,input            key2,input            key3,input            key4,input            key5,input           [3:0]   r_pin,output  wire    [4:0]   led,output  wire    [3:0]   c_pin,output	wire	[5:0]	sel,output	wire	[7:0]	dig,//UART端口    input            uart_rxd ,   //UART接收端口output           uart_txd     //UART发送端口);
wire            button1_negedge;
wire            uart_tx_en; 
wire            uart_rx_done; 
wire            uart_tx_done; wire  [23:0]    correct_password;
wire            mima_flag;//密码正确标志
wire  [23:0]    mima;     //密码wire  [23:0]    din;     //                  
wire  [7:0]     uart_tx_data; 
wire  [7:0]     uart_rx_data; 
wire  [3:0]	    key_out;wire            hand_flag;
wire            check_hand_flag;
wire            led1;
wire            led2;
wire            led3;
wire            led4;
wire            led5;
wire            led6;assign led={led1,led2,led3,led4,led5};four_four_key u_four_four_key(.clk(sys_clk),//时钟.rst(rst_n),//复位.c_pin(c_pin),//行引脚.r_pin(r_pin),//列引脚.key_out(key_out)//按键编号输出
);
check_mima u_check_mima(.clk(sys_clk),           // 时钟信号.rst_n(rst_n),         // 异步复位信号,低有效.key3(key3),          // 启动密码输入的按键.r_pin(r_pin),   // 键盘输入(数字键的按下信号).key_out(key_out), // 键盘输出的具体数字.correct_password(correct_password),.mima(mima),    // 24位密码存储寄存器.mima_flag(mima_flag)       // 密码验证标志
);   
change_mima u_change_mima(.clk(sys_clk),           // 时钟信号.rst_n(rst_n),         // 异步复位信号,低有效.key4(key4),          // 启动密码输入的按键.r_pin(r_pin),   // 键盘输入(数字键的按下信号).key_out(key_out), // 键盘输出的具体数字.led_change(led6),    .correct_password(correct_password));check_hand u_check_hand(.clk(sys_clk),.rst_n(rst_n),.hand_flag(hand_flag),.check_hand_flag(check_hand_flag),.led_hand_right(led4),.led_hand_error(led5)
);seg_ctrl u_seg_ctrl( .clk(sys_clk)		,.rst_n(rst_n)	,.din(mima)		,//输入6位数码管显示数据,每位数码管占4位.point_n(6'b111111) ,//输入小数点控制位.sel(sel)	,//输出位选.dig(dig)  //输出段选
);	AS608_data u_AS608_data(.clk(sys_clk),.rst_n(rst_n),.WAK(WAK),.key1(key1),.key2(key2),.key3(key3),.key4(key4),.key5(key5),.led_hand1(led1),.led_hand2(led2),.led_hand3(led3),.hand_flag_r1(hand_flag),.check_hand_flag(check_hand_flag),.uart_tx_done(uart_tx_done),.uart_rx_data(uart_rx_data),.uart_rx_done(uart_rx_done),.uart_tx_en(uart_tx_en),.uart_tx_data(uart_tx_data));key_debounce u_key_debounce
(.sys_clk(sys_clk),.rst_n(rst_n),.key(key1),.button_negedge(button1_negedge) //Key falling edgz
);uart_top u_uart_top(.sys_clk(sys_clk)  ,   //外部50MHz时钟.sys_rst_n(rst_n),   //系外部复位信号,低有效.uart_rx_done  (uart_rx_done),.uart_rx_data  (uart_rx_data),.uart_tx_en   (uart_tx_en),.uart_tx_data (uart_tx_data),.uart_tx_done (uart_tx_done),.uart_rxd(uart_rxd) ,   //UART接收端口.uart_txd(uart_txd)     //UART发送端口);endmodule

9.仿真tb文件

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/12/02 20:16:35
// Design Name: 
// Module Name: tb_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//module tb_top();reg sys_clk;
reg rst_n; reg WAK;   
reg key1;  
reg key2;  
reg key3;  
reg key4;  
reg key5;  
reg uart_rxd;
reg [3:0]   r_pin;
wire [3:0]  c_pin;
wire	[5:0]	sel;
wire	[7:0]	dig;reg flag;
wire uart_txd;
parameter CLK_FREQ = 50000000;    //定义系统时钟频率
parameter UART_BPS = 115200  ;    //定义串口波特率top u_top(.sys_clk(sys_clk),.rst_n(rst_n),.WAK(WAK),.key1(key1),.key2(key2),.key3(key3),.key4(key4),.key5(key5),.c_pin(c_pin),.r_pin(r_pin),.sel(sel),//输出位选.dig(dig), .uart_rxd(uart_rxd) ,   //UART接收端口.uart_txd(uart_txd)     //UART发送端口);always #10 sys_clk=~sys_clk;initial beginsys_clk=0;rst_n=0;WAK=1;key1=0;key2=0;key3=0;key4=0;key5=0;flag=0;r_pin=4'b0000;uart_rxd=1;#100rst_n=1;#100key1=1;#120key1=0;#250000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;///22222222222222222222222222222222222222222222222222222222222222222ak#250000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;///22222222222222222222222222222222222222222222222222222222222222222ak#250000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;///22222222222222222222222222222222222222222222222222222222222222222ak#250000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#250000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;///22222222222222222222222222222222222222222222222222222222222222222ak#250000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;///22222222222222222222222222222222222222222222222222222222222222222ak#250000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000key1=1;#20key1=0;///22222222222222222222222222222222222222222222222222222222222222222ak#250000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#100key2=1;#20key2=0;///22222222222222222222222222222222222222222222222222222222222222222ak#250000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;///22222222222222222222222222222222222222222222222222222222222222222ak#300000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=0;#1720uart_rxd=1;#1000uart_rxd=0;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1736uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1000uart_rxd=0;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;#1720uart_rxd=1;key3=1;///mima#20key3=0;#100r_pin=4'b0100; //1#20r_pin=4'b0000;#100r_pin=4'b0010;//2#20r_pin=4'b0000;#100r_pin=4'b0001;//3#20r_pin=4'b0000;#500000r_pin=4'b1000;//4#20r_pin=4'b0000;#100r_pin=4'b0100;//5#20r_pin=4'b0000;#100r_pin=4'b0010;//6#20r_pin=4'b0000;#1000key3=1;///mima#20key3=0;#100r_pin=4'b0100; //1#20r_pin=4'b0000;#100r_pin=4'b0010;//2#20r_pin=4'b0000;#100r_pin=4'b0001;//3#20r_pin=4'b0000;#500000r_pin=4'b1000;//4#20r_pin=4'b0000;#100r_pin=4'b0100;//5#20r_pin=4'b0000;#100r_pin=4'b0010;//6#20r_pin=4'b0000;#1000key3=1;///mima#20key3=0;#100r_pin=4'b0100; //1#20r_pin=4'b0000;#100r_pin=4'b0010;//2#20r_pin=4'b0000;#100r_pin=4'b0001;//3#20r_pin=4'b0000;#500000r_pin=4'b1000;//4#20r_pin=4'b0000;#100r_pin=4'b0100;//5#20r_pin=4'b0000;#100r_pin=4'b0010;//6#20r_pin=4'b0000;#1000key3=1;///mima#20key3=0;#1000r_pin=4'b1000;//4#20r_pin=4'b0000;#100r_pin=4'b0100;//5#20r_pin=4'b0000;#100r_pin=4'b0010;//6#20r_pin=4'b0000;#1000r_pin=4'b1000;//4#20r_pin=4'b0000;#100r_pin=4'b0100;//5#20r_pin=4'b0000;#100r_pin=4'b0010;//6#20r_pin=4'b0000;#1000key4=1;#20key4=0;#1000#100r_pin=4'b0100; //1#20r_pin=4'b0000;#100r_pin=4'b0010;//2#20r_pin=4'b0000;#100r_pin=4'b0001;//3#20r_pin=4'b0000;#500000r_pin=4'b1000;//4#20r_pin=4'b0000;#100r_pin=4'b0100;//5#20r_pin=4'b0000;#100r_pin=4'b0010;//6#20r_pin=4'b0000;#1000r_pin=4'b1000;//4#20r_pin=4'b0000;#100r_pin=4'b0100;//5#20r_pin=4'b0000;#100r_pin=4'b0010;//6#20r_pin=4'b0000;end
//1736endmodule

这里接受的数据,没有按照手册来,只是将第10个数据设置为00,来表示通讯正确。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

其实就是围绕UART和状态机展开的逻辑编写,部分常见代码直接参考了正点原子、野火、等等案例,部分简单功能使用了chatgpt进行描述生成。实现难度并不大,就是涉及的模块较多,不过好好利用仿真结果能够差不多。代码有很多不足之处,有问题欢迎批评指正。

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

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

相关文章

静坐修心.

文章目录 打坐的历史文化渊源东方的起源与传承西方的接受与演变现代生活中的打坐 盘腿坐对身体的影响促进脊椎健康改善呼吸系统功能增强消化系统机能改善血液循环调节神经系统错误姿势及其他潜在危害 盘腿坐对心理的作用促进内心平静与放松提升自我觉察与内在探索培养专注力与精…

后端-编辑按钮的实现

编辑一共要实现两步&#xff1a; 1.点击编辑蹦出来一个弹窗&#xff0c;此时需要回显&#xff0c;根据id查出来这条数据 2.修改某些值之后点击保存的时候调用修改的接口 根据id查询的时候正常操作 修改值的时候要注意一些问题 mapper层的Employee和impl层的接收实体不一样

前端开发流程实操:从概念到上线

在前端开发这个充满创意与技术挑战的领域&#xff0c;一个清晰的开发流程是确保项目顺利进行并达到预期效果的关键。 下面就和大家分享一下前端开发的实操流程。 一、项目启动与需求分析 前端开发不是孤立的&#xff0c;它是整个项目的一部分&#xff0c;所以首先要与项目团…

IDE如何安装插件实现Go to Definition

项目背景 框架&#xff1a;Cucumber Cypress 语言&#xff1a;Javascript IDE&#xff1a;vscode 需求 项目根目录cypress-automation的cypress/integration是测试用例的存放路径&#xff0c;按照不同模块不同功能创建了很多子目录&#xff0c;cucumber测试用例.feature文…

Oracle Recovery Tools工具一键解决ORA-00376 ORA-01110故障(文件offline)---惜分飞

客户在win上面迁移数据文件,由于原库非归档,结果导致有两个文件scn不一致,无法打开库,结果他们选择offline文件,然后打开数据库 Wed Dec 04 14:06:04 2024 alter database open Errors in file d:\app\administrator\diag\rdbms\orcl\orcl\trace\orcl_ora_6056.trc: ORA-01113:…

ES使用script进行复杂排序

es数据字段&#xff0c;关注_source内容&#xff0c;为自定义的es表字段内容 {"clerk_id": 3150036230,"clerk_follow_status": 60,"create_time": 1729156110000,"channel": 1,"mid": 1538020071,"binlog_timestamp&…

【C++算法】32.前缀和_矩阵区域和

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a; 题目链接&#xff1a; 1314. 矩阵区域和 题目描述&#xff1a; 解法 防止有人看不明白题目&#xff0c;先解释一下题目 二维前缀和思想&#xff1a; 使用前缀和矩阵 ret [x1,y1]~[x2,y2] D …

【数据结构】树和森林

树的存储结构 双亲表示法 定义结构数组&#xff0c;存放树的结点&#xff0c;每个结点含两个域&#xff1a; ​ 数据域&#xff1a;存放结点信息 ​ 双亲域&#xff1a;指示结点的双亲结点在数组中的位置 typedef struct PTNode{TElemType data;int parent; }PTNode;#defi…

Thonny IDE + MicroPython + ESP32 + GY-302 测量环境中的光照强度

GY-302是一款基于BH1750FVI光照强度传感器芯片的模块。该模块能够直接测量出环境中的光照强度&#xff0c;并将光照强度转换为数字信号输出。其具体参数如下表所示。 参数名称 参数特性 测量范围 0-65535 LX 测量精度 在环境光下误差小于20%&#xff0c;能够自动忽略50/60…

智创 AI 新视界 -- AI 时代的数据隐私保护挑战与应对(16 - 3)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

网上图书购物管理系统|Java|SSM|VUE| 前后端分离

【一】可以提供远程部署安装&#xff0c;包扩环境 【二】提供软件相关的安装包 【三】如果需要提供java入门资料可咨询 【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、M…

双子气膜:科技与艺术的璀璨交融—轻空间

在城市的繁华一隅&#xff0c;即将崛起一座令人叹为观止的未来地标——双子气膜项目。这是由轻空间与国内知名企业强强联手打造的全新气膜球幕建筑&#xff0c;集合了尖端科技与视觉艺术&#xff0c;成为现代建筑领域的一次创意突破。 双子气膜&#xff1a;双球对称的震撼设计…

【全面】上市公司企业能源消耗数据(水、电、汽油、天然气、钢材等)2008-2022年

一、数据范围&#xff1a;包括水、电、汽油、天然气、钢材等3000多类能源&#xff0c;1.4万个样本。 二、资源类型&#xff1a;电 水 人均用电 人均用水 公务用车汽油 办公用水 办公用电 总行物业管理大楼办公用水 总…

双绞线直连两台电脑的方法及遇到的问题

文章目录 前言一、步骤二、问题总结&#xff1a;问题1:遇到ping不通的问题。问题2:访问其他电脑上的共享文件时提示输入网络凭证问题3:局域网共享文件时提示“没有权限访问&#xff0c;请与网络管理员联系请求访问权限” 前言 办公室里有两台电脑&#xff0c;一台装了显卡用于…

windows文件下换行, linux上不换行 解决CR换行符替换为LF notepad++

html文件是用回车换行的&#xff0c;在windows电脑上&#xff0c;显示正常。 文件上传到linux服务器后&#xff0c;文件不换行了。只有一行。而且相关js插件也没法正常运行。 用notepad查看&#xff0c;显示尾部换行符&#xff0c;是CR&#xff0c;这就是原因。CR是不被识别的。…

Android -- [SelfView] 自定义多行歌词滚动显示器

Android – [SelfView] 自定义多行歌词滚动显示器 流畅、丝滑的滚动歌词控件* 1. 背景透明&#xff1b;* 2. 外部可控制进度变化&#xff1b;* 3. 支持屏幕拖动调节进度&#xff08;回调给外部&#xff09;&#xff1b;效果 歌词文件&#xff08;.lrc&#xff09; 一. 使用…

Android APP自学笔记

摘抄于大学期间记录在QQ空间的一篇自学笔记&#xff0c;当前清理空间&#xff0c;本来想直接删除掉的&#xff0c;但是感觉有些舍不得&#xff0c;因此先搬移过来。 Android导入已有外部数据库 2015.06.26在QQ空间记录&#xff1a;在Android中不能直接打开res aw目录中的数据…

python进阶-05-利用Selenium来实现动态爬虫

python进阶-05-利用Selenium来实现动态爬虫 一.说明 这是python进阶部分05&#xff0c;我们上一篇文章学习了Scrapy来爬取网站&#xff0c;但是很多网站需要登录才能爬取有用的信息&#xff0c;或者网站的静态部分是一个空壳&#xff0c;内容是js动态加载的,或者人机验证&…

网安瞭望台第10期:开源机器学习框架存在漏洞、GammaDrop 恶意软件

研究人员发现流行开源机器学习框架存在漏洞 网络安全研究人员披露了多个影响开源机器学习&#xff08;ML&#xff09;工具和框架&#xff08;如 MLflow、H2O、PyTorch 和 MLeap&#xff09;的安全漏洞&#xff0c;这些漏洞可能导致代码执行。这些漏洞由 JFrog 发现&#xff0c;…

Onchain 正在蚕食 Offchain

目录 未来在链上 价值创造 技术加速 机构采用 小队&#xff1a;加速链上经济 我们正在进入一个代码就是货币、信任被编程、全球接入打破传统经济界限的时代。这种新兴模式就是我们所说的链上经济。 在此领域&#xff0c;Solana 因其在基础设施和应用程序方面的持续创新而脱颖而…