vhdl 4x4键盘扫描程序

合集下载

【例7-3】4x4键盘的VHDl扫描程序[2页]

【例7-3】4x4键盘的VHDl扫描程序[2页]

【例7-3】4X4键盘的VHDL扫描程序library ieee;use ieee.std_logic_1164.all;entity kbscan isport( clk :in std_logic;Kin :in std_logic_vector(3 downto 0);kout :out std_logic_vector(3 downto 0);result :out integer range 0 to 16);end kbscan;architecture bev of kbscan issignal scans :std_logic_vector(7 downto 0);signal scan: std_logic_vector(3 downto 0);signal I : integer range 0 to3;beginscans<=kin & scan;kout<=scan;process(clk) --进程,产生扫描信号beginif (clk'event and clk='1') thenif(i=3) theni<=0;else i<=i+1;end if;case i iswhen 0=> scan<=”1000”;when 1=> scan<=” 0100”;when 2=> scan<=” 0010”;when 3=> scan<=” 0001”;end case;end if;end process;process(clk) --进程,根据信号译码beginif (clk'event and clk='1') thenif(kin=”0000”) thenresult<=16;elsecase scans iswhen “00011000”=>result<=0;when “00101000”=>result<=1;when “01001000”=>r esult<=2;when “10001000”=>result<=3;when “00010100”=>result<=4;when “00100100”=>result<=5;when “01000100”=>result<=6;when “10000100”=>result<=7;when “00010010”=>result<=8;when “00100010”=>result<=9;when “01000010”=>result<=10;when “10000010”=>resu lt<=11;when “00010001”=>result<=12;when “00100001”=>result<=13;when “01000001”=>result<=14;when “10000001”=>result<=15;when others =>result<=16;end case;end if;end if ;end process;end bev;。

实验07:4X4键盘阵列扫描输入.pdf

实验07:4X4键盘阵列扫描输入.pdf

键盘阵列扫描输入一、实验目的1. 进一步学习并掌握Quartus II设计的方法及步骤;2. 熟悉VHDL语言电路设计方法;3. 熟悉EACF型FPGA开发板,参见6.1节;4. 学习并掌握利用VHDL描述并设计电路的方法及步骤;5. 学习并掌握键盘阵列的扫描输入的方法及实现过程。

二、实验原理键盘阵列是一个由4×4的按键开关组成的阵列,可实现16种状态的输入。

4×4按键阵列的硬件连接原理如下图所示。

4X4键盘阵列其中VCC3.3为3.3V的正电源;BUTTON为4×4共16个按键,R为电阻。

而K_H_1、K_H_2、K_H_3、K_H_4为4×4按键阵列连接到FPGA通用IO引脚的行信号;K_V_1、K_V_2、K_V_3、K_V_4为4×4按键阵列连接到FPGA通用IO引脚的列信号,如下图所示。

键盘阵列与FPGA的连接另外,连接到FPGA的行列信号圴为3.3V的LVTTL电平标准:即电压小于0.8V为低电平,高于2.0V为高电平。

通过上述4×4按键阵列的硬件连接原理图可看出,行和列信号都通过10K的电阻上拉到3.3V的电源,也就是说如果FPGA通过对应的IO引脚来读取4×4按键阵列的行和列信号,得到的全部为高电平“1”,即使按键按下时,读到的依然是高电平“1”。

那么如何在FPGA中判断4×4按键阵列中的哪个键按下呢?当然我们要实现按键输入的功能,就不能全部读取行和列的信号。

而应通过不断地输出扫描行(或列),再通过读取列(或行)的信号来判断哪个按键按下。

即:通过对4×4键盘阵列的4个行(或列)控制信号循环输出”1110、1101、1011、0111”,来驱动键盘阵列,紧接着读取相应的4个列(或行)信号。

通过读取的数据或状态来判断16个按键中哪个键被按下,并对其状态做编码输出。

此电路不停的工作,以便实时准确地获取键盘的输入状态,以供其它电路使用,从而实现了键盘阵列的扫描输入。

4X4键盘扫描程序

4X4键盘扫描程序

4X4键盘扫描程序,采用查表方式,适用于AVR单片机。

此处为4X4键盘软件部分,硬件部分设计请参照:4X4键盘扫描电路分析。

此程序对应的键盘电路为:键盘状态扫描函数/*键盘扫描函数读取当前键盘的状态有按键按下返回相应按键值无按键按下返回"0x00"*/unsigned char key_read(void){unsigned char i;DDRA = 0x00;/*获取列地址*/PORTA = 0x0F;DDRA = 0xF0;此处应加入几uS延时;i = PINA;DDRA = 0x00;/*获取行地址*/PORTA = 0xF0;DDRA = 0x0F;此处应加入几uS延时;i |= PINA;DDRA = 0x00;/*输出复位*/PORTA = 0xFF;switch (i) {/*将按键码转换成键值*/ case 0x00: return 0x00;case 0xEE: return '1';case 0xDE: return '2';case 0xBE: return '3';case 0x7E: return 'A';case 0xED: return '4';case 0xDD: return '5';case 0xBD: return '6';case 0x7D: return 'B';case 0xEB: return '7';case 0xDB: return '8';case 0xBB: return '9';case 0x7B: return 'C';case 0xE7: return '*';case 0xD7: return '0';case 0xB7: return '#';case 0x77: return 'D';default : return 0x00;}}键盘读取函数/*按键获取函数获取按键信号,其中包含有状态记录及按键去颤抖。

AVR单片机扫描4X4矩阵键盘并数码管显示程序

AVR单片机扫描4X4矩阵键盘并数码管显示程序

AVR单片机扫描4X4矩阵键盘并数码管显示程序/*programname : keyboard ; 功能描述: 扫描16 个按键(4X4),并把键值显示在数码管上(两位); 要点: 在扫描按键时运用了比较复杂的两个for()循环嵌套式扫描方案,大大减少了程序量,循环嵌套方案让我纠结了好久,键值有0~9,上,下,左,右,确认,清零; 体会: 又一个里程碑,泪奔啊...我似乎成了代码男神啊...;实验用时: 约等于14 小时(每天2 小时X7 天);完成时间: 2013-11-19 23:58:22*/#include #include#define uint8 unsigned char //宏定义8 位数据类型;#define uint16 unsigned int // 宏定义16 位数据类型;// 0 , 1 , 2 , 3 , 4 , 5 , 6 ,uint8 ak[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, // 7 , 8 , 9 , 上, 下左, 右; 0x07,0x7f,0x6f,0x62 ,0x54,0x21,0x0c};uint8 ge=8,shi=8 ,si=0;void bit(uint8 h) //数码管位选使能函数;{ PORTB|=0X02; //数码管位选置1(透明状态); if(h==0) {PORTB&=0XFD; //清零(锁存状态);}}void dat(uint8 u) //数码管数据使能函数;{ PORTB|=0X01; if(u==0) { PORTB&=0XFE; }}void buzz(uint8 k) //蜂鸣器函数;{ if(k==0) {PORTC&=~(0X80);} else PORTC|=0X80;}void delay(uint8 j) //1=1000 个计数周期;{ uint16 h=0; while(j--) {for(h=0;hvoid mega16() //初始化各个IO 口;{DDRA=0XFF; //PA 输出; DDRB=0XFF; //PB 输出; PORTA=0X00; //PA 输出全0; delay(1); //延时一下,1000 个计数周期; bit(0); //数码管共阴极全零;。

