首页 > 其他分享 >基于EP4CE6F17C8的FPGA矩阵键盘实例(另类方法)

基于EP4CE6F17C8的FPGA矩阵键盘实例(另类方法)

时间:2024-04-22 12:55:20浏览次数:33  
标签:count seg FPGA 矩阵 EP4CE6F17C8 键盘 key

一、电路模块

电路模块参见“基于EP4CE6F17C8的FPGA矩阵键盘实例”部分。

二、实验代码

本例使用6个数码管依次显示按下按键的键值,每位显示的值可从0~F,对应16个矩阵按键。按键reset为复位键,代码使用Verilog编写,具体如下。

先编写数码管实现显示字形解码的程序,模块名称为seg_decode,文件名称为seg_decode.v,代码如下。

module seg_decode(
        input[4:0]         data,          //显示的字形,可显示0~F十六个字形,所以需要5位
        output reg[7:0]    seg7           //字形编码,包含小数点,共8位
);
always@(*)                                //敏感信号为所有输入量
begin
    case(data)
        5'd0:seg7 <= 8'b1100_0000;        //字形0的编码
        5'd1:seg7 <= 8'b1111_1001;        //字形1的编码
        5'd2:seg7 <= 8'b1010_0100;        //字形2的编码
        5'd3:seg7 <= 8'b1011_0000;        //字形3的编码
        5'd4:seg7 <= 8'b1001_1001;        //字形4的编码
        5'd5:seg7 <= 8'b1001_0010;        //字形5的编码
        5'd6:seg7 <= 8'b1000_0010;        //字形6的编码
        5'd7:seg7 <= 8'b1111_1000;        //字形7的编码
        5'd8:seg7 <= 8'b1000_0000;        //字形8的编码
        5'd9:seg7 <= 8'b1001_0000;        //字形9的编码
        5'ha:seg7 <= 8'b1000_1000;        //字形A的编码
        5'hb:seg7 <= 8'b1000_0011;        //字形B的编码
        5'hc:seg7 <= 8'b1100_0110;        //字形C的编码
        5'hd:seg7 <= 8'b1010_0001;        //字形D的编码
        5'he:seg7 <= 8'b1000_0110;        //字形E的编码
        5'hf:seg7 <= 8'b1000_1110;        //字形F的编码
        default:
             seg7 <= 8'b1111_1111;        //默认不显示
    endcase
end
endmodule

接下来编写矩阵键盘扫描程序,模块名称为key4x4,文件名称为key4x4.v,代码如下。

