|
- `define fosc 50000000 //晶振频率
- `define scan 1000000 //矩阵键盘扫描频率
- module display4( //4位数码管模块
- input clk, //有源晶振输入
- input [15:0] hex, //数码管显示的16进制字符
- output [7:0] seg_code, //数码管段码 8位 A~DP
- output [3:0] bit_code //数码管位码 4位 1:千位 2:百位 4:十位 8:个位
- );
- function [7:0] display; //16进制数码管段码查询
- input [3:0] hex;
- begin
- case(hex)
- 4'h0:display = 8'h3F;
- 4'h1:display = 8'h06;
- 4'h2:display = 8'h5B;
- 4'h3:display = 8'h4F;
- 4'h4:display = 8'h66;
- 4'h5:display = 8'h6D;
- 4'h6:display = 8'h7D;
- 4'h7:display = 8'h07;
- 4'h8:display = 8'h7F;
- 4'h9:display = 8'h6F;
- 4'hA:display = 8'h77;
- 4'hB:display = 8'h7C;
- 4'hC:display = 8'h39;
- 4'hD:display = 8'h5E;
- 4'hE:display = 8'h79;
- 4'hF:display = 8'h71;
- endcase
- end
- endfunction
- integer i;
- reg [1:0] j;
- reg [7:0] k;
- reg [3:0] l;
- assign seg_code = k;
- assign bit_code = l;
- always @(posedge clk) begin
- i = i + 1;
- if(i == `fosc/1000) begin
- i = 0;
- j <= j + 1;
- /*
- 共阴或共阳 如果显示不正确
- 可将 seg_code 或 bit_code 前的 ~号去除
- 并检查A~DP的Pin是否设置颠倒
- */
- case(j)
- 0:k <= ~display(hex[15:12]);
- 1:k <= ~display(hex[11:8]);
- 2:k <= ~display(hex[7:4]);
- 3:k <= ~display(hex[3:0]);
- endcase
- l <= ~(1 << j);
- end
- end
- endmodule
- module keyboard4x4_ghost( //4x4矩阵键盘 鬼键处理模块
- input [15:0] key, //16位按键 按下1 松开0
- output ghost //按键组合是否发生鬼键 (按键冲突)
- );
- reg [3:0] i;
- reg [23:0] j;
- reg k;
- assign ghost = k;
- always @(*) begin
- i = 0;
- k = 0;
- repeat(16) begin
- case(i)
- 4'h0:j = 24'h12348C; //0的X方向有:1,2,3,Y方向有:4,8,C
- 4'h1:j = 24'h02359D; //0与X:(1或2或3) 与 Y:(4或8或C)
- 4'h2:j = 24'h0136AE; //以上3个按键同时按下即为鬼键,以此类推
- 4'h3:j = 24'h0127BF; //当按键0,3,C按下后,按键F的回路被导通
- 4'h4:j = 24'h56708C; //此表格严禁修改,否则会出错
- 4'h5:j = 24'h46719D;
- 4'h6:j = 24'h4572AE;
- 4'h7:j = 24'h4563BF;
- 4'h8:j = 24'h9AB04C;
- 4'h9:j = 24'h8AB15D;
- 4'hA:j = 24'h89B26E;
- 4'hB:j = 24'h89A37F;
- 4'hC:j = 24'hDEF048;
- 4'hD:j = 24'hCEF159;
- 4'hE:j = 24'hCDF26A;
- 4'hF:j = 24'hCDE37B;
- endcase
- k = k | (key[i] && (
- key[j[23:20]] |
- key[j[19:16]] |
- key[j[15:12]]
- ) && (
- key[j[11:08]] |
- key[j[07:04]] |
- key[j[03:00]]
- ));
- i = i + 1;
- end
- end
- endmodule
- module keyboard4x4( //4x4矩阵键盘模块
- input clk, //有源晶振输入
- input k0, //矩阵键盘第1脚
- input k1, //k0~k3必须配置为弱上拉
- input k2, //否则会受到干扰出错
- input k3,
- output k4, //k4~k7只允许输出0和高阻态
- output k5, //否则多按键同时按下可能会短路
- output k6,
- output k7, //第8脚
- output [15:0] key //16位对应16个按键 矩阵键盘按下哪些按键 按下置1 松开清0 发生鬼键全部置1 (已消抖)
- );
- wire [3:0] ki;
- assign ki[0] = k0;
- assign ki[1] = k1;
- assign ki[2] = k2;
- assign ki[3] = k3;
- reg [3:0] ko;
- assign k4 = ko[0] ? 1'bz : 1'b0;
- assign k5 = ko[1] ? 1'bz : 1'b0;
- assign k6 = ko[2] ? 1'bz : 1'b0;
- assign k7 = ko[3] ? 1'bz : 1'b0;
- reg [1:0] i;
- reg [1:0] j;
- integer k;
- reg [15:0] l;
- reg [15:0] m;
- integer n;
- reg [3:0] o;
- reg [15:0] p;
- reg [15:0] q;
- reg [15:0] r;
- reg [4:0] s [15:0];
- wire t;
- assign key = r;
- keyboard4x4_ghost keyboard4x4_ghost(
- .key(q),
- .ghost(t)
- );
- always @(posedge clk) begin //矩阵键盘按键扫描
- k = k + 1;
- if(k >= `fosc/`scan) begin
- k = 0;
- ko = ~(1 << i);
- i = i + 1;
- j = 0;
- repeat(4) begin
- if(!ki[j]) begin
- l[{i^1,~j}] = 1;
- end
- j = j + 1;
- end
- if(i == 0) begin
- m = l;
- l = 0;
- end
- end
- end
- always @(posedge clk) begin //矩阵键盘按键消抖 (去抖)
- n = n + 1;
- if(n >= `fosc/1000) begin
- n = 0;
- repeat(16) begin
- if(m[o]) begin
- if(!(&s[o])) begin
- s[o] = s[o] + 1;
- end
- end else begin
- s[o] = 0;
- end
- p[o] = &s[o];
- o = o + 1;
- if(o == 0) begin
- q = p;
- p = 0;
- r = t ? 16'hFFFF : q;
- end
- end
- end
- end
- endmodule
- /*
- 矩阵键盘按键与代码:
- 1 2 3 A | 0 1 2 3 | 0001 0002 0004 0008
- 4 5 6 B | 4 5 6 7 | 0010 0020 0040 0080
- 7 8 9 C | 8 9 A B | 0100 0200 0400 0800
- * 0 # D | C D E F | 1000 2000 4000 8000
- */
- module main(
- input clk, //有源晶振输入
- //接矩阵键盘
- input k0,
- input k1,
- input k2,
- input k3,
- output k4,
- output k5,
- output k6,
- output k7,
- //接数码管
- output [7:0] seg_code, //数码管段码 8位 A~DP
- output [3:0] bit_code //数码管位码 4位 1:千位 2:百位 4:十位 8:个位
- );
- wire [15:0] hex;
- wire [15:0] key;
- display4 display4(
- .clk(clk),
- .hex(hex),
- .seg_code(seg_code),
- .bit_code(bit_code)
- );
- keyboard4x4 keyboard4x4(
- .clk(clk),
- .k0(k0),
- .k1(k1),
- .k2(k2),
- .k3(k3),
- .k4(k4),
- .k5(k5),
- .k6(k6),
- .k7(k7),
- .key(key),
- );
- assign hex = key;
- endmodule
复制代码 |
|