【Easy CPLD570】Verilog实现4x4矩阵按键检测

【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时钟周期,其余时间为低电平。

4X4键盘扫描实验

4X4键盘扫描实验

44键盘扫描实验实验目的1、学习HDL程序的基本设计技巧;2、掌握矩阵键盘的扫描原理和使用方法。

Verilog程序:module hex_keypad(Col,Code,show,show1,count,scan,clock,Row); output[3:0] Code,Col,count; //定义列信号Col、行列信号共同决定的输出代码Code、以及计数变量count output[7:0] show,show1; //定义七段显示变量show、show1 input[3:0] Row; //定义输入行信号Rowinput scan; //定义数码管选择信号scaninput clock; //定义时钟信号clockreg[3:0] Col,Code,count; //将输出信号定义为reg型reg[7:0] show,show1;reg[1:0] cn; //定义reg型变量cn,用于计数reg reset,count_up,count_down; //定义变量reset用于计数清零,count_up开始加计数,count_down开始减计数reg[15:0] times1,times2; //定义变量times1、times2用于决定开始计数的时间assign scan=1'b1; //将数码管选择信号赋值为1always@(posedge clock) //产生列信号if(cn==4)cn<=0; elsecn<=cn+1;always@(cn)case(cn)2'b00:Col=4'b1110;2'b01:Col=4'b1101;2'b10:Col=4'b1011;2'b11:Col=4'b0111;endcasealways@(posedge clock) //行列信号共同决定输出代码Code case({Row,Col})8'b1110_1110:Code=4'h0;8'b1110_1101:Code=4'h1;8'b1110_1011:Code=4'h2;8'b1110_0111:Code=4'h3;8'b1101_1110:Code=4'h4;8'b1101_1101:Code=4'h5;8'b1101_1011:Code=4'h6;8'b1101_0111:Code=4'h7;8'b1011_1110:Code=4'h8;8'b1011_1101:Code=4'h9;8'b1011_1011:Code=4'hA;8'b1011_0111:Code=4'hB;8'b0111_1110:Code=4'hC;8'b0111_1101:Code=4'hD;8'b0111_1011:Code=4'hE;8'b0111_0111:Code=4'hF;endcasealways@(posedge clock) //由输出Code决定数码管的显示,七段用十六进制数表示case(Code[3:0])4'h0:show=8'hFC;4'h1:show=8'h60;4'h2:show=8'hDA;4'h3:show=8'hF2;4'h4:show=8'h66;4'h5:show=8'hB6;4'h6:show=8'h3E;4'h7:show=8'hE0;4'h8:show=8'hFE;4'h9:show=8'hE6;4'hA:show=8'hEE;4'hB:show=8'hCE;4'hC:show=8'h9C;4'hD:show=8'h7A;4'hE:show=8'h9E;4'hF:show=8'h8E;endcasealways@(posedge clock) //加减计数case(Code)4'h0:begin reset=1;count_up=0;count_down=0;end //按0键时清零4'hE:begin count_up=1;count_down=0;end //按E键加计数4'hF:begin count_down=1;count_up=0;end //按F键减计数default: begin count_down=0;count_up=0;reset=0; end //按其它键不计数endcasealways@(posedge clock)if(times1==1000) times1<=101; else if (count_up) times1<=times1+1;always@(posedge clock)if(times2==1000) times2<=101; else if (count_down) times2<=times2+1; always@(posedge clock)if(reset)count<=4'h0; elseif (times1>100&&Code==4'hE) //加计数begincount<=count+4'b1;if (count==4'h9) count<=4'h0;endelseif (times2>100&&Code==4'hF) //减计数begincount<=count-4'b1;if (count==4'h0) count<=4'h9;endalways@(posedge clock) //计数显示case(count[3:0])4'h0:show1=8'hFC;4'h1:show1=8'h60;4'h2:show1=8'hDA;4'h3:show1=8'hF2;4'h4:show1=8'h66;4'h5:show1=8'hB6;4'h6:show1=8'h3E;4'h7:show1=8'hE0;4'h8:show1=8'hFE;4'h9:show1=8'hE6;endcaseendmodule仿真波形:Col、Row、Code、show、show[17..10]为十六进制显示,times1、times2、count为十进制显示当Code为F(即按F键)时,show显示8E即F,表明此时按下的是F 键。

4×4矩阵键盘扫描

4×4矩阵键盘扫描