module key4x4(
        input              clk,                  //系统时钟
        input              rst_n,                //复位按键
        input[3:0]         key_in_y,             //输入矩阵键盘的列信号(KEY0~KEY3)
        output reg[3:0]    key_out_x,            //输出矩阵键盘的行信号(KEY4~KEY7)                            
        output reg[4:0]    key_val               //输出矩阵键盘按键键值
);
reg[19:0] count;                                 //定义20位扫描计数器
//20ms整体扫描矩阵键盘一次矩阵键盘
always @(posedge clk or negedge rst_n)           //敏感信号为时钟上沿或复位下沿
begin
   if(!rst_n)                                    //低电平复位
    begin
      count <= 20'd0;
      key_out_x <= 4'b1111;                      //复位时计数值清零,行输出全1  
   end        
   else
    begin
    if(count == 20'd0)                           //0ms时扫描第一行
    begin
        key_out_x <= 4'b1110;                    //第一行输出0
        count <= count + 20'b1;                  //计数器加1
    end
    else if(count == 20'd249_999)                //5ms时扫描第二行
    begin
        key_out_x <= 4'b1101;                    //第二行输出0
        count <= count + 20'b1;                  //计数器加1
    end                
    else if(count ==20'd499_999)                 //10ms时扫描第三行
    begin
        key_out_x <= 4'b1011;                    //第三行输出0
        count <= count + 20'b1;                  //计数器加1
    end    
    else if(count ==20'd749_999)                 //15ms时扫描第四行
    begin
        key_out_x <= 4'b0111;                    //第四行输出0
        count <= count + 20'b1;                  //计数器加1
    end                
    else if(count ==20'd999_999)                 //20ms时计数器清零
    begin
        count <= 0;
    end    
    else
        count <= count + 20'b1;                  //计数器加1            
    end
end
//采样列的按键信号
reg[3:0] key_h1_scan;                            //第一行按键扫描值KEY
reg[3:0] key_h1_scan_r;                          //第一行按键扫描值寄存器KEY
reg[3:0] key_h2_scan;                            //第二行按键扫描值KEY
reg[3:0] key_h2_scan_r;                          //第二行按键扫描值寄存器KEY
reg[3:0] key_h3_scan;                            //第三行按键扫描值KEY
reg[3:0] key_h3_scan_r;                          //第三行按键扫描值寄存器KEY
reg[3:0] key_h4_scan;                            //第四行按键扫描值KEY
reg[3:0] key_h4_scan_r;                          //第四行按键扫描值寄存器KEY
always @(posedge clk or negedge rst_n)           //敏感信号为时钟上沿或复位下沿
begin
    if(!rst_n)                                   //低电平复位,复位时按键扫描值全部置1
    begin
        key_h1_scan <= 4'b1111;     
        key_h2_scan <= 4'b1111;          
        key_h3_scan <= 4'b1111;          
        key_h4_scan <= 4'b1111;        
    end        
    else
    begin
    if(count == 20'd124_999)                     //2.5ms时获取第一行矩阵键盘值
        key_h1_scan <= key_in_y;
    else if(count == 20'd374_999)                //7.5ms时获取第二行矩阵键盘值
        key_h2_scan <= key_in_y;
    else if(count == 20'd624_999)                //12.5ms时获取第三行矩阵键盘值
        key_h3_scan <= key_in_y;
    else if(count == 20'd874_999)                //17.5ms时获取第四行矩阵键盘值
        key_h4_scan <= key_in_y; 
    end
end
//获取到的按键信号锁存一个时钟节拍,用于后面产生按键节拍
always @(posedge clk)
begin
        key_h1_scan_r <= key_h1_scan;       
        key_h2_scan_r <= key_h2_scan; 
        key_h3_scan_r <= key_h3_scan; 
        key_h4_scan_r <= key_h4_scan;  
end 
//以下为第一行扫描的四个按键有效值,当检测到本行按键有下降沿时,flag_h1_key有效一个时钟周期   
wire[3:0] flag_h1_key = key_h1_scan_r[3:0] & (~key_h1_scan[3:0]);
//以下为第二行扫描的四个按键有效值,当检测到本行按键有下降沿时,flag_h2_key有效一个时钟周期
wire[3:0] flag_h2_key = key_h2_scan_r[3:0] & (~key_h2_scan[3:0]);
//以下为第三行扫描的四个按键有效值,当检测到本行按键有下降沿时,flag_h3_key有效一个时钟周期 
wire[3:0] flag_h3_key = key_h3_scan_r[3:0] & (~key_h3_scan[3:0]);
//以下为第四行扫描的四个按键有效值,当检测到本行按键有下降沿时,flag_h4_key有效一个时钟周期 
wire[3:0] flag_h4_key = key_h4_scan_r[3:0] & (~key_h4_scan[3:0]);
//按键键值编码
always @ (posedge clk or negedge rst_n)          //敏感信号为时钟上沿或复位下沿
begin
    if (!rst_n)                                  //低电平复位
        key_val <= 5'b11111;                     //复位时键值全部置1
    else
    begin            
         if(flag_h1_key[0])                      //矩阵键盘key1键按下,键值为0
            key_val <= 5'd0;
         else                                    //key1未按下,键值恢复为全1
            key_val <= 5'b11111;
         if(flag_h1_key[1])                      //矩阵键盘key2键按下,键值为1
            key_val <= 5'd1;
         if(flag_h1_key[2])                      //矩阵键盘key3键按下,键值为2
            key_val <= 5'd2;
         if(flag_h1_key[3])                      //矩阵键盘key4键按下,键值为3
            key_val <= 5'd3;
         if(flag_h2_key[0])                      //矩阵键盘key5键按下,键值为4
            key_val <= 5'd4;
         if(flag_h2_key[1])                      //矩阵键盘key6键按下,键值为5
            key_val <= 5'd5;
         if(flag_h2_key[2])                      //矩阵键盘key7键按下,键值为6
            key_val <= 5'd6;
         if(flag_h2_key[3])                      //矩阵键盘key8键按下,键值为7
            key_val <= 5'd7;
         if(flag_h3_key[0])                      //矩阵键盘key9键按下,键值为8
            key_val <= 5'd8;
         if(flag_h3_key[1])                      //矩阵键盘key10键按下,键值为9
            key_val <= 5'd9;
         if(flag_h3_key[2])                      //矩阵键盘key11键按下,键值为10
            key_val <= 5'd10;
         if(flag_h3_key[3])                      //矩阵键盘key12键按下,键值为11
            key_val <= 5'd11;
         if(flag_h4_key[0])                      //矩阵键盘key13键按下,键值为12
            key_val <= 5'd12;
         if(flag_h4_key[1])                      //矩阵键盘key14键按下,键值为13
            key_val <= 5'd13;
         if(flag_h4_key[2])                      //矩阵键盘key15键按下,键值为14
            key_val <= 5'd14;
         if(flag_h4_key[3])                      //矩阵键盘key16键按下,键值为15
            key_val <= 5'd15;
    end
end
endmodule

最后编写显示模块,并设置为顶层模块,模块名称为key_show,文件名称为key_show.v,代码如下。

module key_show(
    input               clk,                            //板载50HMz系统时钟
    input               rst_n,                          //复位按键
    input[3:0]          key_in_y,                       //输入矩阵键盘的列信号(KEY0~KEY3)
    output[3:0]         key_out_x,                      //输出矩阵键盘的行信号(KEY4~KEY7)
    output reg[7:0]     seg7,                           //段码端口
    output reg[5:0]     bit                             //位选端口
);
wire[4:0]    key_val;                                   //定义键值存储变量
//下面例化矩阵键盘
key4x4 u1(.clk(clk), .rst_n(rst_n), .key_in_y(key_in_y), .key_out_x(key_out_x), .key_val(key_val));
//下面定义6个数码管的字形码存储变量
wire [7:0] seg_0,seg_1,seg_2,seg_3,seg_4,seg_5;
//下面定义6个数码管显示数值的存储变量
reg [4:0] count_data0 = 5'b11111;
reg [4:0] count_data1 = 5'b11111;
reg [4:0] count_data2 = 5'b11111;
reg [4:0] count_data3 = 5'b11111;
reg [4:0] count_data4 = 5'b11111;
reg [4:0] count_data5 = 5'b11111;
//下面例化秒的个位字形解码单元
seg_decode seg0(.data(count_data0), .seg7(seg_0));
//下面例化秒的十位字形解码单元
seg_decode seg1(.data(count_data1), .seg7(seg_1));
//下面例化分的个位字形解码单元
seg_decode seg2(.data(count_data2), .seg7(seg_2));
//下面例化分的十位字形解码单元
seg_decode seg3(.data(count_data3), .seg7(seg_3));
//下面例化时的个位字形解码单元
seg_decode seg4(.data(count_data4), .seg7(seg_4));
//下面例化时的十位字形解码单元
seg_decode seg5(.data(count_data5), .seg7(seg_5));
always @(posedge clk or negedge rst_n)                  //敏感信号为时钟上沿或复位下沿
begin
   if(!rst_n)                                           //低电平复位,复位时数值存储变量全部置1
    begin
      count_data0 <= 5'b11111;
        count_data1 <= 5'b11111;
        count_data2 <= 5'b11111;
        count_data3 <= 5'b11111;
        count_data4 <= 5'b11111;
        count_data5 <= 5'b11111;  
   end        
   else
    begin
    case(key_val)                                       //判断键值
        5'd0:                                           //0号键值,显示左移一位,最低位显示0
        begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd0;
        end
        5'd1:                                           //1号键值,显示左移一位,最低位显示1
        begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd1;
        end
        5'd2:                                           //2号键值,显示左移一位,最低位显示2
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd2;
        end
        5'd3:                                           //3号键值,显示左移一位,最低位显示3
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd3;
        end
        5'd4:                                           //4号键值,显示左移一位,最低位显示4
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd4;
        end
        5'd5:                                           //5号键值,显示左移一位,最低位显示5
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd5;
        end
        5'd6:                                           //6号键值,显示左移一位,最低位显示6
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd6;
        end
        5'd7:                                           //7号键值,显示左移一位,最低位显示7
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd7;
        end
        5'd8:                                           //8号键值,显示左移一位,最低位显示8
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd8;
        end
        5'd9:                                           //9号键值,显示左移一位,最低位显示9
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd9;
        end
        5'd10:                                          //10号键值,显示左移一位,最低位显示A
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd10;
        end
        5'd11:                                          //11号键值,显示左移一位,最低位显示b
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd11;
        end
        5'd12:                                          //12号键值,显示左移一位,最低位显示C
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd12;
        end
        5'd13:                                          //13号键值,显示左移一位,最低位显示d
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd13;
        end
        5'd14:                                          //14号键值,显示左移一位,最低位显示E
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd14;
        end
        5'd15:                                          //15号键值,显示左移一位,最低位显示F
            begin
            count_data5 <= count_data4;
            count_data4 <= count_data3;
            count_data3 <= count_data2;
            count_data2 <= count_data1;
            count_data1 <= count_data0;
            count_data0 <= 5'd15;
        end
    endcase
    end
end
reg[17:0]    time_cnt;                                  //定义20位时钟计数器
reg[3:0]     scan_sel;                                     //定义扫描位置计数器
//3.3毫秒循环计数
always@(posedge clk or negedge rst_n)                   //敏感信号为时钟上沿或复位下沿
begin
    if(rst_n == 1'b0)                                   //低电平复位时计数器全部清零
    begin
        time_cnt <= 18'd0;
        scan_sel <= 4'd0;
    end
    else if(time_cnt >= 18'd166_666)                    //时钟计数器到达3.3毫秒时
    begin
        time_cnt <= 18'd0;                              //时钟计数器清零
        if(scan_sel == 4'd5)                            //如果扫描位置计数器已经到1则恢复0
            scan_sel <= 4'd0;
        else
            scan_sel <= scan_sel + 4'd1;                //否则扫描位置计数器加1,即每3.3ms加一次
    end
    else
        begin
            time_cnt <= time_cnt + 18'd1;               //否则时钟计数器加1,即来一次时钟脉冲加一次
        end
end
//数码管扫描显示
always@(posedge clk or negedge rst_n)                   //敏感信号为时钟上沿或复位下沿
begin
    if(!rst_n)                                          //低电平复位时数码管全灭
    begin
        bit <= 6'b111111;
        seg7 <= 8'hff;
    end
    else 
        case(scan_sel)
            4'd0:                                       //数码管0显示个位
            begin
                bit <= 6'b111110;
                seg7 <= seg_0;
            end
            4'd1:                                       //数码管1显示十位
            begin
                bit <= 6'b111101;
                seg7 <= seg_1;
            end
                4'd2:                                   //数码管2显示百位
            begin
                bit <= 6'b111011;
                seg7 <= seg_2;
            end
                4'd3:                                   //数码管3显示千位
            begin
                bit <= 6'b110111;
                seg7 <= seg_3;
            end
                4'd4:                                   //数码管4显示万位
            begin
                bit <= 6'b101111;
                seg7 <= seg_4;
            end
                4'd5:                                   //数码管5显示十万位
            begin
                bit <= 6'b011111;
                seg7 <= seg_5;
            end
            default:                                    //数码管全部熄灭
            begin
                bit <= 6'b111111;
                seg7 <= 8'hff;
            end
        endcase
end
endmodule

三、代码说明

1、本例主要讨论矩阵键盘的设计方法,数码管的扫描及字形解码可参看“基于EP4CE6F17C8的FPGA数码管动态显示实例”一文。
2、本例中使用的矩阵键盘为4X4型,共16个按键,行、列各引出4个引脚,共8个引脚。程序代码先对第一行输出0,其余行输出1;经过5ms之后第二行输出0,第一行输出1;再过5ms之后,第三行输出0,第二行输出1;再过5ms之后,第四行输出0,第三行输出1;再过5ms之后重复第一行扫描。全部行扫描一次用时20ms。
3、获取按键值的时刻取5ms的一半,即2.5ms进行。在第一个2.5ms时读取四个列的数据,即在第一行输出0的5ms时间的中点取列上的数据,第二个在7.5ms时读取,第三个在12.5ms时读取,第四个在17.5ms时读取。
4、把第3步获取到的四个按键数据锁存一个时钟节拍,用于产生按键节拍,具体原理可参见“基于EP4CE6F17C8的FPGA键控灯实例”一文。
5、把第4步锁存的前后两个数据进行相关逻辑操作(如key_h1_scan_r[3:0] & (~key_h1_scan[3:0])得到下降沿, (~key_h1_scan_r[3:0])&key_h1_scan[3:0])得到上升沿,可得到本行扫描时的有效按键的值(有效时对应位为1),且存续一个时钟周期,之后恢复到全0。
6、对全部四行扫描到的16个按键有效值进行编码,键值从0编到15。在输出键值编码时,仍然采取一个时钟周期有效的方式,即健值只存在一个时钟周期。这样可以有效消除按一次键形成多次动作的缺陷。
7、在对按键值进行编码的代码中,只有第一个if语句使用了else,其原因如下。当flag_h1_key[0]有效时,在本时钟周期内,只对它进行编码(key_val <= 5'd0),若无效则编码一个无效的键值(5'b11111,因为只有16个按键编码不到该值)。当flag_h1_key[1]有效时,在本时钟周期内,只对它进行编码(key_val <= 5'd1),其余14个按键编码均如此。由于16个按键flag_hm_key[n]的有效信号只存在一个时钟周期,所以,在当前时钟周期内,都会对有效按键进行编码,但在下一个时钟周期内所有按键都无效,因此会执行第一个if的else部分,即输出无效编码。这样就保证了键值编码只会输出一个时钟周期。注意,无效赋值(key_val <= 5'b11111)只能放在第一个if语句中的else部分,理由如下。假设放在最后一个if语句的else中,则除了最后个按键外其他所有按键都得不到编码。因为前面所有的编码都会被最后一个if语句的else部分所覆盖。相反,放在第一个if语句中,当flag_h1_key[0]无效时,编码先被赋无效值5'b11111,但在其后按键有效时编码会被真实键值覆盖,所以不影响。以第二行第一列的flag_h2_key[0]为例,当其有效时(k5键被按下),其编码过程如下。由于16个按键在同一个时钟范围内,只会有一个按键有效,所以第一个if语句中的flag_h1_key[0]无效,编码被赋值为5'b11111,当执行到第5个if语句时,由于flag_h2_key[0]有效,编码被修改为5'd4。当下一个时钟来时,flag_h2_key[0]从有效变为无效,所以编码值不更新,仍然为第一个if语句的无效赋值5'b11111。这样就保证了key5按下一次,只输出一个时钟周期的键值编码5'd4。
8、本例中的矩阵键盘设计并没有采取延时消抖方式,但实际使用效果还不错。其原因是利用每行5ms的扫描时间,且获取按键在其时间中点进行,间接也取到了消抖的效果。
9、显示部分采用了向左移位的方式,即当前按下的键值只显示在最右边一位数码管上,其余的往左移一位。

四、实验步骤

FPGA开发的详细步骤请参见“基于EP4CE6F17C8的FPGA开发流程(以半加器为例)”一文,本例只对不同之处进行说明。

本例工程放在D:\EDA_FPGA\Exam_9文件夹下,工程名称为Exam_9。模块文件名称为key_show.v,并设置为顶层实体。其余步骤与“基于EP4CE6F17C8的FPGA开发流程”中的一样。

接下来看管脚约束,本例中6个数码管一共有14个引脚,矩阵键盘8个引脚,再加上时钟晶振和复位按钮,一共24个。具体的端口分配如下图所示。

对于未用到的引脚设置为三态输入方式,多用用途引脚全部做为普通I/O端口,电压设置为3.3-V LVTTL(与”基于EP4CE6F17C8的FPGA开发流程“中的一样)。需要注意,程序中的每个端口都必须为其分配管脚,如果系统中存在未分配的I/O,软件可能会进行随机分配,这将造成不可预料的后果,存在烧坏FPGA芯片的风险。

接下来对工程进行编译,编译完成后,可查看一下逻辑器件的消耗情况,如下图所示。可见消耗的逻辑器件要比“基于EP4CE6F17C8的FPGA矩阵键盘实例”中的多,因此并不推荐采用此方法,仅提供学习参考而已。

最后进行下载,并查看结果,结果可参看“基于EP4CE6F17C8的FPGA矩阵键盘实例”一文。

标签:count,seg,FPGA,矩阵,EP4CE6F17C8,键盘,key
From: https://www.cnblogs.com/fxzq/p/18150160

相关文章

  • m基于FPGA的多通道FIR滤波器verilog实现,包含testbench测试文件
    1.算法仿真效果VIVADO2019.2仿真结果如下:   系统RTL结构如下:   2.算法涉及理论知识概要       多通道FIR(FiniteImpulseResponse)滤波器是一种在数字信号处理中广泛应用的线性时不变滤波技术,尤其适用于多通道音频、视频、图像等多维数据的处理。   ......
  • 键盘控制2
    #include<iostream>#include<windows.h>#include<conio.h>//控制台输入输出头文件usingnamespacestd;intmain(){HANDLEhandle=GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出的句柄COORDcoord={0,2};//保存光标位置SetConsoleCursorPosition(handle,co......
  • vb.net from窗体接受键盘输入信息
    PublicClassForm1'当窗体初始化时,订阅键盘按下事件PrivateSubForm1_Load(senderAsObject,eAsEventArgs)HandlesMyBase.LoadAddHandlerMe.KeyDown,AddressOfForm1_KeyDownEndSub'键盘按下事件的处理程序PrivateSubForm1_K......
  • 基于键盘钩子实现扫码枪输入
    基于键盘钩子实现扫码枪输入dotNet工控上位机更多资料,请关注微信公众号:dotNet工控上位机​关注 3人赞同了该文章钩子钩子是操作系统消息处理的一种机制。通过钩子,应用程序可以安装一个钩子回调过程让系统调用,从而监视系统中的消息队列。在这些消息......
  • 键盘各按键的指令码
    -------------------------------------F1:0x1b0x4f0x50F2:0x1b0x4f0x51F3:0x1b0x4f0x52F4:0x1b0x4f0x53F5:0x1b0x5b0x310x350x7eF6:0x1b0x5b0x310x370x7eF7:0x1b0x5b0x310x380x7eF8:0x1b0x5b0x310x390x7eF9:0x1b0x5b0x320x300......
  • FPGA器件实现逻辑运算的基本原理是(   )。
    选项:A、采用最小项相加的电路形式实现逻辑运算B、采用与非门电路实现逻辑运算C、采用异或门电路实现逻辑运算D、采用查找表的方式实现逻辑运算答案:D解析:组成FPGA的两个最基本的部分是组合逻辑以及时序逻辑,分别实现这两个基本部分的结构就是FPGA的基本单元。组合逻辑......
  • 具有低功耗、小尺寸和高可靠性,LIFCL-40-9MG121I、LIFCL-40-8MG121I、LIFCL-40-7MG121I
    说明CrossLink-NXFPGA是首款采用Nexus技术平台设计的产品系列,为网络边缘开发工程师提供实现创新的嵌入式视觉解决方案所需的更低功耗、小尺寸和高可靠性。该系列采用低功耗28nmFD-SOI技术,具有小尺寸、高可靠性和出色的性能。该器件适合用于各种应用,包括嵌入式视觉。应用包......
  • FPGA入门笔记013——嵌入式块RAM使用之FIFO
    1、FIFO概述​ FIFO(FirstInFirstOut),即先进先出。FPGA或者ASIC中使用到的FIFO一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存或者高速异步数据的交互。它与普通存储器的区别是没有外部读写地址线,这样使用起来相对简单,但缺点就是只能顺序写入数据......
  • 基于直方图相似性的图像分类算法FPGA实现,包括tb测试文件和MATLAB辅助验证
    1.算法运行效果图预览MATLAB测试结果:    FPGA测试结果:   上述仿真图中,红色XX表示图像读取完毕。因此输出XX。当图像输出完成之后,最下面的相似性指标 same1输出为11226,same2输出为67584.即图1和图2相似性较强,图1和图3相似性较弱。 2.算法运行软件版本vi......
  • m基于FPGA的217卷积编码维特比译码verilog实现,包含testbench不使用IP核
    1.算法仿真效果Vivado2019.2   编码部分:   译码部分输出:   RTL图:   2.算法涉及理论知识概要2.1卷积编码       卷积编码是一种前向纠错编码方式,特别适用于无线通信和其他信道条件恶劣的应用场景。它主要通过卷积算子将信息序列映射成......