矩阵键盘Verilog
矩阵键盘的verilog代码分享
矩阵键盘的verilog代码分享defineSCANmodulekey_scan(clk ,rst_n,key_col, //键盘列输入key_row, //键盘行输出key_num, //指示哪一个按键按下,用0~15指示key_vld//按下有效指示信号,其为1表示按下一次。
);parameter KEY_W = 4 ;parameter COL = 0 ;parameter ROW = 1 ;parameter DLY = 2 ;parameter FIN = 3 ;parameter COL_CNT= 16;parameter TIME_20MS= 1000000;//输入信号定义input clk ;input rst_n;input[3:0] key_col;//输出信号定义output key_vld;output[3:0] key_num;output[KEY_W-1:0] key_row;//输出信号reg定义reg [3:0] key_num;reg [KEY_W-1:0] key_row;reg key_vld;reg [ 3:0] key_col_ff0 ;reg [ 3:0] key_col_ff1 ;reg [ 1:0] key_col_get ;reg shake_flag ;reg shake_flag_ff0;reg [ 3:0] state_c ;reg [19:0] shake_cnt ;reg [ 3:0] state_n ;reg [ 1:0] row_index ;reg [15:0] row_cnt ;reg [ 2:0] x ;always@(posedge clk or negedge rst_n)begin if(rst_n==1b0)beginkey_col_ff0 = 4b1111;key_col_ff1 = 4b1111;endelse beginkey_col_ff0 = key_col ;key_col_ff1 = key_col_ff0;endendalways@(posedge clk or negedge rst_n)begin if(rst_n==1b0)beginshake_cnt = 0;endelse if(add_shake_cnt)beginif(end_shake_cnt)shake_cnt = 0;elseshake_cnt = shake_cnt + 1;endelse beginshake_cnt = 0;endassignadd_shake_cnt = key_col_ff1!=4hf shake_flag==0; assignend_shake_cnt = add_shake_cnt shake_cnt==TIME_20MS-1; always@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginshake_flag = 0;endelse if(end_shake_cnt) beginshake_flag = 1b1;endelse if(key_col_ff1==4hf) beginshake_flag = 1b0;endend`ifdef SCANalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginstate_c = COL;endelse beginstate_c = state_n;endendalways@(*)begincase(state_c)COL: beginif(col2row_start)beginstate_n = ROW;endelse beginstate_n = state_c;endROW: beginif(row2dly_start)beginstate_n = DLY;endelse beginstate_n = state_c;endendDLY :beginif(dly2fin_start)beginstate_n = FIN;endelse beginstate_n = state_c;endendFIN: beginif(fin2col_start)beginstate_n = COL;endelse beginstate_n = state_c;endenddefault: state_n = COL;endcaseendassigncol2row_start = state_c==COL end_shake_cnt; assignrow2dly_start = state_c==ROW end_row_index; assigndly2fin_start = state_c==DLY end_row_index; assignfin2col_start = state_c==FIN key_col_ff1==4hf; always@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_row = 4b0;endelse if(state_c==ROW)beginkey_row = ~(1b1 row_index);endelse beginkey_row = 4b0;endendalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginrow_cnt = 0;endelse if(add_row_cnt) beginif(end_row_cnt)row_cnt = 0;elserow_cnt = row_cnt + 1;endendassign add_row_cnt = state_c==ROW || state_c==DLY; assign end_row_cnt = add_row_cnt row_cnt==COL_CNT-1; always@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginrow_index = 0;endelse if(add_row_index) beginif(end_row_index)row_index = 0;elserow_index = row_index + 1;endassign add_row_index = end_row_cnt;assign end_row_index = add_row_index row_index==x-1; always@(*)beginif(state_c==ROW)x = 4;elsex = 1;endalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_col_get = 0;endelse if(col2row_start) beginif(key_col_ff1==4b1110)key_col_get = 0;else if(key_col_ff1==4b1101)key_col_get = 1;else if(key_col_ff1==4b1011)key_col_get = 2;elsekey_col_get = 3;endendalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_num = 0;endelse if(state_c==ROW end_row_cnt)beginkey_num = {row_index,key_col_get};endelse beginkey_num = 0;endalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_vld = 1b0;endelse if(state_c==ROW end_row_cnt key_col_ff1[key_col_get]==1b0)begin key_vld = 1b1;endelse beginkey_vld = 1b0;endend`elsealways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_vld = 0;endelse beginkey_vld = end_shake_cnt;endendalways@(*)beginkey_num = 0;end`endifendmodule。
矩阵键盘程序设计精简版
矩阵键盘程序设计矩阵键盘程序设计引言矩阵键盘的工作原理矩阵键盘由多行和多列组成,每个按键位于特定的行和列交叉点上。
在未按下任何按键时,所有的行和列都处于高电平状态。
当按下某个按键时,该按键所在的行和列会产生短接,从而导致相应的行和列变为低电平。
为了检测按键的输入,矩阵键盘通常采用矩阵扫描的方式。
具体来说,它通过依次将一行置为低电平,然后读取相应的列的状态来判断是否有按键按下。
为了提高检测的精度,还可以采用定时器中断的方式来不断扫描键盘状态。
矩阵键盘程序设计示例下面是一个简单的矩阵键盘程序设计示例,使用Arduino开发板和Keypad库来实现。
在该示例中,我们假设矩阵键盘由3行4列组成,使用数字1-9和星号()作为按键。
cppinclude <Keypad.h>const byte ROWS = 3; // 定义行数const byte COLS = 4; // 定义列数char keys[ROWS][COLS] = {{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'}};byte rowPins[ROWS] = {9, 8, 7}; // 设置行引脚byte colPins[COLS] = {6, 5, 4, 3}; // 设置列引脚Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);void setup() {Serial.begin(9600); // 初始化串口通信}void loop() {char key = keypad.getKey(); // 读取按键if (key != NO_KEY) { // 判断是否有按键按下Serial.println(key); // 打印按下的按键到串口}delay(100); // 延时等待}在上述示例中,我们定义了矩阵键盘的行数和列数,并指定了每个按键的字符表示。
【Easy CPLD570】Verilog实现4x4矩阵按键检测
Verilog实现4x4矩阵按键检测1 原理图4x4的矩阵按键,8个IO,检测原理是IO63、66、67、68作为输出信号,轮流赋值高电平,IO59、60、61、62作为输入信号,检测对应的按键按下。
比如,在IO68赋值高电平时,检测到IO59信号为高电平,则表示按键K1被按下。
拨码开关用于测试。
2 CPLD代码module key_array (clk_24m,reset_n,Hline, //输出4bit按键赋高电平信号。
Vline, //输入4bit按键检测信号。
ledline, //测试使用LED点灯信号switch //测试使用按键表现选择信号,因只有8个LED,而按键有16个,通过此信号来选择是表现K1-K8,还是K9-K16。
);input wire clk_24m;input wire reset_n;output wire [3:0] Hline;input wire [3:0] Vline;output reg [7:0] ledline;input wire switch;/****************************************************************************** 24M时钟分频,用于内部控制及计数等。
******************************************************************************/ reg [14:0] count_div1;wire condition_732; //732 Hz时钟信号。
always @ (posedge clk_24m or negedge reset_n)beginif(reset_n == 1'b0)count_div1 <= 15'h0000;elsecount_div1 <= count_div1 + 15'h0001;end/****************************************************************************** condition_732:732Hz时钟信号,高电平持续一个24MHz时钟周期,其余时间为低电平。
verilog矩阵键盘
二、矩阵键盘显示电路设计(显示键盘值的平方)矩阵键盘显示电路的设计一、实验目的1、了解普通4×4 键盘扫描的原理。
2、进一步加深七段码管显示过程的理解。
3、了解对输入/输出端口的定义方法。
二、实验原理实现键盘有两种方案:一是采用现有的一些芯片实现键盘扫描;再就是用软件实现键盘扫描。
作为一个嵌入系统设计人员,总是会关心产品成本。
目前有很多芯片可以用来实现键盘扫描,但是键盘扫描的软件实现方法有助于缩减一个系统的重复开发成本,且只需要很少的 CPU 开销。
嵌入式控制器的功能能强,可能充分利用这一资源,这里就介绍一下软键盘的实现方案。
图10-1 简单键盘电路通常在一个键盘中使用了一个瞬时接触开关,并且用如图 10-1 所示的简单电路,微处理器可以容易地检测到闭合。
当开关打开时,通过处理器的I/O 口的一个上拉电阻提供逻辑 1;当开关闭合时,处理器的/IO口的输入将被拉低得到逻辑 0。
可遗憾的是,开关并不完善,因为当它们被按下或者被释放时,并不能够产生一个明确的1或者0。
尽管触点可能看起来稳定而且很快地闭合,但与微处理器快速的运行速度相比,这种动作是比较慢的。
当触点闭合时,其弹起就像一个球。
弹起效果将产生如图10-2所示的好几个脉冲。
弹起的持续时间通常将维持在5ms∼30ms 之间。
如果需要多个键,则可以将每个开关连接到微处理器上它自己的输入端口。
然而,当开关的数目增加时,这种方法将很快使用完所有的输入端口。
图10-2 按键抖动键盘上阵列这些开关最有效的方法(当需要5个以上的键时)就形成了一个如图 10-3 所示的二维矩阵。
当行和列的数目一样多时,也就是方型的矩阵,将产生一个最优化的布列方式(I/O 端被连接的时候),一个瞬时接触开关(按钮)放置在每一行与线一列的交叉点。
矩阵所需的键的数目显然根据应用程序而不同。
每一行由一个输出端口的一位驱动,而每一列由一个电阻器上拉且供给输入端口一位。
图 10-3 矩阵键盘键盘扫描的实现过程如下:对于4×4键盘,通常连接为4行、4列,因此要识别按键,只需要知道是哪一行和哪一列即可,为了完成这一识别过程,我们的思想是,首先固定输出4行为高电平,然后输出4列为低电平,在读入输出的4行的值,通常高电平会被低电平拉低,如果读入的4 行均为高电平,那么肯定没有按键按下,否则,如果读入的4 行有一位为低电平,那么对应的该行肯定有一个按键按下,这样便可以获取到按键的行值。
EDA实验七 矩阵键盘与数码管显示测试
实验七4*4键盘数据读取及数据显示设计一、实验目的:1、了解数码管的工作原理;2、掌握4*4矩阵键盘和数码管显示的编程方法。
3、学会用于Verilog语言进行程序设计。
二、实验仪器设备1、PC机一台2、FPGA实验开发系统一套。
三、实验原理:本实验通过扫描4*4矩阵键盘的值,在数码管上显示对应按钮的编号数据。
矩阵键盘及数码管电路如下所示。
四、实验要求1、预习教材中的相关内容。
2、阅读并熟悉本次实验的内容。
3、完成实验内容。
五、实验步骤(1)启动 Quartus II 建立一个空白工程,选择的器件为 Altera 公司的 Cyclone 系列的 EP2C8Q240C8芯片,命名为 keyarray.qpf;(2)新建一个 Schematic File 文件,命名为 keyarray.bdf;(3)分别新建 3 个 Verilog HDL File 文件,分别命名为 seg_show.v、 divclk.v、keyarraycontrol.v。
输入程序代码并保存(对应源程序 8),然后进行综合编译。
若在编译过程中发现错误,则找出错误并更正错误,直至编译成功为止。
(4)从设计文件创建模块(File→Creat Update→Creat Symbol Files for Current File),seg_show.v 生成名为seg_show.bsf;divclk.v 生成名为divclk.bsf;keyarraycontrol.v 生成名为keyarraycontrol.bsf;(5)在 keyarray.bdf 文件中,在空白处双击鼠标左键,在 Symbol 对话框左上角的libraries 中,分别将 Project 下的 seg_show, divclk, keyarraycontrol 模块放在图形文件 keyarray.bdf 中,加入输入、输出引脚,双击每个引脚,进行引脚命名,并锁定管脚,将未使用的引脚设置为三态输入(一定要设置,否则可能会损坏芯片);完整的顶层模块原理图如图所示(6)将keyarray.bdf 设置为顶层实体。
verilog 矩阵键盘
/************************************************工程:4x4矩阵键盘日期:2011-08-3最后修改:功能:键盘说明:ROW【3:0】设为输入,COL【3:0】设为输出。
如果没有按键按下,则ROW【3:0】一直被上拉为高电平,且 COL【3:0】有低电平输出,ROW【3:0】中才有可能低电平输入。
*************************************************/ module keys(clk_50M,rst_n,row,col,dataout,smg_wei); /*************************************************/output [3:0]col; //矩阵键盘列input rst_n; //复位键input clk_50M; //系统时钟input [3:0]row; //矩阵键盘行output [7:0]dataout; //键盘值数码管显示数据output [7:0]smg_wei; //数码管显示使能reg [7:0]dataout;reg [3:0]col;reg [3:0]key_board_val;/*************************************************/ assign smg_wei=0; //八个数码管显示/*************************************************/ //分频部分开始/*************************************************/ reg[19:0]cnt; //计数子always @(posedge clk_50M or negedge rst_n)if(!rst_n)cnt<=0; elsecnt<=cnt+1'b1;wire key_clk=cnt[19];// 2^20/50M=21ms/*************************************************状态机部分独热码编码*************************************************/parameter NO_KEY_PRESSED=6'b000_001;//没有键按下parameter SCAN_COL0 =6'b000_010;//扫描第 0 列parameter SCAN_COL1 =6'b000_100;//扫描第 1 列parameter SCAN_COL2 =6'b001_000;//扫描第 2 列parameter SCAN_COL3 =6'b010_000;//扫描第 3 列parameter KEY_PRESSED =6'b100_000;//有键按下/*************************************************/ reg [5:0]current_state,next_state; //现态和次态/*************************************************///复位/*************************************************/always @(posedge key_clk or negedge rst_n)if(!rst_n)current_state<=NO_KEY_PRESSED;elsecurrent_state<=next_state;/*************************************************/always @ * //(current_state) //根据条件转移状态 case (current_state)NO_KEY_PRESSED: //没有键按下if(row!=4'hf)next_state=SCAN_COL0;elsenext_state=NO_KEY_PRESSED;SCAN_COL0: //扫描第 0 列 if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=SCAN_COL1;SCAN_COL1: //扫描第 1 列 if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=SCAN_COL2;SCAN_COL2: //扫描第 2 列 if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=SCAN_COL3;SCAN_COL3: //扫描第 3 列if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=NO_KEY_PRESSED;KEY_PRESSED: //有按键按下if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=NO_KEY_PRESSED;endcase/*************************************************/reg key_pressed_flag; //按键按下标志reg [3:0]col_val; //列值reg [3:0]row_val; //行值/*************************************************///根据次态,给相应的寄存器赋值/*************************************************/always @(posedge key_clk or negedge rst_n)if(!rst_n) //复位begincol<=4'h0;key_pressed_flag<=0;endelsecase (next_state)NO_KEY_PRESSED:begincol<=4'h0;key_pressed_flag<=0;endSCAN_COL0: //扫描第 0 列col<=4'b1110;SCAN_COL1: //扫描第 1 列col<=4'b1101;SCAN_COL2: //扫描第 2 列col<=4'b1011;SCAN_COL3: //扫描第 3 列col<=4'b0111;KEY_PRESSED: //有按键按下begincol_val<=col; // 锁存列值row_val<=row; // 锁存行值key_pressed_flag<=1;// 置键盘按下标endendcase/****************************************************************************** **/// 扫描行列值部分开始/****************************************************************************** **/always @(posedge key_clk or negedge rst_n)if(!rst_n)key_board_val<=4'h0;elseif(key_pressed_flag)case({col_val,row_val})8'b11101110 : key_board_val <= 4'h0; 8'b11101101 : key_board_val <= 4'h4; 8'b11101011 : key_board_val <= 4'h8; 8'b11100111 : key_board_val <= 4'hC;8'b11011110 : key_board_val <= 4'h1; 8'b11011101 : key_board_val <= 4'h5; 8'b11011011 : key_board_val <= 4'h9; 8'b11010111 : key_board_val <= 4'hD;8'b10111110 : key_board_val <= 4'h2; 8'b10111101 : key_board_val <= 4'h6; 8'b10111011 : key_board_val <= 4'hA; 8'b10110111 : key_board_val <= 4'hE;8'b01111110 : key_board_val <= 4'h3; 8'b01111101 : key_board_val <= 4'h7; 8'b01111011 : key_board_val <= 4'hB;8'b01110111 : key_board_val <= 4'hF;endcase/****************************************************************************** ***/// 键盘值转换为数码管显示/****************************************************************************** ***/always @ * //(key_board_val)begincase(key_board_val)4'h0:dataout<=8'b11000000; //04'h1: dataout<=8'b11111001; //14'h2:dataout<=8'b10100100; //24'h3:dataout<=8'b10110000; //3dataout<=8'b10011001; //4 4'h5:dataout<=8'b10010010; //5 4'h6:dataout<=8'b10000010; //6 4'h7:dataout<=8'b11111000; //7 4'h8:dataout<=8'b10000000; //8 4'h9:dataout<=8'b10010000; //9 4'hA:dataout<=8'b10001000; //a 4'hB:dataout<=8'b10000011; //b 4'hC:dataout<=8'b11000110; //c 4'hD:dataout<=8'b10100001; //d 4'hE:dataout<=8'b10000110; //edataout<=8'b10001110; //fendcaseend/****************************************************************************** ***/// 键盘值转换为数码管显示结束/****************************************************************************** ***/endmodule。
矩阵键盘
FPGA学习心得——矩阵键盘1、行列式键盘概述为了减少键盘与单片机接口时所占用I/O口线的数目,在键数较多时,通常都将键盘排列成行列矩阵式,行列式键盘又叫矩阵式键盘。
用带有I/O口的线组成行列结构,按键设置在行列的交点上。
例如用2*2的行列结构可以构成4个键的键盘,4*4的行列结构可以构成有16个键的键盘。
这样,当按键数量平方增长时,I/O口线只是线性增长,这样就可以节省I/O口线。
2、行列式键盘原理教研室已有薄膜矩阵键盘,其实物图如图所示。
其电路原理图如下图所示。
由行列式键盘的原理可以知道,要正确地完成按键输入工作必须有按键扫描电路产生keydrv3~keydrv0信号。
同时还必须有按键译码电路从keydrv3~keydrv0信号和keyin3~keyin0信号中译码出按键的键值。
此外,一般还需要一个按键发生标志信号用于和其他模块接口,通知其它模块键盘上有按键动作发生,并可以从键盘模块中读取按键键值。
由于各个模块需要的时钟频率是不一样的,因此时钟产生模块就是用于产生各个模块需要的时钟信号。
因此得到键盘接口电路的结构如图2所示。
图2 键盘接口电路结构图行列式键盘电路的FPGA实现主要解决三个问题,一是如何检测是否有按键按下并防止采集到干扰信号;二是在按键闭合时如何防止抖动;三是如何判断为哪一个按键位动作,并对其进行译码。
因此,为了解决这些问题,程序中使用不同的进程分别实现键盘扫描信号的产生、键盘去抖以及键盘的译码。
3、源程序[plain]view plaincopy1.----------------------------------------------------------------------------------2.-- Company:3.-- Engineer:4.--5.-- Create Date: 08:46:57 07/31/20126.-- Design Name:7.-- Module Name: MatrixKeyboard - Behavioral8.-- Project Name:9.-- Target Devices:10.-- Tool versions:11.-- Description:12.--13.-- Dependencies:14.--15.-- Revision:16.-- Revision 0.01 - File Created17.-- Additional Comments:18.--19.----------------------------------------------------------------------------------20.library IEEE;e IEEE.STD_LOGIC_1164.ALL;e IEEE.STD_LOGIC_ARITH.ALL;e IEEE.STD_LOGIC_UNSIGNED.ALL;24.25.---- Uncomment the following library declaration if instantiating26.---- any Xilinx primitives in this code.27.--library UNISIM;28.--use UNISIM.VComponents.all;29.30.entity MatrixKeyboard is31. Port ( Clk : in STD_LOGIC;32. Reset : in STD_LOGIC;33. KeyIn : in STD_LOGIC_VECTOR (3 downto 0);34. KeyScan : out STD_LOGIC_VECTOR (3 downto 0);35. LED : out STD_LOGIC_VECTOR (3 downto 0)36. );37.end MatrixKeyboard;38.39.architecture Behavioral of MatrixKeyboard is40.41.Signal Clk_scan : STD_LOGIC := '0';42.Signal Clk_5ms : STD_LOGIC := '0';43.Signal Clk_2ms : STD_LOGIC := '0';44.Signal Key_Scan : STD_LOGIC_VECTOR(3 downto 0);45.Signal Key_Decode : STD_LOGIC_VECTOR(7 downto 0);46.47.Type State_Key is(st_key1,st_key2,st_key3,st_key4);48.Signal Current_Key : State_Key := st_key1;49.50.Type State_Scan is(st_scan1,st_scan2,st_scan3,st_scan4);51.Signal Current_Scan : State_Scan := st_scan1;52.53.begin54.55. Proc_Clk_5ms : process(Clk)56. variable cnt_clk : integer range 0 to 250000 := 0;57. begin58. if(rising_edge(Clk)) then59. if(cnt_clk < 125000) then60. cnt_clk := cnt_clk + 1;61. Clk_scan <= '0';62. elsif(cnt_clk < 249999) then63. cnt_clk := cnt_clk + 1;64. Clk_scan <= '1';65. else66. cnt_clk := 0;67. end if;68. Clk_5ms <= Clk_scan;69. end if;70. end process Proc_Clk_5ms;71.72. Proc_Clk_2ms : process(Clk)73. variable cnt_clk : integer range 0 to 100000 := 0;74. begin75. if(rising_edge(Clk)) then76. if(cnt_clk < 50000) then77. cnt_clk := cnt_clk + 1;78. Clk_2ms <= '0';79. elsif(cnt_clk < 99999) then80. cnt_clk := cnt_clk + 1;81. Clk_2ms <= '1';82. else83. cnt_clk := 0;84. end if;85. end if;86. end process Proc_Clk_2ms;87.88.89. Proc_Scan:process(Clk_5ms)90. begin91. if(rising_edge(Clk_5ms)) then92. case Current_Scan is93. when st_scan1 =>94. Key_Scan <= "1110";95. Current_Scan <= st_scan2;96. when st_scan2 =>97. Key_Scan <= "1101";98. Current_Scan <= st_scan3;99. when st_scan3 =>100. Key_Scan <= "1011";101. Current_Scan <= st_scan4;102. when st_scan4 =>103. Key_Scan <= "0111";104. Current_Scan <= st_scan1;105. end case;106. end if;107.108. end process Proc_Scan;109.110. KeyScan <= Key_Scan;111. Key_Decode <= Key_Scan & Keyin;112.113. Proc_Keyboard:process(Clk_2ms,Reset)114. variable cnt_btn : integer range 0 to 50000 := 0;115. begin116. if(Reset = '1') then117. LED <= x"1";118. Current_Key <= st_key1;119. elsif(falling_edge(Clk_2ms)) then120. case Current_Key is121. when st_key1 => --Check whether any keys are p ressed122. if((Keyin and "1111") = "1111") then123. Current_Key <= st_key1;124. else125. Current_Key <= st_key2;126. end if;127. when st_key2 => --keys debouncing128. if((Keyin and "1111") = "1111") then129. Current_Key <= st_key1;130. else131. case Key_Decode is132. when "11101110" => LED <= "0001";133. when "11101101" => LED <= "0010";134. when "11101011" => LED <= "0011";135. when "11100111" => LED <= "1010";136. when "11011110" => LED <= "0100";137. when "11011101" => LED <= "0101";138. when "11011011" => LED <= "0110";139. when "11010111" => LED <= "1011";140. when "10111110" => LED <= "0111";141. when "10111101" => LED <= "1000";142. when "10111011" => LED <= "1001";143. when "10110111" => LED <= "1100";144. when "01111110" => LED <= "1110";145. when "01111101" => LED <= "0000";146. when "01111011" => LED <= "1111";147. when "01110111" => LED <= "1101";when others => null;148. end case;149. end if;150. Current_Key <= st_key3;151. when st_key3 => --Check whether the pressed keys a re released152. if((Keyin and "1111") /= "1111") then153. Current_Key <= st_key3;154. else155. Current_Key <= st_key4;156. end if;157. when st_key4 => --keys debouncing158. if((Keyin and "1111") /= "1111") then159. Current_Key <= st_key3;160. else161. LED <= x"0";162. Current_Key <= st_key1;163. end if;164. end case;165. end if;166. end process Proc_Keyboard;167.168.end Behavioral;169.薄膜键盘矩阵键盘4x4 ,单片机开发配件,机械手按键。
基于矩阵键盘的加法器并用数码管显示
基于矩阵键盘的加法器并用数码管显示一.任务解析用Verilog语言编写矩阵键盘驱动程序,实现“0~9,+,=”输入,数码管显示“加数”,按“+”键后再显示“被加数”,按“=”键后显示结果“和”。
二.实验方案键盘的识别有两种编程方法:方法一:module keyboard(clk,clr,keyv,C,L,k1);//输入行线[3:0]Linput clk,clr; //输出扫描列线[3:0]C;input [3:0]L; //输出键值[3:0]keyv。
output[3:0]C;output k1;output [3:0]keyv;reg [1:0]scan;reg [3:0]C;reg k1;always @(posedge clk or negedge clr)begin//clk大概1000HZif(!clr) scan=0;else beginscan=scan+2'h1;case(scan)2'H0:C=4'b1110;//列2'H1:C=4'b1101;2'H2:C=4'b1011;2'H3:C=4'b0111;endcaseendendreg [3:0]keyv;always @(negedge clk or negedge clr)beginif(!clr) begin keyv=0;k1=0;endelse begincase(L)4'HE:begin keyv={2'H0,scan};k1=1;end4'HD:begin keyv={2'H1,scan};k1=1;end4'HB:begin keyv={2'H2,scan};k1=1;end方法二:module key_recognize(clk,reset,row,col,key_value,key_flag);//50MHz clk,复位,行,列,键值input clk,reset;input [3:0]row;output [3:0]col;output [3:0]key_value;output key_flag;reg [3:0]col;reg [3:0]key_value;reg [5:0]count;//delay_20msreg [2:0]state;//状态标志reg key_flag;//按键标志位reg clk_500khz;//500KHZ时钟信号reg [3:0]col_reg;//寄存扫描列值reg [3:0]row_reg;//寄存扫描行值always @(posedge clk or negedge reset)if(!reset) begin clk_500khz<=0; count<=0; endelse beginif(count>=50) begin clk_500khz<=~clk_500khz;count<=0;endelse count<=count+1;endalways @(posedge clk_500khz or negedge reset)if(!reset) begin col<=4'b0000;state<=0;endelsebegincase (state)0:begin col[3:0]<=4'b0000;key_flag<=1'b0;if(row[3:0]!=4'b1111) begin state<=1;col[3:0]<=4'b1110;end //有键按下,扫描第一行else state<=0;end1:beginif(row[3:0]!=4'b1111) begin state<=5;end//判断是否是第一行else begin state<=2;col[3:0]<=4'b1101;end//扫描第二行end2:beginif(row[3:0]!=4'b1111) begin state<=5;end//判断是否是第二行else begin state<=3;col[3:0]<=4'b1011;end//扫描第三行end3:beginif(row[3:0]!=4'b1111) begin state<=5;end//判断是否是第三一行else begin state<=4;col[3:0]<=4'b0111;end//扫描第四行end4:beginif(row[3:0]!=4'b1111) begin state<=5;end//判断是否扫描第一行else state<=0;end5:beginif(row[3:0]!=4'b1111) begincol_reg<=col;row_reg<=row;//保存扫描列、行值state<=5;key_flag<=1'b1;//有键按下endelse begin state<=0;endendendcaseendalways @(clk_500khz or col_reg or row_reg)beginif(key_flag==1'b1)begincase({col_reg,row_reg})8'b1110_1110:key_value<=0;8'b1110_1101:key_value<=1;8'b1110_1011:key_value<=2;8'b1110_0111:key_value<=3;8'b1101_1110:key_value<=4;8'b1101_1101:key_value<=5;8'b1101_1011:key_value<=6;8'b1101_0111:key_value<=7;三.重难点解析原理框图:从上图及以上两种按键识别程序可以看出,必须设置一个按键标志位以获取有效按键。
4 4矩阵键盘(未消抖)verilog
4*4矩阵键盘(未消抖):module Matrix_keyboard(clk,in_s,out_s,num);//定义模块端口信息input clk;input [3:0] in_s;output [3:0] out_s;output [4:0] num;//定义输出信号类型及局部变量reg [4:0] num;reg [1:0] cnt = 0;reg [1:0] tmp = 0;reg [3:0] o_ut_st = 0;wire [7:0] dsample;//将扫描输出和输入信号级联,得到矩阵扫描结果assign dsample = {o_ut_st, in_s};assign out_s = o_ut_st;//产生按钮矩阵的列扫描信号always @(posedge clk)begincnt <= cnt + 1'b1;case (cnt)2'b00: o_ut_st <= 4'b1000;2'b01: o_ut_st <= 4'b0100;2'b10: o_ut_st <= 4'b0010;2'b11: o_ut_st <= 4'b0001;endcaseend//根据按钮的列扫描信号和行输入信号判断按钮是否被按下always @(posedge clk)begin//如果无按钮按下,定义num=16为无效状态if (in_s == 4'b0000)beginif (tmp == 3)beginnum <= 16; //无按键输入,输出16tmp <= 0;endelsebeginnum <= num;tmp <= tmp + 1'b1; //扫描周期,3个时钟周期endendelsebegintmp <= 0;case (dsample)//第1列扫描结果8'b1000_0001: num <= 0;8'b1000_0010: num <= 1;8'b1000_0100: num <= 2;8'b1000_1000: num <= 3;//第2列扫描结果8'b0100_0001: num <= 4;8'b0100_0010: num <= 5;8'b0100_0100: num <= 6;8'b0100_1000: num <= 7;//第3列扫描结果8'b0010_0001: num <= 8;8'b0010_0010: num <= 9;8'b0010_0100: num <= 10;8'b0010_1000: num <= 11;//第4列扫描结果8'b0001_0001: num <= 12;8'b0001_0010: num <= 13;8'b0001_0100: num <= 14;8'b0001_1000: num <= 15;endcaseendendendmodule独立按键消抖程序:module Btn_without_shake(Clk_50MHz,PB_UP,PB_Out,count_sel); //定义模块端口信息input Clk_50MHz; //模块时钟50MHzinput PB_UP; //按钮输入output PB_Out; //去抖后按钮输出output [1:0] count_sel; //计数器输出//定义输出信号类型及局部变量reg [19:0] count_high = 0; //按钮输入高电平计数器reg [19:0] count_low = 0; //按钮输入低电平计数器reg PB_reg = 0;reg [1:0] count_sel_reg = 0;//输出赋值assign PB_Out = PB_reg;assign count_sel = count_sel_reg;//对输入进行采样,计数always @(posedge Clk_50MHz)if(PB_UP == 1'b0)count_low <= count_low + 1'b1;elsecount_low <= 20'h0_0000;always @(posedge Clk_50MHz)if(PB_UP == 1'b1)count_high <= count_high + 1'b1;elsecount_high <= 20'h0_0000;//防抖输出always @(posedge Clk_50MHz)if(count_high == 20'h7_FFFF) //判断高电平信号是否符合输出条件10msPB_reg <= 1'b1; //如果符合条件,则防抖输出高电平elseif(count_low == 20'h7_FFFF) //判断低电平信号是否符合输出条件10msPB_reg <= 1'b0; //如果符合条件,则防抖输出低电平elsePB_reg <= PB_reg;//使用去抖输出PB_reg控制count_sel计数always @(posedge PB_reg)count_sel_reg <= count_sel_reg + 1'b1;endmodule初学,参考书上的《Verilog HDL程序设计与实践》,准备用状态机做一下矩阵键盘,恩,坛子里也有,不过还是自己尝试一下,坛里老牛很多呀!。
矩阵键盘工作原理
矩阵键盘工作原理
矩阵键盘是一种现代的键盘技术,它是一种利用矩阵形式实现的复杂电路技术。
矩阵键盘的工作原理是,当按下某个按键时,将按键所在行和列的信号连接起来,并通过控制器来识别按键的位置,从而实现对按键的控制。
矩阵键盘的电路原理是,它将每行的按键之间连接在一起,每列的按键之间连接在一起,当按下某个按键时,将按键所在行和列的信号连接起来,这样,控制器就可以识别到按键的位置。
由于每行和每列的按键都是相互独立的,因此按键的控制是非常精确的。
矩阵键盘的优点是,它可以有效减少键盘的接口数量,减少电路板上的接口,提高键盘的密度,提高按键的可靠性,并且可以实现多功能按键。
它的缺点是,键盘的故障率较高,如果键盘中的某个按键出现故障,整个键盘都会受到影响。
总之,矩阵键盘是一种先进的键盘技术,它的工作原理是将每行的按键之间连接在一起,每列的按键之间连接在一起,通过控制器识别按键的位置,从而实现对按键的控制。
它具有节省接口、提高可靠性的优点,但是由于故障率较高,它的使用也存在一定的风险。
eda 实验《matrix keypad controller》简要心得
eda 实验《matrix keypad controller》简要心得1. 引言1.1 概述本篇长文旨在总结和分享我在进行EDA实验《matrix keypad controller》中的经验和心得。
该实验主要涉及矩阵键盘控制器的设计与实现,通过对材料、方法、设计方案以及实验步骤进行详细讲解,展示了从理论到实践的全过程。
1.2 文章结构本文将按照以下结构来展开:- 引言部分介绍了文章的背景和目的;- 接下来的部分将回顾实验过程,包括材料与方法、设计方案以及实验步骤的说明;- 随后是结果与分析部分,其中包括数据收集与处理、功能测试结果以及故障分析与解决方案;- 心得体会与反思部分引用个人观察和反思,对实验中遇到的问题、取得的成功之处以及改进空间进行讨论;- 最后是结论部分对整个实验进行总结,并给出进一步学习此主题所需参考文献。
1.3 目的本文旨在分享我在EDA实验《matrix keypad controller》中所获得的知识和技能,并提供一个有价值且清晰易懂的指南,帮助读者更好地理解和应用矩阵键盘控制器的设计与实现。
通过对实验过程、结果分析以及心得体会的详细描述,读者可以深入了解该实验的具体步骤和原理,并从中汲取经验,提升自己在EDA 领域的能力和技术水平。
2. 实验过程:2.1 材料与方法:在本次实验中,我们使用了以下材料和方法来完成Matrix Keypad Controller 的设计与实现。
首先,我们准备了一个4x4矩阵按键阵列,并将其连接到Arduino 开发板上。
接下来,我们选择了合适的导线来连接按键阵列和Arduino板的数字引脚。
我们还需要一台电脑或笔记本电脑来编写代码,并通过串行通信监视器进行结果的输出。
2.2 设计方案:在开始实验之前,我们需要确定Matrix Keypad Controller的设计方案。
我们决定使用Arduino作为主控制器,并利用其数字引脚实现对矩阵按键阵列的读取和解析。
verilog_矩阵键盘
资料范本本资料为word版本,可以直接编辑和打印,感谢您的下载verilog_矩阵键盘地点:__________________时间:__________________说明:本资料适用于约定双方经过谈判,协商而共同承认,共同遵守的责任与义务,仅供参考,文档可直接下载或修改,不需要的部分可直接删除,使用时请详细阅读内容二、矩阵键盘显示电路设计(显示键盘值的平方)矩阵键盘显示电路的设计一、实验目的1、了解普通4×4 键盘扫描的原理。
2、进一步加深七段码管显示过程的理解。
3、了解对输入/输出端口的定义方法。
二、实验原理实现键盘有两种方案:一是采用现有的一些芯片实现键盘扫描;再就是用软件实现键盘扫描。
作为一个嵌入系统设计人员,总是会关心产品成本。
目前有很多芯片可以用来实现键盘扫描,但是键盘扫描的软件实现方法有助于缩减一个系统的重复开发成本,且只需要很少的 CPU 开销。
嵌入式控制器的功能能强,可能充分利用这一资源,这里就介绍一下软键盘的实现方案。
图 10-1 简单键盘电路通常在一个键盘中使用了一个瞬时接触开关,并且用如图 10-1 所示的简单电路,微处理器可以容易地检测到闭合。
当开关打开时,通过处理器的 I/O 口的一个上拉电阻提供逻辑 1;当开关闭合时,处理器的/IO口的输入将被拉低得到逻辑 0。
可遗憾的是,开关并不完善,因为当它们被按下或者被释放时,并不能够产生一个明确的 1或者 0。
尽管触点可能看起来稳定而且很快地闭合,但与微处理器快速的运行速度相比,这种动作是比较慢的。
当触点闭合时,其弹起就像一个球。
弹起效果将产生如图 10-2所示的好几个脉冲。
弹起的持续时间通常将维持在 5ms∼30ms 之间。
如果需要多个键,则可以将每个开关连接到微处理器上它自己的输入端口。
然而,当开关的数目增加时,这种方法将很快使用完所有的输入端口。
图 10-2 按键抖动键盘上阵列这些开关最有效的方法(当需要5个以上的键时)就形成了一个如图 10-3 所示的二维矩阵。
4 4 矩阵键盘工作原理
4 4 矩阵键盘工作原理
矩阵键盘是一种常见的输入设备,它由一组按键组成,通常是一个矩形阵列。
每个按键都有一个标识符,例如数字、字母或符号,用户可以通过按下相应的按键来输入字符或执行特定的功能。
矩阵键盘使用一种称为矩阵扫描的技术来工作。
矩阵键盘的基本原理是将键盘的每个按键连接到一个二维的电路矩阵中。
该矩阵由行和列组成,行与列的交叉点即为一个按键的位置。
当用户按下一个按键时,键盘的控制电路会检测到按键位置的行和列,然后发送一个对应的信号给计算机。
具体来说,当用户按下一个按键时,键盘的控制电路会扫描矩阵中的行和列,并确定按键的位置。
然后,它将该位置的信息转换为一个数字或字符编码,并将其发送给计算机。
计算机接收到编码后,会根据编码对应的字符表或映射关系,将编码转换为对应的字符或执行相应的功能操作。
为了提高扫描效率,矩阵键盘通常采用多路复用的方式来工作。
具体来说,它会将多个按键连接到同一行或列上,然后通过逐行或逐列扫描的方式来检测按键的状态。
这种方式可以有效减少所需的输入输出引脚数量,从而降低成本并提高性能。
除了普通的按键输入,矩阵键盘还可以支持一些特殊功能,例如功能键、组合键等。
通过按下不同的组合键或功能键,用户可以实现更多的操作,例如调整音量、切换屏幕、执行快捷命令等。
总的来说,矩阵键盘通过矩阵扫描的方式来检测按键的位置和状态,并将其信息转换为数字或字符编码。
这种简单而高效的工作原理使得矩阵键盘成为广泛使用的输入设备。
单片机矩阵键盘
按键在闭合和断开时,触点会存在抖动现象:
数码管前三位显示一个跑表,从000到999之间以1%秒速度运行,当按下一个独立键盘时跑表停止,松开手后跑表继续运行。(用定时器设计表)。
在上题的基础上,用另外三个独立键盘实现按下第一个时计时停止,按下第二个时计时开始,按下第三个是计数值清零从头开始。
键盘处理程序就作这么一个简单的介绍,实际上,键盘、显示处理是很复杂的,它往往占到一个应用程序的大部份代码,可见其重要性,但说到,这种复杂并不来自于单片机的本身,而是来自于操作者的习惯等等问题,因此,在编写键盘处理程序之前,最好先把它从逻辑上理清,然后用适当的算法表示出来,最后再去写代码,这样,才能快速有效地写好代码
ANL A,#0FH
CJNE A,#0FH,KCODE;
MOV A,R1
SETB C RLC A JC NEXT2 NEXT3: MOV R0,#00H RET KCODE: MOV B,#0FBH NEXT4: RRC A INC B JC NEXT4 MOV A,R1 SWAP A NEXT5: RRC A INC B INC B INC B INC B 。
按下16个矩阵键盘依次在数码管上显示1-16的平方。如按下第一个显示1,第二个显示4...
识别方法
04
03
01
02
3、若有键被按下,应识别出是哪一个键闭合。方法是对键盘的行线进行扫描。P1.4-P1.7按下述4种组合依次输出: P1.7 1 1 1 0 P1.6 1 1 0 1 P1.5 1 0 1 1 P1.4 0 1 1 1 在每组行输出时读取P1.0-P1.3,若全为“1”,则表示为“0”这一行没有键闭合,否则有键闭合。由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值 4、为了保证键每闭合一次CPU仅作一次处理,必须去除键释放时的抖动。
矩阵键盘及其电路设计
矩阵键盘及其电路设计
矩阵键盘是一种常见的输入设备,常用于计算机、电视机、手机等电
子产品中。
它由多个按键组成,每个按键都与一个矩阵电路相连。
矩阵键
盘的设计简单、成本低廉,因此在许多场景中广泛应用。
矩阵键盘的电路设计可以分为两个主要方面:行扫描电路和列扫描电路。
行扫描电路负责控制行通道。
它由多个行扫描引脚组成,每一个引脚
都与一个行通道相连。
通常情况下,行扫描电路会以一定的频率依次将每
一个引脚置高电平,然后检测列通道是否有相应的信号。
如果检测到信号,就说明用户按下了对应的按键。
通过依次扫描所有的行通道,可以获取用
户整个键盘的按键状态。
列扫描电路负责控制列通道。
它由多个列扫描引脚组成,每一个引脚
都与一个列通道相连。
当行扫描电路扫描到其中一行时,列扫描电路会检
测到该行通道与列通道之间的电位差。
如果电位差存在,则说明用户按下
了该行和列交叉点处的按键。
在实际的电路设计中,还可以使用连接电阻和电容的方式来降低电路
的噪声。
通过在矩阵键盘中添加适当的抗干扰电路,可以有效减少外界干
扰对键盘输入的影响。
总结起来,矩阵键盘的电路设计主要包括行扫描电路和列扫描电路。
通过行列通道的扫描和检测,可以判断用户所按下的按键。
在实际的设计中,还可以添加抗干扰电路来提高键盘的输入稳定性。
矩阵键盘的设计简
单且成本低廉,因此被广泛应用于各种电子产品中。
基于verilog键盘数码管设计ppt课件
基于verilog语言键盘与数码管制作
2010年11月13日
主要内容:
1.基于verilog语言数码管扫描 程序
2.基于verilog语言矩阵键盘扫描 程序
共阴:1点亮 共阳:0点亮
外形结构
共阴极
共阳极
共阴:1点亮 共阳:0点亮
f
a gb
e d
c
dp
4
动态显示:是指无论在任何时刻只有一个数码管处于显 示状态,每个数码管轮流显示。
STATE_C
col[3:0]=4'b1101
STATE_D
col[3:0]=4'b1011
STATE_E
col[3:0]=4'b0111
STATE_F
实现功能 跳转条件
判读当前是 否有键按下 row[3:0] !=4'b1111
判断按键是 row[3:0] ==4'b1111 否在第一行
row[3:0] !=4'b1111
.
矩阵扫描式键盘硬件电路结构
Vcc
01 23 P1.0 4 5 6 7 P1.1 8 9 A B P1.2 C D E F P1.3
P1.4P1.5P1.6 P1.7
.
读读
读读读
读读读读读 N Y
读 读 10ms
读读读
读读读读读 N Y
读读读读
读读
矩阵式键盘识别按键的步骤: 1.读端口,将端口状态与设 定状态对比,判断状态是否 有变化 2.如有变化,软件延时 消按 键的抖动! 无则返回 3.再次执行第一步的操作 4.如有键按下 则读取数据进 行数据分析!若无则返回! 5.返回分析行列扫描线的信 息的结果!
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
module key
(
clk, //50MHZ
reset,
row, //行
col, //列
key_value //键值
);
input clk,reset;
input [3:0] row;
output [3:0] col;
output [3:0] key_value;
reg [3:0] col;
reg [3:0] key_value;
reg [5:0] count;//delay_20ms
reg [2:0] state; //状态标志
reg key_flag; //按键标志位
reg clk_500khz; //500KHZ时钟信号
reg [3:0] col_reg; //寄存扫描列值
reg [3:0] row_reg; //寄存扫描行值
always @(posedge clk or negedge reset)
if(!reset) begin clk_500khz<=0; count<=0; end
else
begin
if(count>=50) begin clk_500khz<=~clk_500khz;count<=0;end
else count<=count+1;
end
always @(posedge clk_500khz or negedge reset)
if(!reset) begin col<=4'b0000;state<=0;end
else
begin
case (state)
0:
begin
col[3:0]<=4'b0000;
key_flag<=1'b0;
if(row[3:0]!=4'b1111) begin state<=1;col[3:0]<=4'b1110;end //有键按下,扫描第一行
else state<=0;
end
1:
begin
if(row[3:0]!=4'b1111) begin state<=5;end //判断是否是第一行
else begin state<=2;col[3:0]<=4'b1101;end //扫描第二行end
2:
begin
if(row[3:0]!=4'b1111) begin state<=5;end //判断是否是第二行
else begin state<=3;col[3:0]<=4'b1011;end //扫描第三行
end
3:
begin
if(row[3:0]!=4'b1111) begin state<=5;end //判断是否是第三一行
else begin state<=4;col[3:0]<=4'b0111;end //扫描第四行
end
4:
begin
if(row[3:0]!=4'b1111) begin state<=5;end //判断是否是第一行
else state<=0;
end
5:
begin
if(row[3:0]!=4'b1111)
begin
col_reg<=col; //保存扫描列值
row_reg<=row; //保存扫描行值
state<=5;
key_flag<=1'b1; //有键按下
end
else
begin state<=0;end
end
endcase
end
always @(clk_500khz or col_reg or row_reg)
begin
if(key_flag==1'b1)
begin
case ({col_reg,row_reg})
8'b1110_1110:key_value<=0;
8'b1110_1101:key_value<=1;
8'b1110_1011:key_value<=2;
8'b1110_0111:key_value<=3;
8'b1101_1110:key_value<=4;
8'b1101_1101:key_value<=5;
8'b1101_1011:key_value<=6;
8'b1101_0111:key_value<=7;
8'b1011_1110:key_value<=8;
8'b1011_1101:key_value<=9;
8'b1011_1011:key_value<=10;
8'b1011_0111:key_value<=11;
8'b0111_1110:key_value<=12;
8'b0111_1101:key_value<=13;
8'b0111_1011:key_value<=14;
8'b0111_0111:key_value<=15;
endcase
end
end
endmodule。