矩阵键盘(Verilog)module matrixKeyboard_drive(input i_clk,input i_rst_n,input [3:0] row, // 矩阵键盘行output reg [3:0] col, // 矩阵键盘列output reg [3:0] keyboard_val // 键盘值);//++++++++++++++++++++++++++++++++++++++// 分频部分开始//++++++++++++++++++++++++++++++++++++++reg [19:0] cnt; // 计数子always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)cnt <= 0;elsecnt <= cnt + 1'b1;wire key_clk = cnt[19]; // (2^20/50M = 21)ms //--------------------------------------// 分频部分结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 状态机部分开始//++++++++++++++++++++++++++++++++++++++// 状态数较少,独热码编码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, negedge i_rst_n)if (!i_rst_n)current_state <= NO_KEY_PRESSED;elsecurrent_state <= next_state;// 根据条件转移状态always @ *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;endcasereg key_pressed_flag; // 键盘按下标志reg [3:0] col_val, row_val; // 列值、行值// 根据次态,给相应寄存器赋值always @ (posedge key_clk, negedge i_rst_n)if (!i_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, negedge i_rst_n)if (!i_rst_n)keyboard_val <= 4'h0;elseif (key_pressed_flag)case ({col_val, row_val})8'b1110_1110 : keyboard_val <= 4'h0;8'b1110_1101 : keyboard_val <= 4'h4;8'b1110_1011 : keyboard_val <= 4'h8;8'b1110_0111 : keyboard_val <= 4'hC;8'b1101_1110 : keyboard_val <= 4'h1;8'b1101_1101 : keyboard_val <= 4'h5;8'b1101_1011 : keyboard_val <= 4'h9;8'b1101_0111 : keyboard_val <= 4'hD;8'b1011_1110 : keyboard_val <= 4'h2;8'b1011_1101 : keyboard_val <= 4'h6;8'b1011_1011 : keyboard_val <= 4'hA;8'b1011_0111 : keyboard_val <= 4'hE;8'b0111_1110 : keyboard_val <= 4'h3;8'b0111_1101 : keyboard_val <= 4'h7;8'b0111_1011 : keyboard_val <= 4'hB;8'b0111_0111 : keyboard_val <= 4'hF;endcase//--------------------------------------// 扫描行列值部分结束//--------------------------------------endmodule。

4×4键盘扫描程序

4×4键盘扫描程序

键盘程序假设P2.0-P2.3为H0-H3,P2.4-P2.7为L0-L3 (列) L0 L1 L2 L3(行) H0 0 1 2 3H1 4 5 6 7H2 8 9 A BH3 C D E F首先,行为P2口的低四位,而列为高四位。

P0口为数码管输出口。

第一种思路就是逐行逐列判断法。

#include<reg51.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charuchar code table[17] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};//八段数码管对应0-F值. uchar temp;void Delay_1ms(uint i)//1ms延时{uint x, j;for(j=0;j<i;j++)for(x=0;x<=148;x++);}void delay()//消除按键抖动延时{int i,j;for(i=0; i<=10; i++)for(j=0; j<=2; j++);}uchar Keyscan(void){uchar i,j,row,col;temp=P2&0xf0;for(i=0; i<4; i++){if(!(temp&(0x10<<i)))row=i;}P2=0x0f;temp=P2&0x0f;for(j=0; j<4; j++){if(!(temp&(0x01<<j)))col=j;}return (row+col*4);}void Main(void){uchar Key_Value=16; //读出的键值uchar i=0;while(1){P2 = 0xf0;temp=P2;if(temp != 0xf0){Delay_1ms(80); //按键消抖if(temp != 0xf0){Key_Value = Keyscan();}Delay_1ms(350); //按键消抖}P0 = table[Key_Value];//P0口输出数据到数码管}次读取结果组合起来就可以得到当前按键的特征编码。

数字系统设计大作业--4×4阵列键盘键信号检测电路设计

数字系统设计大作业--4×4阵列键盘键信号检测电路设计

2014 ~ 2015学年第1 学期《数字系统设计》大作业题目:4×4阵列键盘键信号检测电路设计专业:电子信息工程班级:姓名:指导教师:电气工程学院2015 年12月摘要人类文明已进入到高度发达的信息化社会。

信息化社会的发展离不开电子信息产品开发技术、产品品质的提高和进步。

电子信息产品随着科学技术的进步,其电子器件和设计方法更新换代的速度日新月异。

实现这种进步的主要原因就是电子设计技术和电子制造技术的发展,其核心就是电子设计自动化(EDA,Electronic Design Automation)技术,EDA技术的发展和推广应用又极大地推动了电子信息产业的发展。

为保证电子系统设计的速度和质量,适应“第一时间推出产品”的设计要求,EDA技术正逐渐成为不可缺少的一项先进技术和重要工具。

目前,在国内电子技术教学和产业界的技术推广中已形成“EDA热”,完全可以说,掌握EDA技术是电子信息类专业学生、工程技术人员所必备的基本能力和技能。

本设计主要利用VHDL硬件描述语言在EDA平台xilinx.ise.7.1i上设计一个4×4阵列键盘扫描电路,将行扫描信号输入阵列键盘,读取列信号的值,输出按键编码,从而判断出按键按下的位置。

并且使用Modelsim软件进行模拟仿真,下载到EDA实验箱进行硬件验证。

关键词:EDA VHDL语言 4×4阵列键盘扫描目录《数字系统设计》 (1)数字系统设计.............................................................................. 错误!未定义书签。

摘要 (2)关键词:EDA VHDL语言 4×4阵列键盘扫描 (2)1、实验目的 (4)2、实验要求 (4)3、实验原理 (4)4、总体框图 (5)4.1.1方案一 (5)4.1.2方案二 (5)4.2设计思路 (6)5、功能模块介绍 (8)5.1键盘消抖模块 (8)5.2键盘模块 (8)5.3VHDL部分程序 (8)6、实验结果 (10)6.1综合电路图 (10)6.2时序仿真 (11)1、实验目的(1)通过常见基本组合逻辑电路的设计,熟悉EDA设计流程;(2)熟悉文本输入及仿真步骤;(3)掌握VHDL设计实体的基本结构及文字规则;(4)理解硬件描述语言和具体电路的映射关系;(5)用VHDL设计一个能识别4×4阵列键盘的实用电路。

4×4键盘扫描时序逻辑电路的VHDL模型实验

4×4键盘扫描时序逻辑电路的VHDL模型实验

汕头大学实验报告实验三4×4键盘扫描时序逻辑电路的VHDL模型实验一、实验目的1、了解普通4×4键盘扫描的原理。

2、掌握组合逻辑电路和时序逻辑电路的混和设计。

3、进一步加深七段码管显示过程的理解。

二、硬件要求1、4×4键盘阵列。

2、FPGA主芯片。

3、可变时钟源。

4、七段码显示区。

5、LED显示模块。

三、实验原理本实验主要完成的实验是完成4×4键盘扫描的,然后获取其键值,并对其进行编码,从而进行按键的识别,并将相应的按键值进行显示。

键盘扫描的实现过程如下:对于4×4键盘,通常连接为4行、4列,因此要识别按键,只需要知道是哪一行和哪一列即可,为了完成这一识别过程,我们的思想是,首先固定输出4行为高电平,然后输出4列为低电平,在读入输出的4行的值,通常高电平会被低电平拉低,如果读入的4行均为高电平,那么肯定没有按键按下,否则,如果读入的4行有一位为低电平,那么对应的该行肯定有一个按键按下,这样便可以获取到按键的行值。

同理,获取列值也是如此,先输出4列为高电平,然后在输出4行为低电平,再读入列值,如果其中有哪一位为低电平,那么肯定对应的那一列有按键按下。

获取到行值和列值以后,组合成一个8位的数据,根据实现不同的编码在对每个按键进行匹配,找到键值后在7段码管和LED显示。

四、实验内容及步骤本实验内容是完成4×4键盘的扫描,然后将正确的键值进行显示,实验步骤如下:1、编写键盘扫描和显示的VHDL代码。

2、用MaxPlusII对其进行编译仿真。

3、在仿真确定无误后,选择芯片ACEX1K EP1K30QC208。

4、给芯片进行管脚绑定,在此进行编译。

5、根据自己绑定的管脚,在实验箱上对键盘接口、显示接口和FPGA之间进行正确连线。

6、给目标板下载代码,在4×4键盘输入键值,观看实验结果。

五、VHDL程序设计代码及结果1、4×4键盘扫描源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY Vhdl1 ISPORT(CLK_1K : IN STD_LOGIC; --时钟输入1KHZCLK_40K : IN STD_LOGIC; --40K TimeClkKEY_LIE : IN STD_LOGIC_VECTOR(3 DOWNTO 0);-- 列输入START :OUT STD_LOGIC; --二-十进制数据输出标志KEY_HANG :OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --行输出DA TA_P : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--二-十进制数输出DISP_DA TA : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);--数码管显示译码输出DISP_SEL : OUT STD_LOGIC_VECTOR(1 downto 0));--数码管显示扫描输出END ;ARCHITECTURE RTL OF Vhdl1 ISSIGNAL INT : STD_LOGIC; --列与非信号SIGNAL CLK_SEL : STD_LOGIC;--键值控制1khz的时钟信号SIGNAL START_REG:STD_LOGIC; --数据输出标志信号SIGNAL DISP_SEL_REG:STD_LOGIC_VECTOR(1 DOWNTO 0);--数码管显示扫描信号SIGNAL DATA_L,DATA_H:STD_LOGIC_VECTOR(3 DOWNTO 0);--二-十进制低位、高位信号SIGNAL DATA_TMP:STD_LOGIC_VECTOR(3 DOWNTO 0);--二-十进制低位高位暂存信号SIGNAL KEY_HANG_TMP:STD_LOGIC_VECTOR(3 DOWNTO 0);--行输出信号SIGNAL DISP_DA TA_REG:STD_LOGIC_VECTOR(3 DOWNTO 0); --二-十进制低位、高位暂存信号(数码管用)SIGNAL KEY_CODE:STD_LOGIC_VECTOR(7 DOWNTO 0);--行列相并信号SIGNAL DATA_P_REG:STD_LOGIC_VECTOR(7 DOWNTO 0); --二-十进制数信号-------------------------------------------------------------------------------BEGINKEY_CODE<=KEY_HANG_TMP&KEY_LIE;--行、列相并DATA_P<=DATA_P_REG;START<= START_REG;KEY_HANG<=KEY_HANG_TMP;DISP_SEL<=DISP_SEL_REG;CLK_SEL<=CLK_1K AND ( NOT INT);--无键按下时有CLK-SEL时钟信号输出--------------------------------------------------PROCESS (CLK_SEL,CLK_40K , INT)V ARIABLE STA TE : INTEGER RANGE 0 TO 3 ;BEGINIF RISING_EDGE(CLK_40K) THEN --一个40K的脉冲上升沿到来输入一次列状态以判断是否有按键按下INT<= NOT (KEY_LIE(3) AND KEY_LIE(2) AND KEY_LIE(1) AND KEY_LIE(0));END IF;IF RISING_EDGE(CLK_SEL) THEN --一个1K的脉冲的上升沿到来输出一个带表行的状态CASE STATE IS--变量表示状态机,4循环WHEN 0=>KEY_HANG_TMP<="1110";STA TE :=1;WHEN 1 =>KEY_HANG_TMP<="1101";STATE :=2 ;WHEN 2 =>KEY_HANG_TMP<="1011";STATE :=3;WHEN 3 =>KEY_HANG_TMP<="0111";STATE :=0;END CASE;END IF;END PROCESS;PROCESS (CLK_40K , INT)--进程是并行的V ARIABLE STA TE :INTEGER RANGE 0 TO 3;V ARIABLE COUNTER : INTEGER RANGE 0 TO 31;BEGINIF INT='0' THENSTATE:=0;COUNTER:=0;ELSIF RISING_EDGE(CLK_40K) THENCASE STATE ISWHEN 0 =>DATA_TMP <= DATA_L;--低四位放入暂存信号内STATE:=1;WHEN 1 =>--再嵌套一个CASE语句CASE KEY_CODE IS--实现把像并数据译码十六进制的1到FWHEN "01110111" =>DA TA_L <="0001";--把1放入低四位DA TA_H <=DA TA_TMP;--把暂存信号的内容放入高四位,相相当于向左移位STA TE:=2;--跳出内嵌套CASE语句,转向外CASE语句的状态2 WHEN "01111011" =>DA TA_L <="0010";DA TA_H <=DATA_TMP;STATE:=2;WHEN "01111101" =>DA TA_L <="0011";DA TA_H <=DATA_TMP;STATE:=2;WHEN "01111110" =>DA TA_L <="0100";DA TA_H <=DATA_TMP;STATE:=2;WHEN "10110111" =>DA TA_L <="0101";DA TA_H <=DATA_TMP;STATE:=2;WHEN "10111011" =>DA TA_L <="0110";DA TA_H <=DATA_TMP;STATE:=2;WHEN "10111101" =>DA TA_L <="0111";DA TA_H <=DATA_TMP;STATE:=2;WHEN "10111110" =>DA TA_L <="1000";DA TA_H <=DATA_TMP;STATE:=2;WHEN "11010111" =>--9键DA TA_L <="1001";DA TA_H <=DATA_TMP;STATE:=2;WHEN "11011011" =>--0键DA TA_L <="0000";DA TA_H <=DATA_TMP;STATE:=2;WHEN "11011101" =>--A键,实现步进加一功能IF DA TA_H ="1001" THENIF DA TA_L="1001" THENDATA_H<="1001";DATA_L<="1001";ELSE DA TA_L<=DATA_L + 1;END IF;ELSIF DA TA_L="1001" THENDATA_L<="0000";DATA_H<=DATA_H+1;ELSEDATA_L<=DATA_L+1;DATA_H<=DATA_H;END IF;STATE:=2;WHEN "11011110" =>--B键,实现步键加十IF DA TA_H="1001" THENDA TA_H<="1001";ELSEDATA_L<=DATA_L;DATA_H<= DATA_H+1;END IF;STATE:=2;WHEN "11100111" =>--C键,实现步进减一IF DA TA_L="0000" AND DATA_H="0000" THENDATA_L<="0000";DATA_H<="0000";ELSIF DA TA_L="0000" THENDA TA_L<="1001";DA TA_H<= DATA_H-1;ELSEDATA_L <=DATA_L-1;DATA_H<=DATA_H;END IF;STA TE:=2;WHEN "11101011"=>--D键,实现步进减十IF DA TA_H="0000" THENDA TA_H<="0000";ELSEDATA_L<=DATA_L;DATA_H<=DATA_H-1;END IF;STATE:=2;WHEN "11101110" =>--E键,实现送数功能DA TA_L<=DATA_L;DA TA_H<=DATA_H;DATA_P_REG<=DATA_H&DATA_L;START_REG<='1';--数据输出标志信号置一STATE:=2;WHEN"11101101" =>--F键,实现清零功能DA TA_L<="0000";DA TA_H<="0000";STATE:=2;WHEN OTHERS =>--不可缺少STATE:=2;END CASE;WHEN 2 =>--状态2实现去抖动功能IF COUNTER=31 THEN --计数延时去抖COUNTER:=0;STA TE:=3;ELSECOUNTER:=COUNTER+1;STATE:=2;END IF;WHEN 3 =>-- 清除数据输出标志START_REG<='0';STA TE:=3;END CASE;END IF;END PROCESS;PROCESS (CLK_1K,DA TA_L,DATA_H)--数码管循环显示V ARIABLE STA TE: INTEGER RANGE 0 TO 1;BEGINIF RISING_EDGE(CLK_1K) THENCASE STATE ISWHEN 0 =>DISP_SEL_REG<="10";-- 输入10到数码管显示扫描信号DISP_DA TA_REG<=DATA_L;--二-十进制低高位暂存节点STATE:=1;WHEN 1 =>DISP_SEL_REG<="01";DISP_DA TA_REG<=DATA_H;STATE:=0;END CASE;END IF;END PROCESS;PROCESS(CLK_1K,DISP_DA TA_REG)--数码管译码BEGINIF RISING_EDGE(CLK_1K) THENCASE DISP_DA TA_REG ISWHEN "0000"=>DISP_DA TA<="1111110";--0WHEN "0001"=>DISP_DA TA<="0110000";--1WHEN "0010"=>DISP_DA TA<="1101101";WHEN "0011"=>DISP_DA TA<="1111001";WHEN "0100"=>DISP_DA TA<="0110011";WHEN "0101"=>DISP_DA TA<="1011011";WHEN "0110"=>DISP_DA TA<="1011111";WHEN "0111"=>DISP_DA TA<="1110000";WHEN "1000"=>DISP_DA TA<="1111111";WHEN "1001"=>DISP_DA TA<="1111011";WHEN OTHERS =>DISP_DA TA<="0000000";END CASE;END IF;END PROCESS;END;2、实验现象(1)38译码器六、思考题1、总结FPGA是如何识别按键的?与单片机读取键值有何不同?答:FPGA的所有I/O控制块允许每个I/O引脚单独配置为输入口,不过这种配置是系统自动完成的。

