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

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

一、功能描述

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模块

实现思想:状态机

一路顺利就是这么个流程,不顺利的话就回到上个可以重新开始的流程。

c 复制代码
`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 03unsuccess
    reg     [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 16btye
    
    reg [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) begin
    if(!rst_n)begin
        hand_flag_r1<=1'b0;
        hand_flag_r<=1'b0;
    end else begin
        hand_flag_r1<=hand_flag;
        hand_flag_r<=hand_flag_r1;
        end
    end
    
    //各个状态return_data
    always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        uart_tx_data <= 8'd0;
    end
    else if((state==GET_HAND1 || state==GET_HAND2) && tx_count<6'd12 ) begin
        uart_tx_data <= cmd_state[95 - tx_count *8 -:8];
    end
    else if((state==FIND_HAND) && tx_count<6'd17 ) begin
        uart_tx_data <= cmd_find[135 - tx_count *8 -:8];
    end
    else if((state==COMPARE_FEATURE) && tx_count<6'd12 ) begin
        uart_tx_data <= cmd_compare[95 - tx_count *8 -:8];
    end
    else if((state==SAVE_FEATURE) && tx_count<6'd12 ) begin
        uart_tx_data <= cmd_save[95 - tx_count *8 -:8];
    end
    else if((state==SEND_FEATURE) && tx_count<6'd15 ) begin
        uart_tx_data <= cmd_send[119 - tx_count *8 -:8];
    end
    else if((state==MAKE_FEATURE1) && tx_count<6'd13 ) begin
        uart_tx_data <= cmd_make1[103 - tx_count *8 -:8];
    end
    else if((state==MAKE_FEATURE2) && tx_count<6'd13 ) begin
        uart_tx_data <= cmd_make2[103 - tx_count *8 -:8];
    end
    else begin
        uart_tx_data <= uart_tx_data;
    end
end
    //各个状态return_flag
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            find_flag <= 1'b0;
        end
        else if(key2==1'b1)begin
            find_flag <= ~find_flag;
        end
        else begin
            find_flag <= find_flag;
        end
    end
    
    //各个状态return_flag
    always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        return_flag <= 1'b0;
    end
    else if((state==WAK_HAND1 ||state==WAK_HAND2) && return_data==8'h00&& rx_count==11 && uart_rx_done==1'b1)  begin
        return_flag <= 1'b1;
    end
    else 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)  begin
        return_flag <= 1'b1;
    end
    else if((state==WAK_FIND) && return_data==8'h00 && rx_count==15 && uart_rx_done==1'b1)  begin
        return_flag <= 1'b1;
    end
    else begin
        return_flag <= 1'b0;
    end
end
    
    //各个状态return_data
    always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        return_data <= 8'b0;
    end
    else if((state==WAK_HAND1 ||state==WAK_HAND2) && rx_count==10 ) begin
        return_data <= uart_rx_data;
    end
    else if((state==WAK_FEATURE1 ||state==WAK_FEATURE2 || state== WAK_COMPARE || state==WAK_SAVE || state==WAK_FIND) && rx_count==10 ) begin
        return_data <= uart_rx_data;
    end
    else begin
        return_data <= return_data;
    end
end
    
    
    //各个状态data_tx_en
    always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        uart_tx_en_temp <= 1'b0;
        uart_tx_en <= uart_tx_en_temp;
    end
    else if((state==GET_HAND1 || state==GET_HAND2 || state==COMPARE_FEATURE || state==SAVE_FEATURE) && tx_en_count==1) begin
        uart_tx_en_temp <= 1'b1;
        uart_tx_en <= uart_tx_en_temp;
    end
    else if((state==MAKE_FEATURE1 || state==MAKE_FEATURE2 || state==SEND_FEATURE || state==FIND_HAND ) && tx_en_count==1) begin
        uart_tx_en_temp <= 1'b1;
        uart_tx_en <= uart_tx_en_temp;
    end
    else if((state==GET_HAND1 || state==GET_HAND2 || state==COMPARE_FEATURE || state==SAVE_FEATURE) && tx_count<6'd11 && uart_tx_done==1)begin
        uart_tx_en_temp <= 1'b1;
        uart_tx_en <= uart_tx_en_temp;
    end
    else if((state==MAKE_FEATURE1 || state==MAKE_FEATURE2) && tx_count<6'd12 && uart_tx_done==1)begin
        uart_tx_en_temp <= 1'b1;
        uart_tx_en <= uart_tx_en_temp;
    end
    else if((state==SEND_FEATURE) && tx_count<6'd14 && uart_tx_done==1)begin
        uart_tx_en_temp <= 1'b1;
        uart_tx_en <= uart_tx_en_temp;
    end
    else if((state==FIND_HAND) && tx_count<6'd16 && uart_tx_done==1)begin
        uart_tx_en_temp <= 1'b1;
        uart_tx_en <= uart_tx_en_temp;
    end
    else begin
        uart_tx_en_temp <= 1'b0;
        uart_tx_en <= uart_tx_en_temp;
    end
end
    //各个状态rx_count
    always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rx_count <= 6'd0;
    end
    else if((state==WAK_HAND1 ||state==WAK_HAND2 || state==WAK_FEATURE1 ||state==WAK_FEATURE2 || state== WAK_COMPARE || state==WAK_SAVE || state==WAK_SEND) ) begin
        if(uart_rx_done==1'd1)
            rx_count <= rx_count+1'b1;
        else if(rx_count==6'd12) begin
            rx_count <= 6'b0;
        end
        else begin
            rx_count <= rx_count;
        end
    end
    else if((state==WAK_FIND) ) begin
        if(uart_rx_done==1'd1)
            rx_count <= rx_count+1'b1;
        else if(rx_count==6'd16) begin
            rx_count <= 6'b0;
        end
        else begin
            rx_count <= rx_count;
        end
    end
end
    //各个状态tx_count
    always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        tx_count <= 6'd0;
    end
    else if((state==GET_HAND1 || state==GET_HAND2 || state==COMPARE_FEATURE || state==SAVE_FEATURE) ) begin
        if(uart_tx_done==1'd1)
            tx_count <= tx_count+1'b1;
        else if(tx_count==6'd12) begin
            tx_count <= 6'b0;
        end
        else begin
            tx_count <= tx_count;
        end
    end
    else if((state==MAKE_FEATURE1 || state==MAKE_FEATURE2) ) begin
        if(uart_tx_done==1'd1)
            tx_count <= tx_count+1'b1;
        else if(tx_count==6'd13) begin
            tx_count <= 6'b0;
        end
        else begin
            tx_count <= tx_count;
        end
    end
    else if((state==SEND_FEATURE) ) begin
        if(uart_tx_done==1'd1)
            tx_count <= tx_count+1'b1;
        else if(tx_count==6'd15) begin
            tx_count <= 6'b0;
        end
        else begin
            tx_count <= tx_count;
        end
    end
    else if((state==FIND_HAND) ) begin
        if(uart_tx_done==1'd1)
            tx_count <= tx_count+1'b1;
        else if(tx_count==6'd17) begin
            tx_count <= 6'b0;
        end
        else begin
            tx_count <= tx_count;
        end
    end
end
    //tx_en time
    always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        tx_en_count <= 2'b0;
    end
    else 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) begin
        tx_en_count <=tx_en_count+ 2'd1;
    end
    else 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) begin
        tx_en_count <= 2'd3;
    end
    else 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))begin
        tx_en_count <= 2'd0;
    end
    else begin
        tx_en_count <= tx_en_count;
    end
end
    //state go 
    always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        state <= 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;
    end
    else begin
        case(state)
        IDLE:begin
            blink_counter <= 0;
            hand_flag<=1'b0;
            check_hand_flag<=1'b0;
            if(key1==1'b1 && WAK==1'b1)begin
                state <= GET_HAND1;
            end
            else begin
                state <= IDLE;
            end
        end
        GET_HAND1:begin
            if(tx_count==6'd12)begin
                state <= WAK_HAND1;
            end
            else begin
                state <= GET_HAND1;
            end
        end
        
        WAK_HAND1:begin
            if(rx_count==6'd12 && return_flag==1'b1)begin
                state <= MAKE_FEATURE1;
            end
            else if(rx_count==6'd12 && return_flag==1'b0)begin
                state <= IDLE;
            end
            else begin
                state <= WAK_HAND1;
            end
        end
        HAND1_LED: begin
            if (blink_counter < 2) begin
                if (blink_timer == 16'd0) begin
                    led_hand1 = ~led_hand1; // 每秒反转一次 led
                    blink_counter = blink_counter + 1;
                end
            end else begin
                state = MAKE_FEATURE1; // 完成 10 次闪烁后返回 IDLE 状态
            end
        end
        MAKE_FEATURE1:begin
            if(tx_count==6'd13)begin
                state <= WAK_FEATURE1;
            end
            else begin
                state <= MAKE_FEATURE1;
            end
        end
        WAK_FEATURE1:begin
            if(find_flag==1'b0) begin
                 if(rx_count==6'd12 && return_flag==1'b1)begin
                     state <= GET_HAND2;
                 end
                 else if(rx_count==6'd12 && return_flag==1'b0)begin
                     state <= IDLE;
                 end
                 else begin
                     state <= WAK_FEATURE1;
                 end
            end
            else begin
                if(rx_count==6'd12 && return_flag==1'b1)begin
                     state <= FIND_HAND;
                 end
                 else if(rx_count==6'd12 && return_flag==1'b0)begin
                     state <= IDLE;
                 end
                 else begin
                     state <= WAK_FEATURE1;
                 end
            end
        end
        GET_HAND2:begin
            blink_counter <= 0;
            if(tx_count==6'd12)begin
                state <= WAK_HAND2;
            end
            else begin
                state <= GET_HAND2;
            end
        end
       WAK_HAND2:begin
            if(rx_count==6'd12 && return_flag==1'b1)begin
                state <= MAKE_FEATURE2;
            end
            else if(rx_count==6'd12 && return_flag==1'b0)begin
                state <= GET_HAND2;
            end
            else begin
                state <= WAK_HAND2;
            end
        end
        HAND2_LED: begin
            if (blink_counter < 2) begin
                if (blink_timer == 16'd0) begin
                    led_hand2 = ~led_hand2; // 每秒反转一次 led
                    blink_counter = blink_counter + 1;
                end
            end else begin
                state = MAKE_FEATURE2; // 完成 10 次闪烁后返回 IDLE 状态
            end
        end
        MAKE_FEATURE2:begin
            if(tx_count==6'd13)begin
                state <= WAK_FEATURE2;
            end
            else begin
                state <= MAKE_FEATURE2;
            end
        end
        WAK_FEATURE2:begin
            if(rx_count==6'd12 && return_flag==1'b1)begin
                state <= COMPARE_FEATURE;
            end
            else if(rx_count==6'd12 && return_flag==1'b0)begin
                state <= IDLE;
            end
            else begin
                state <= WAK_FEATURE2;
            end
        end
        COMPARE_FEATURE:begin
            if(tx_count==6'd12)begin
                state <= WAK_COMPARE;
            end
            else begin
                state <= COMPARE_FEATURE;
            end
        end
        WAK_COMPARE:begin
            if(rx_count==6'd12 && return_flag==1'b1)begin
                state <= SAVE_FEATURE;
            end
            else if(rx_count==6'd12 && return_flag==1'b0)begin
                state <= IDLE;
            end
            else begin
                state <= WAK_COMPARE;
            end
        end
        SAVE_FEATURE:begin
            if(tx_count==6'd12)begin
                state <= WAK_SAVE;
            end
            else begin
                state <= SAVE_FEATURE;
            end
        end
        WAK_SAVE:begin
            if(rx_count==6'd12 && return_flag==1'b1)begin
                state <= SEND_FEATURE;
            end
            else if(rx_count==6'd12 && return_flag==1'b0)begin
                state <= IDLE;
            end
            else begin
                state <= WAK_SAVE;
            end
        end
        SEND_FEATURE:begin
            if(tx_count==6'd15)begin
                state <= WAK_SEND;
            end
            else begin
                state <= SEND_FEATURE;
            end
        end
        WAK_SEND:begin
            if(rx_count==6'd12 && return_flag==1'b1)begin
                state <= IDLE;
            end
            else if(rx_count==6'd12 && return_flag==1'b0)begin
                state <= IDLE;
            end
            else begin
                state <= WAK_SEND;
            end
        end
        
        SAVE_LED: begin
            if (blink_counter < 2) begin
                if (blink_timer == 16'd0) begin
                    led_hand3 = ~led_hand3; // 每秒反转一次 led
                    blink_counter = blink_counter + 1;
                end
            end else begin
                state = IDLE; // 完成 10 次闪烁后返回 IDLE 状态
            end
        end
        FIND_HAND:begin
            if(tx_count==6'd17)begin
                state <= WAK_FIND;
            end
            else begin
                state <= FIND_HAND;
            end
        end
        WAK_FIND:begin
            
            if(rx_count==6'd16 && return_flag==1'b1)begin
                state <= IDLE;
                check_hand_flag<=1'b1;
                hand_flag<=1'b1;
            end
            else if(rx_count==6'd16 && return_flag==1'b0)begin
                state <= IDLE;
                check_hand_flag<=1'b1;
                hand_flag<=1'b0;
            end
            else begin
                state <= WAK_FIND;
            end
        end
        default:state <= IDLE;
        endcase
    end
end
// 计时器,用于实现 1 秒钟的闪烁周期
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        blink_timer <= 0;
    end else begin
        if (state == HAND2_LED ||state == HAND1_LED ||state == SAVE_LED) begin
            if (blink_timer == 16'd49999) // 假设时钟频率是 50MHz,每 1 秒
                blink_timer <= 0;
            else
                blink_timer <= blink_timer + 1;
        end else begin
            blink_timer <= 0;
        end
    end
end

    
endmodule

2.check_hand模块

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

代码如下(示例):

c 复制代码
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) begin
    if (!rst_n) begin
        blink_timer <= 0;
    end else begin
        if (state == BLINK) begin
            if (blink_timer == 16'd49999) // 假设时钟频率是 50MHz,每 1 秒
                blink_timer <= 0;
            else
                blink_timer <= blink_timer + 1;
        end else begin
            blink_timer <= 0;
        end
    end
end

// 错误状态计时器(10秒)
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        error_timer <= 0;
    end else if (state == ERROR) begin
        if (error_timer == 16'd49999) // 假设时钟频率是 50MHz,10秒
            error_timer <= 0; // 超过 10 秒后,计时器重置
        else
            error_timer <= error_timer + 1;
    end else begin
        error_timer <= 0; // 不是错误状态时,计时器清零
    end
end

// 状态转移与输出逻辑
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        state <=IDLE;
        led_hand_right <= 0;
        led_hand_error <=0;
    end
    else begin
    case(state)
        IDLE: begin
            if (check_hand_flag) begin
                state <=CHECK; // 如果检测标志位为1,进入检测状态
            end
            else begin
                state <=IDLE;
            end
        end
        CHECK: begin
            if (hand_flag) begin
                state <= BLINK; // 如果手势正确,进入闪烁状态
            end else begin
                state <= ERROR; // 如果手势错误,进入错误状态
            end
        end
        
        BLINK: begin
            if (blink_counter < 10) begin
                if (blink_timer == 16'd0) begin
                    led_hand_right = ~led_hand_right; // 每秒反转一次 led
                    blink_counter = blink_counter + 1;
                end
            end else begin
                state = IDLE; // 完成 10 次闪烁后返回 IDLE 状态
            end
        end
        
        ERROR: begin
            if (blink_counter < 10) begin
                if (error_timer == 16'd0) begin
                    led_hand_error <= ~led_hand_error; // 错误时,led_hand_error 10次
                    blink_counter <= blink_counter + 1;
                end
            end else begin
                state <= IDLE; // 完成 10 次闪烁后返回 IDLE 状态
            end
        end
    endcase
    end
end

// 控制闪烁次数
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        blink_counter <= 0;
    end else if (state == IDLE) begin
        blink_counter <= 0; // 重置闪烁计数器
    end
end

endmodule

3.four_four_key模块

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

c 复制代码
`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;//检测R1
	localparam				CHECK_R2=3'b001;//检测R2
	localparam				CHECK_R3=3'b011;//检测R3
	localparam				CHECK_R4=3'b010;//检测R4

	always @(posedge clk or negedge rst)
    begin
        if(!rst) begin
            state_r <= 3'b0;
        end
        else begin
            state_r <= state;
        end
    end
	assign clear_flag= (state_r==state)?1:0;
	always @(posedge clk or negedge rst)
    begin
        if(!rst) begin
            key_out_r <= 4'b0;
        end
        else begin
            key_out_r <= key_out;
        end
    end
  //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//此处设计每次拉高一行时间为1ms
		if(!rst)begin
			div_cnt <= 16'd0;
			cnt_full <= 1'b0;
		end
		else
			if(div_cnt==16'd49999)begin
				div_cnt <= 16'd0;
				cnt_full <= 1'b1;
			end
			else begin
				div_cnt <= div_cnt + 1'b1;
				cnt_full <= 1'b0;
			end
	end

	//状态组合判断
	always@(posedge cnt_full or negedge rst)begin
		if(!rst)begin
			state <= CHECK_R1;
			
	    end
		else begin
			case(state)
				CHECK_R1:
					if(cnt_full)begin
						state <= CHECK_R2;
						
						end
					else begin
						state <= CHECK_R1;
						
						end
				CHECK_R2:
				    if(cnt_full)begin
						state <= CHECK_R3;
						
						end
					else begin
						state <= CHECK_R2;
						
						end
				CHECK_R3:
					if(cnt_full)begin
						state <= CHECK_R4;
						
						end
					else begin
						state <= CHECK_R3;
					
						end
				CHECK_R4:
					if(cnt_full)begin
						state <= CHECK_R1;
					
						end
					else begin
						state <= CHECK_R4;
					
						end
				default: begin
					state <= state;
					
					end
			endcase
	end
	end
	//状态机输出逻辑
	always@(posedge clk or negedge rst)begin
		if(!rst)begin
			c_pin <= 4'b0000;
			key_out <= 4'd0;
	   end
		else begin
			case(state)
				CHECK_R1:begin
					c_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;
					endcase
				end
				CHECK_R2:begin
					c_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;
					endcase
				end
				CHECK_R3:begin
					c_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;
					endcase
				end
				CHECK_R4:begin
					c_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;
					endcase
				end	
				default:begin
					c_pin <= 4'b0000;
					key_out <= 4'd0;
				end
			endcase
			end
	end
endmodule

4.check_mima模块

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

c 复制代码
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) begin
        if (!rst_n) begin
            blink_timer <= 0;
        end else begin
            if (state == WARNING) begin
                if (blink_timer == 16'd20) // 假设时钟频率是 50MHz,每 1 秒
                    blink_timer <= 0;
                else
                    blink_timer <= blink_timer + 1;
            end else begin
                blink_timer <= 0;
            end
        end
    end
    
    // 状态机逻辑
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n)
            state <= IDLE;  // 异步复位时,状态机回到IDLE状态
        else
            state <= next_state;  // 按时钟更新状态
    end

    // 下一个状态的逻辑
    always @(posedge clk) begin
        case(state)
            IDLE: begin
                
                if (key3)           // 按下key3启动密码输入
                    next_state <=  STORE;
                else
                    next_state <= IDLE;
            end
            STORE: begin
                if (digit_count == 6)  // 密码输入6位后,进入校验状态
                    next_state <=  CHECK;
                else
                    next_state <=  STORE;
            end
            CHECK: begin
                if((mima_error_count==2) && (mima != correct_password))begin
                next_state <= WARNING;  // 校验完成后回到IDLE状态
                end else begin
                next_state <=  IDLE;
                end
            end
            WARNING: begin
               if (blink_counter == 10) begin
                    next_state <=  IDLE;
               end
               else begin
                    next_state <=  WARNING;
               end
            end
            default: next_state <= IDLE;
        endcase
    end

    // 密码输入存储逻辑
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            mima_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 begin
            case(state)
                IDLE: begin
                    mima_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;
                    end
                STORE: begin
                    if (r_pin != 4'b0000 && digit_count < 6) begin
                     digit_count <= digit_count + 1;
                    end
                        case(digit_count)
                        6:begin
                            mima_6<=key_out;
                        end
                        1:begin
                            mima_1<=key_out;
                        end
                        2:begin
                            mima_2<=key_out;
                        end
                        3:begin
                            mima_3<=key_out;
                        end
                        4:begin
                            mima_4<=key_out;
                        end
                        5:begin
                            mima_5<=key_out;
                        end
                        default:begin
                            mima_1<=4'd0;
                            mima_2<=4'd0;
                            mima_3<=4'd0;
                            mima_4<=4'd0;
                            mima_5<=4'd0;
                            mima_6<=4'd0;
                        end
                        endcase
                       
                end
                CHECK: begin
                    mima_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)begin
                        mima_error_count<=mima_error_count+1;
                        mima_flag <= 0;   // 密码验证失败,保持mima_flag为低
                        end
                end
                WARNING: begin
                   mima_error_count<=0;
                   if (blink_counter < 10) begin
                    if (blink_timer == 16'd0) begin
                        led_warning = ~led_warning; // 每秒反转一次 led
                        blink_counter = blink_counter + 1;
                    end
                  end 
                end
                
                
                default: begin
                    mima_flag <= 0;       // 在其他状态下,密码标志保持低
                end
            endcase
        end
    end

    assign mima={mima_1,mima_2,mima_3,mima_4,mima_5,mima_6};

endmodule

5.change_mima模块

类似check_mima模块

c 复制代码
`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) begin
    if (!rst_n) begin
        blink_timer <= 0;
    end else begin
        if (state == CHANGE_OK) begin
            if (blink_timer == 16'd100) // 假设时钟频率是 50MHz,每 1 秒
                blink_timer <= 0;
            else
                blink_timer <= blink_timer + 1;
        end else begin
            blink_timer <= 0;
        end
    end
end
     // 状态机逻辑
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n)
            state <= IDLE;  // 异步复位时,状态机回到IDLE状态
        else
            state <= next_state;  // 按时钟更新状态
    end
    
     // 下一个状态的逻辑
    always @(posedge clk) begin
        case(state)
            IDLE: begin
                if (key4)           // 按下key3启动密码输入
                    next_state = STORE;
                else
                    next_state = IDLE;
            end
            STORE: begin
                if (digit_count == 6)  // 密码输入6位后,进入校验状态
                    next_state <= CHANGE_OK;
                else
                    next_state <= STORE;
            end
            CHANGE_OK: begin
                if(blink_counter == 10)
                 next_state <=  IDLE;  // 校验完成后回到IDLE状态
                else begin
                 next_state <=  CHANGE_OK; 
                end
            end
            default: next_state <=  IDLE;
        endcase
    end
    
     // 密码输入存储逻辑
    always @(posedge clk or negedge rst_n) begin
        if (~rst_n) begin
            mima_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 begin
            case(state)
                IDLE: begin
                     mima_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;     // 清空输入的位数
                end
                STORE: begin
                    if (r_pin != 4'b0000 && digit_count < 6) begin
                     digit_count <= digit_count + 1;
                    end
                        case(digit_count)
                        6:begin
                            mima_6<=key_out;
                        end
                        1:begin
                            mima_1<=key_out;
                        end
                        2:begin
                            mima_2<=key_out;
                        end
                        3:begin
                            mima_3<=key_out;
                        end
                        4:begin
                            mima_4<=key_out;
                        end
                        5:begin
                            mima_5<=key_out;
                        end
                        default:begin
                            mima_1<=mima_1;
                            mima_2<=mima_2;
                            mima_3<=mima_3;
                            mima_4<=mima_4;
                            mima_5<=mima_5;
                            mima_6<=mima_6;
                        end
                        endcase
                       
                end
                CHANGE_OK: begin
                if (blink_counter < 10) begin
                if (blink_timer == 16'd0) begin
                    led_change<= ~led_change; // 每秒反转一次 led
                    blink_counter <= blink_counter + 1;
                end
            end else begin
                    blink_counter <= blink_counter;
            end
                end
                default: begin
                        state<=IDLE;
                end
            endcase
        end
    end
    
endmodule

6.seg_ctrl模块

数码管显示模块

c 复制代码
/**************************************功能介绍***********************************
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,//0
               NUM_1 = 7'b111_1001,//1
               NUM_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,//b
               C     = 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)begin
            cnt_1ms <= 'd0;
        end 
        else if(add_cnt_1ms)begin 
            if(end_cnt_1ms)begin 
                cnt_1ms <= 'd0;
            end
            else begin 
                cnt_1ms <= cnt_1ms + 1'b1;
            end 
        end
    end 
    
    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)begin
            sel <= 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)begin
            disp_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]; end
                6'b111_011 : begin disp_data <= din[11:8] ; point_n_r <= point_n[2]; end
                6'b110_111 : begin disp_data <= din[15:12]; point_n_r <= point_n[3]; end
                6'b101_111 : begin disp_data <= din[19:16]; point_n_r <= point_n[4]; end
                6'b011_111 : begin disp_data <= din[23:20]; point_n_r <= point_n[5]; end
                default: disp_data <= 'd0;
            endcase
        end 
    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;
        endcase
    end


endmodule

7.uart_top模块

c 复制代码
//****************************************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//

c 复制代码
//****************************************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) begin
    if(!rst_n) begin
        uart_rxd_d0 <= 1'b0;
        uart_rxd_d1 <= 1'b0;
        uart_rxd_d2 <= 1'b0;
    end
    else begin
        uart_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) begin
    if(!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;
    else
        rx_flag <= rx_flag;
end        

//波特率的计数器赋值
always @(posedge clk or negedge rst_n) begin
    if(!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    
    else
        baud_cnt <= 16'd0;     //接收过程结束时计数器清零
end

//对接收数据计数器(rx_cnt)进行赋值
always @(posedge clk or negedge rst_n) begin
    if(!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;        //接收数据计数器加1
        else
            rx_cnt <= rx_cnt;
    end
    else
        rx_cnt <= 4'd0;                     //接收过程结束时计数器清零
end        

//根据rx_cnt来寄存rxd端口的数据
always @(posedge clk or negedge rst_n) begin
    if(!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  
        end
        else
            rx_data_t <= rx_data_t;
    end
    else
        rx_data_t <= 8'b0;
end        

//给接收完成信号和接收到的数据赋值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        uart_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) begin
        uart_rx_done <= 1'b1     ;  //拉高接收完成信号
        uart_rx_data <= rx_data_t;  //并对UART接收到的数据进行赋值
    end    
    else begin
        uart_rx_done <= 1'b0;
        uart_rx_data <= uart_rx_data;
    end
end

endmodule

//uart_tx//

//uart_tx//

//uart_tx//

c 复制代码
//****************************************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) begin
    if(!rst_n) 
        uart_tx_done<=1'b0;
    else if(tx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX - 1) begin
       uart_tx_done<=1'b1;
    end    
    else
        uart_tx_done<=1'b0;     //发送过程结束时计数器清零
end


//*****************************************************
//**                    main code
//*****************************************************

//当uart_tx_en为高时,寄存输入的并行数据,并拉高BUSY信号
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        tx_data_t <= 8'b0;
        uart_tx_busy <= 1'b0;
    end
    //发送使能时,寄存要发送的数据,并拉高BUSY信号
    else if(uart_tx_en) begin
        tx_data_t <= uart_tx_data;
        uart_tx_busy <= 1'b1;
    end
    //当计数到停止位结束时,停止发送过程
    else if(tx_cnt == 4'd9 && baud_cnt == BAUD_CNT_MAX - 1) begin
        tx_data_t <= 8'b0;     //清空发送数据寄存器
        uart_tx_busy <= 1'b0;  //并拉低BUSY信号
    end
    else begin
        tx_data_t <= tx_data_t;
        uart_tx_busy <= uart_tx_busy;
    end
end

//波特率的计数器赋值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        baud_cnt <= 16'd0;
    else if(uart_tx_en)  
        baud_cnt <= 16'd0;      
    //当处于发送过程时,波特率计数器(baud_cnt)进行循环计数
    else if(uart_tx_busy) begin
        if(baud_cnt < BAUD_CNT_MAX - 1'b1)
            baud_cnt <= baud_cnt + 16'b1;
        else 
            baud_cnt <= 16'd0; //计数达到一个波特率周期后清零
    end    
    else
        baud_cnt <= 16'd0;     //发送过程结束时计数器清零
end

//tx_cnt进行赋值
always @(posedge clk or negedge rst_n) begin
    if(!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;        //发送数据计数器加1
        else
            tx_cnt <= tx_cnt;
    end
    else
        tx_cnt <= 4'd0;                     //发送过程结束时计数器清零
end

//根据tx_cnt来给uart发送端口赋值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        uart_txd <= 1'b1;
    else if(uart_tx_busy) begin
        case(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;
        endcase
    end
    else
        uart_txd <= 1'b1;                    //空闲时发送端口为高电平
end

endmodule

8.key_debounce模块

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

c 复制代码
//
//                                                                              //
//                                                                              //
//  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模块

c 复制代码
//****************************************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文件

c 复制代码
`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 begin
    sys_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;
    #100
    rst_n=1;
    
    #100
    key1=1;
    #120
    key1=0;
    #250000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
    ///22222222222222222222222222222222222222222222222222222222222222222ak
    #250000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
    
    ///22222222222222222222222222222222222222222222222222222222222222222ak
    #250000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
    ///22222222222222222222222222222222222222222222222222222222222222222ak
    #250000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
    
    #250000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
     ///22222222222222222222222222222222222222222222222222222222222222222ak
    #250000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
     ///22222222222222222222222222222222222222222222222222222222222222222ak
    #250000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    key1=1;
    
    #20
    key1=0;
    
    ///22222222222222222222222222222222222222222222222222222222222222222ak
    #250000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
    #100
    key2=1;
    #20
    key2=0;
    
     ///22222222222222222222222222222222222222222222222222222222222222222ak
    #250000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
    
    
    
    ///22222222222222222222222222222222222222222222222222222222222222222ak
    #300000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
   uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1000
    
    uart_rxd=0;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1736
    uart_rxd=1;
    #1000
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1000
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
    #1000
    uart_rxd=0;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    #1720
    uart_rxd=1;
    
    key3=1;///mima
    #20
    key3=0;
    
    #100
    
    r_pin=4'b0100; //1
    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//2
    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0001;//3
    #20
    r_pin=4'b0000;
    #500000
    r_pin=4'b1000;//4

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0100;//5

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//6

    #20
    r_pin=4'b0000;
    #1000
    key3=1;///mima
    #20
    key3=0;
    
    #100
    
    r_pin=4'b0100; //1
    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//2
    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0001;//3
    #20
    r_pin=4'b0000;
    #500000
    r_pin=4'b1000;//4

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0100;//5

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//6

    #20
    r_pin=4'b0000;
    #1000
    key3=1;///mima
    #20
    key3=0;
    
    #100
    
    r_pin=4'b0100; //1
    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//2
    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0001;//3
    #20
    r_pin=4'b0000;
    #500000
    r_pin=4'b1000;//4

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0100;//5

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//6

    #20
    r_pin=4'b0000;
    #1000
     key3=1;///mima
    #20
    key3=0;
    
    #1000
    r_pin=4'b1000;//4

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0100;//5

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//6

    #20
    r_pin=4'b0000;
     #1000
    r_pin=4'b1000;//4

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0100;//5

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//6

    #20
    r_pin=4'b0000;
    
    #1000
    
    key4=1;
    #20
    key4=0;
    #1000
    #100
    
    r_pin=4'b0100; //1
    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//2
    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0001;//3
    #20
    r_pin=4'b0000;
    #500000
    r_pin=4'b1000;//4

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0100;//5

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//6

    #20
    r_pin=4'b0000;
    #1000
    r_pin=4'b1000;//4

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0100;//5

    #20
    r_pin=4'b0000;
    #100

    r_pin=4'b0010;//6

    #20
    r_pin=4'b0000;
    
end
//1736

endmodule

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


总结

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

相关推荐
修己xj7 小时前
Anki:让记忆更高效、更智能的开源力量
开源
冬奇Lab13 小时前
一天一个开源项目(第17篇):ViMax - 多智能体视频生成框架,导演、编剧、制片人全包
开源·音视频开发
一个处女座的程序猿15 小时前
AI之Agent之VibeCoding:《Vibe Coding Kills Open Source》翻译与解读
人工智能·开源·vibecoding·氛围编程
一只大侠的侠16 小时前
React Native开源鸿蒙跨平台训练营 Day16自定义 useForm 高性能验证
flutter·开源·harmonyos
IvorySQL16 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
一只大侠的侠17 小时前
Flutter开源鸿蒙跨平台训练营 Day11从零开发商品详情页面
flutter·开源·harmonyos
一只大侠的侠17 小时前
React Native开源鸿蒙跨平台训练营 Day18自定义useForm表单管理实战实现
flutter·开源·harmonyos
一只大侠的侠17 小时前
React Native开源鸿蒙跨平台训练营 Day20自定义 useValidator 实现高性能表单验证
flutter·开源·harmonyos
晚霞的不甘18 小时前
Flutter for OpenHarmony 可视化教学:A* 寻路算法的交互式演示
人工智能·算法·flutter·架构·开源·音视频
晚霞的不甘19 小时前
Flutter for OpenHarmony 实现计算几何:Graham Scan 凸包算法的可视化演示
人工智能·算法·flutter·架构·开源·音视频