4x4键盘的程序有扫描法与线反法

4x4键盘的程序有扫描法与线反法

4x4键盘的程序有扫描法与线反法,但我个人认为用线反法较好,用扫描法得依次扫描所有行或列,如果用线反法就简单多了。

先使键盘的行置为低、列置为高(或列置为高、行置为低),接着读回端口的值。

比如:如果使用P0为键盘接口就先使低四位为低、高四位为高即P0=0xf0然后就读回P0口的值赋给一个变量,a=P0;紧接就给行列赋相反的值行置为高、列置为低(或列置为低、行置为高)即P0=0x0f然后就读回再与a运算就能得到唯一的识别码下面的程序就是用线反写一个4x4键盘识别程序:#include<AT89X52.H>#include<delay.h>#define KEY_SCAN P1#define uchar unsigned char//char num;/********************************//*函数名称:KEY_DOWN() *//*函数功能:延时子函数 *//*参数:无 *//*返回:返回1或0 *//*备注:1表示有键按下,0则无*//********************************/bit KEY_DOWN(){KEY_SCAN=0x0f; //先给键盘口赋个初值if(KEY_SCAN!=0x0f) //判断是有按键按下,即KEY_SCAN不等于初值时有键按下{delayms(10); //消抖if(KEY_SCAN!=0x0f) //再次判断是否真有键按下return 1; //真有就返回1没有返回零elsereturn 0;}elsereturn 0;}/********************************//*函数名称:SCAN_GET() *//*函数功能:键盘值函数 *//*参数:无 *//*返回:返回1或0 *//*备注:无 *//********************************/uchar SCAN_GET(){char button;uchar key_code;button=KEY_SCAN;KEY_SCAN=0xf0;button=(button|KEY_SCAN);while(KEY_SCAN!=0xf0);delayms(10);switch(button){case 0xd7: key_code='1';break;case 0xdb: key_code='2';break;case 0xdd: key_code='3';break;case 0xb7: key_code='4';break;case 0xbb: key_code='5';break;case 0xbd: key_code='6';break;case 0x77: key_code='7';break;case 0x7b: key_code='8';break;case 0x7d: key_code='9';break;case 0xeb: key_code='0';break;case 0xee: key_code=0xee;break;default : break;}return key_code;}////////////////////////////////////////////////////////////// //此程序是上两个程序结合的/********************************//*函数名称:Key_Get() *//*函数功能:键盘扫描函数 *//*参数:无 *//*返回:无 *//*备注:无 *//********************************/void Key_Get(){char button;KEY_SCAN=0x0f;if(KEY_SCAN!=0x0f){delayms(5);if(KEY_SCAN!=0x0f)button=KEY_SCAN;KEY_SCAN=0xf0;button=(button|KEY_SCAN);while(KEY_SCAN!=0xf0);switch(button){case 0xd7: num='1';P0=0x00;break; case 0xdb: num='2';P0=0x0f;break; case 0xdd: num='3';break;case 0xb7: num='4';break;case 0xbb: num='5';break;case 0xbd: num='6';break;case 0x77: num='7';break;case 0x7b: num='8';break;case 0x7d: num='9';break;case 0xeb: num='0';break;case 0xe7: num='a';break;case 0xed: num='b';break;case 0xee: num='c';break;case 0xde: num='d';break;case 0xbe: num='e';break;case 0x7e: num='f';break;default : break;}}}}qinglei120713的分享分享矩阵键盘C51程序(4*4)(来自互联网) 1111111111111111111111111111111111111111111111 11111111111111111111111111111111111111#include <reg51.h>#include <intrins.h>#define key_port P0 //键盘接口定义sbit key_port_0=key_port^0;sbit key_port_1=key_port^1;sbit key_port_2=key_port^2;sbit key_port_3=key_port^3;/*******************************STC89C59 单片机一毫秒延时函数*******************************/void delay_ms(unsigned int ms){unsigned int i,j;for( i=0;i<ms;i++)for(j=0;j<332;j++); //1947是STC89C58在22.1184MHz晶振下,通过软件仿真反复实验得到的数值}/**************************串口发送一个字符**************************/void com_send_dat( unsigned char dat){SBUF=dat;while (TI== 0);TI= 0 ;}/**************************串口初始化**************************/void init_com( void ){SCON=0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr //UART为模式1,8位数据,允许接收TMOD|=0x20 ; //TMOD: timer 1, mode 2, 8-bit reload //定时器1为模式2,8位自动重装TH1=0xfa ; //Baud:19200 fosc="22.1184MHzTL1=0xfa;PCON|=0x80; //SMOD=1;波特率加倍;ES=1; //Enable Serial InterruptTR1 = 1 ; // timer 1 run}/**************************键盘扫描函数**************************/unsigned char keyscan(void){unsigned char key,i;unsigned char co de key_table[16]={0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,0xbe,0xbd,0x bb,0xb7,0x7e,0x7d,0x7b,0x77};key_port=0x0f; //确定行列位置if(key_port==0x0f)return(0);//无键按下返回0delay_ms(10); //调用延时函数,目的是去前沿键抖。

4x4键盘(任意同时按键按下有效)扫程序-数码管显示键值

4x4键盘(任意同时按键按下有效)扫程序-数码管显示键值
case 16:if(col3==0) key=15;n=1;break;
}
}
void main()
{
unsigned char i, key_key[16];
while(1)
{
for(i=0;i<16;i++)
{
key_4x4();
duan_xuan();_xuan();
}
}
for(i=x;i>0;--i)
for(j=114;j>0;--j);
}
void duan_xuan()
{
wr=0; //时钟输入端WR置低电平
cs1=0;//cs1为低电平选通段码锁存IC
wr=1; //时钟输入端WR置高电平,WR得到上升沿
cs1=1;//cs1为高电平,段码锁存IC锁存输出保持不变
case 4:if(col3==0) key=3;n=5;break;
case 5:row1=0;row0=1;if(col0==0) key=4;n=6;break;
case 6:if(col1==0) key=5;n=7;break;
case 7:if(col2==0) key=6;n=8;break;
{
static unsigned char n=1;
// P2=0XFF;
switch(n)
{
case 1:row0=0;row3=1;if(col0==0) key=0;n=2;break;
case 2:if(col1==0) key=1;n=3;break;
case 3:if(col2==0) key=2;n=4;break;

4_4键盘VHDL程序

4_4键盘VHDL程序

elsif clkfrq'event and clkfrq = '1' then
if cntscn = "11" then
cntscn <= "00";
else
cntscn <= cntscn+1;
when "11" => scnlin <= "1110";
when others => null;
end case;
end if;
end process;
signal cntscn : std_logic_vector(1 downto 0);
signal scnlin : std_logic_vector(3 downto 0);
signal cntfrq : integer range 30000 downto 0;
when "01111110" =>leds <= "1100";
when "10111110" =>leds <= "1101";
when "11011110" =>leds <= "1110";
--signal cntfrq : std_logic_vector(3 downto 0); --仿真时用的
signal lednum : std_logic_vector(7 downto 0);
begin
process(rst,clk, clkfrq) -- 晶振为50MHz,进行25000分频产生扫描时钟(1000Hz)

数字系统设计大作业--4×4阵列键盘键信号检测电路设计

数字系统设计大作业--4×4阵列键盘键信号检测电路设计

2014 ~ 2015学年第1 学期《数字系统设计》大作业题目:4×4阵列键盘键信号检测电路设计专业:电子信息工程班级:姓名:指导教师:电气工程学院2015 年12月摘要人类文明已进入到高度发达的信息化社会。

信息化社会的发展离不开电子信息产品开发技术、产品品质的提高和进步。

电子信息产品随着科学技术的进步,其电子器件和设计方法更新换代的速度日新月异。

实现这种进步的主要原因就是电子设计技术和电子制造技术的发展,其核心就是电子设计自动化(EDA,Electronic Design Automation)技术,EDA技术的发展和推广应用又极大地推动了电子信息产业的发展。

为保证电子系统设计的速度和质量,适应“第一时间推出产品”的设计要求,EDA技术正逐渐成为不可缺少的一项先进技术和重要工具。

目前,在国内电子技术教学和产业界的技术推广中已形成“EDA热”,完全可以说,掌握EDA技术是电子信息类专业学生、工程技术人员所必备的基本能力和技能。

本设计主要利用VHDL硬件描述语言在EDA平台xilinx.ise.7.1i上设计一个4×4阵列键盘扫描电路,将行扫描信号输入阵列键盘,读取列信号的值,输出按键编码,从而判断出按键按下的位置。

并且使用Modelsim软件进行模拟仿真,下载到EDA实验箱进行硬件验证。

关键词:EDA VHDL语言 4×4阵列键盘扫描目录《数字系统设计》 (1)数字系统设计.............................................................................. 错误!未定义书签。

摘要 (2)关键词:EDA VHDL语言 4×4阵列键盘扫描 (2)1、实验目的 (4)2、实验要求 (4)3、实验原理 (4)4、总体框图 (5)4.1.1方案一 (5)4.1.2方案二 (5)4.2设计思路 (6)5、功能模块介绍 (8)5.1键盘消抖模块 (8)5.2键盘模块 (8)5.3VHDL部分程序 (8)6、实验结果 (10)6.1综合电路图 (10)6.2时序仿真 (11)1、实验目的(1)通过常见基本组合逻辑电路的设计,熟悉EDA设计流程;(2)熟悉文本输入及仿真步骤;(3)掌握VHDL设计实体的基本结构及文字规则;(4)理解硬件描述语言和具体电路的映射关系;(5)用VHDL设计一个能识别4×4阵列键盘的实用电路。

4×4键盘扫描程序开启原理及实例(精心整理)

4×4键盘扫描程序开启原理及实例(精心整理)

4×4键盘扫描程序开启原理及实例(精心整理)单片机4*4键盘扫描程序时如何开启的?按照行顺序,一行一行的开启,如下图:4*4共16键,假设P0.0-P0.3为H0-H3,P0.4-P0.7为L0-L3(列) L0 L1 L2 L3(行) H0 0 1 2 3H1 4 5 6 7H2 8 9 A BH3 C D E F首先让H0 = 0,然后依次检测L0-L3,看那个键按下了,则对应的L0-L3为0,这样第一行检测结束。

比如扫描H0行时第一个键按下了,则L0=0,获得的P0=0xee,你也可以返回一个值,比如就是0,来代表第一个键(0)被按下,这样依次检测就扫描满16个键就行了。

4*4键盘扫描程序#include //包含头文件#define uchar unsigned char#define uint unsigned intunsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};//0-Fuchar keyscan(void);void delay(uint i);void main(){uchar key;P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符while(1){key=keyscan();//调用键盘扫描,switch(key){case 0x7e:P0=dofly[0];break;//0 按下相应的键显示相对应的码值case 0x7d:P0=dofly[1];break;//1case 0x7b:P0=dofly[2];break;//2case 0x77:P0=dofly[3];break;//3case 0xbe:P0=dofly[4];break;//4case 0xbd:P0=dofly[5];break;//5case 0xbb:P0=dofly[6];break;//6case 0xb7:P0=dofly[7];break;//7case 0xde:P0=dofly[8];break;//8case 0xdd:P0=dofly[9];break;//9case 0xdb:P0=dofly[10];break;//acase 0xd7:P0=dofly[11];break;//bcase 0xee:P0=dofly[12];break;//ccase 0xed:P0=dofly[13];break;//dcase 0xeb:P0=dofly[14];break;//ecase 0xe7:P0=dofly[15];break;//f}}}uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖if(cord_h!=0x0f){cord_h=P3&0x0f; //读入列线值P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}void delay(uint i)//延时函数{while(i--);}以下为详细解释:假设按下的是S1键进行如下检测(4*4键盘)先在P3口输出p3 00001111低四位行会有变化cord_h =00001111&00001110 =00001110if !=00001111延时0.1uscord_h=00001110&00001111=00001110if !=00001111P3再输出11111110P3 =00001110|11110000=11111110输出高四位cord_l=P3&0xf0 //此时P3口就是输入值01111110 而不是上面的11111110cord_l=01111110&11110000=01110000cord_h+cord_l=00001110+01110000=01111110=0x7e //此编码即为S1的编码#include //包含头文件#define uchar unsigned char#define uint unsigned intunsigned char const table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};//0-Fuchar keyscan(void);void delay(uint i);void main(){uchar key;P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符while(1){key=keyscan();//调用键盘扫描,switch(key){case 0x7e:P0=table[0];break;//0 按下相应的键显示相对应的码值case 0x7d:P0=table[1];break;//1case 0x7b:P0=table[2];break;//2case 0x77:P0=table[3];break;//3case 0xbe:P0=table[4];break;//4case 0xbd:P0=table[5];break;//5case 0xbb:P0=table[6];break;//6case 0xb7:P0=table[7];break;//7case 0xde:P0=table[8];break;//8case 0xdd:P0=table[9];break;//9case 0xdb:P0=table[10];break;//acase 0xd7:P0=table[11];break;//bcase 0xee:P0=table[12];break;//ccase 0xed:P0=table[13];break;//dcase 0xeb:P0=table[14];break;//ecase 0xe7:P0=table[15];break;//f}}}uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法{ uchar cord_h,cord_l;//行列值P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f){P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}void delay(uint i)//延时函数{while(i--);}在P3口做的键盘你的去抖检测没有做好通过电平输入来引发中断,必须是由P3.2或P3.3引脚输入,这样才能触发中断。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
dyp_tmp <= "1000010";
WHEN "0100" =>
dyp_tmp <= "1100100";
WHEN "0101" =>
dyp_tmp <= "1001000";
BEGIN
row <= scan_key;
--dyp <= dyp_tmp;
ledct<="000001";
PROCESS(clk)
BEGIN
IF(clk'EVENT AND clk = '1')THEN
div_cnt <= div_cnt + 1;
WHEN "0110" =>
dyp_tmp <= "0001000";
WHEN "0111" =>
dyp_tmp <= "1100011";
WHEN "1000" =>
WHEN "0001" =>
dyp_tmp <= "1100111";
WHEN "0010" =>
dyp_tmp <= "0010010";
WHEN "0011" =>
key_code <= "1101";
WHEN "1011" =>
key_code <= "1110";
用VHDL编写的一个简单4X4键盘扫描程序(2007-07-27 19:07:07)标签:vhdl键盘扫描
没有考虑去抖和判断键弹起的问,把相应的键值显示在数码管上,VHDL程序如下:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
key_code <= "1000";
WHEN "1101" =>
key_code <= "1001";
dyp_tmp <= "1000010";
WHEN "1110" =>
dyp_tmp <= "0110000";
ledct : OUT std_logic_vector(5 downto 0):="000001"); --数码管显示使能
END KEYDIS;
ARCHITECTURE arch OF KEYDIS IS
SIGNAL div_cnt : std_logic_vector(24 downto 0);
column : IN std_logic_vector(3 DOWNTO 0); -- 列线
dyp : OUT std_logic_vector(7 DOWNTO 1):="1111001"; -- 数码管显示数据
dyp_tmp <= "0000000";
WHEN "1001" =>
dyp_tmp <= "1100000";
WHEN "1010" =>
dyp_tmp <= "0001000";
END CASE;
WHEN OTHERS =>
key_code <= "1111ቤተ መጻሕፍቲ ባይዱ;
END CASE;
WHEN "0111" =>
key_code <= "1111";
WHEN OTHERS =>
NULL;
END IF;
END PROCESS;
PROCESS(div_cnt(20 downto 19))
BEGIN
CASE div_cnt(20 downto 19) IS
WHEN "00"=> scan_key<="1110";
WHEN "01"=> scan_key<="1101";
END IF;
END PROCESS;
-----显示键值
PROCESS(key_code)
BEGIN
CASE key_code IS
WHEN "0000" =>
dyp_tmp <= "0000001";
WHEN "1110" =>
key_code <= "0000";
WHEN "1101" =>
key_code <= "0001";
WHEN "1011" =>
dyp_tmp <= "1100000";
WHEN "1100" =>
dyp_tmp <= "0110001";
WHEN "1101" =>
WHEN "0111" =>
key_code <= "0111";
WHEN OTHERS =>
NULL;
WHEN OTHERS =>
NULL;
END CASE;
WHEN "0111" =>
WHEN "1011" =>
key_code <= "0010";
WHEN "0111" =>
key_code <= "0011";
END CASE;
WHEN "1011" =>
CASE column IS
WHEN "1110" =>
SIGNAL scan_key : std_logic_vector(3 DOWNTO 0); --扫描码寄存器
SIGNAL key_code : std_logic_vector(3 DOWNTO 0);
SIGNAL dyp_tmp : std_logic_vector(7 DOWNTO 1);
WHEN "10"=> scan_key<="1011";
WHEN "11"=> scan_key<="0111";
END CASE;
END PROCESS;
PROCESS(clk)
BEGIN
-- IF (NOT rst = '1') THEN
CASE column IS
WHEN "1110" =>
key_code <= "0100";
WHEN "1101" =>
CASE column IS
WHEN "1110" =>
key_code <= "1100";
WHEN "1101" =>
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY KEYDIS IS
PORT (
clk : IN std_logic;
row : OUT std_logic_vector(3 DOWNTO 0); -- 行线
WHEN "1011" =>
key_code <= "1010";
WHEN "0111" =>
key_code <= "1011";
WHEN OTHERS =>
NULL;
END CASE;
WHEN "1101" =>
key_code <= "0101";
WHEN "1011" =>
key_code <= "0110";
-- key_code <= "0000";
--ELS
IF(clk'EVENT AND clk='1')THEN
CASE scan_key IS --检测何处有键按下
WHEN "1110" =>
CASE column IS
相关文档
最新文档