3956|2

15

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

FPGA学习—矩阵键盘数码管显示 [复制链接]

控制单个数码管显示按键的键值,

在设计中,利用VHDL硬件描述语言在FPGA芯片上实现键盘接口设计并利用仿真FPGA软件进行仿真,主要解决了三个问题:一是如何检测是否有按键按下并防止采集到干扰信号;二是在按键闭合时如何防止抖动;三是如何判断为哪一个按键位动作,并对其进行译码。

分为四个模块,分频模块,译码模块,键盘扫描模块,键值确定模块,

分频模块

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY FENPING IS
PORT(
CLK:IN STD_LOGIC;
CLK_200:OUT STD_LOGIC;
CLK_1K:OUT STD_LOGIC;
CLK_40K:OUT STD_LOGIC
);
END ENTITY;

ARCHITECTURE ART OF FENPING IS
SIGNAL COUNT0:INTEGER RANGE 0 TO 1249;
SIGNAL COUNT1:INTEGER RANGE 0 TO 49999;
SIGNAL COUNT2:INTEGER RANGE 0 TO 249999;
BEGIN

PROCESS(CLK)IS
BEGIN
IF(CLK'EVENT AND CLK='1')THEN
   IF(COUNT0=1249)THEN COUNT0<=0;
    ELSE COUNT0<=COUNT0+1;
    END IF;
   IF(COUNT1=49999)THEN COUNT1<=0;
      ELSE COUNT1<=COUNT1+1;
      END IF;
    IF(COUNT2=249999)THEN COUNT2<=0;
     ELSE COUNT2<=COUNT2+1;
     END IF;
END IF;
END PROCESS;

PROCESS(COUNT0)IS
BEGIN
IF(COUNT0>=625)THEN CLK_40K<='1';
ELSE CLK_40K<='0';
END IF;
END PROCESS;

PROCESS(COUNT1)IS
BEGIN
IF(COUNT1>=25000)THEN CLK_1K<='1';
ELSE CLK_1K<='0';
END IF;
END PROCESS;

PROCESS(COUNT2)IS
BEGIN
IF(COUNT2>=125000)THEN CLK_200<='1';
ELSE CLK_200<='0';
END IF;
END PROCESS;

END ARCHITECTURE;
产生200HZ,1KHZ,40KHZ三中频率

译码模块

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY YIMA IS

PORT(
TMP:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
DIS:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END ENTITY;

ARCHITECTURE ART OF YIMA IS
BEGIN
PROCESS(TMP)IS
BEGIN
CASE(TMP)IS
 WHEN"0000"=>DIS<="00111111";
       WHEN"0001"=>DIS<="00000110";
       WHEN"0010"=>DIS<="01011011";
       WHEN"0011"=>DIS<="01001111";
       WHEN"0100"=>DIS<="01100110";
       WHEN"0101"=>DIS<="01101101";
       WHEN"0110"=>DIS<="01111101";
       WHEN"0111"=>DIS<="00000111";
       WHEN"1000"=>DIS<="01111111";
       WHEN"1001"=>DIS<="01101111";
       WHEN"1010"=>DIS<="01110111";
       WHEN"1011"=>DIS<="01111100";
       WHEN"1100"=>DIS<="00111001";
       WHEN"1101"=>DIS<="01011110";
       WHEN"1110"=>DIS<="01111001";
       WHEN"1111"=>DIS<="01110001";
       WHEN OTHERS=>DIS<="00000000";
 END CASE;
 END PROCESS;
 END ARCHITECTURE;

得到键值后,译成数码管显示的键值,由于只有一个数码管,所以不存在位扫描。

键盘扫描模块

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY KEY_SCAN IS
PORT(
CLK_200:IN STD_LOGIC;
KEY_LIE:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END ENTITY;

ARCHITECTURE ART OF KEY_SCAN IS

SIGNAL CURRENT_STATE,NEXT_STATE:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN
PROCESS(CLK_200)IS
BEGIN
IF(CLK_200'EVENT AND CLK_200='1')THEN
 CURRENT_STATE<=NEXT_STATE;
 END IF;
END PROCESS;

PROCESS(CURRENT_STATE)IS
BEGIN
CASE CURRENT_STATE IS
WHEN"1110"=>NEXT_STATE<="1101";
WHEN"1101"=>NEXT_STATE<="1011";
WHEN"1011"=>NEXT_STATE<="0111";
WHEN"0111"=>NEXT_STATE<="1110";
WHEN OTHERS=>NEXT_STATE<="1110";
END CASE;
END PROCESS;
KEY_LIE<=CURRENT_STATE;
END ARCHITECTURE;

键盘扫描的思路是对输出列信号四位轮流输出低电平,检测输入行信号四位是否有低电平,有低电平说明有键码按下,再根据行列的矢量值,判断到底是哪一位按下。

键值确定模块

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY JIANPAN1 IS
PORT(
CLK:IN STD_LOGIC;

KEY_HANG:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
KEY_LIE:BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0);
DIS:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END ENTITY;

ARCHITECTURE ART OF JIANPAN1 IS

COMPONENT FENPING IS
PORT(
CLK:IN STD_LOGIC;
CLK_200:OUT STD_LOGIC;
CLK_1K:OUT STD_LOGIC;
CLK_40K:OUT STD_LOGIC
);
END COMPONENT;
COMPONENT YIMA IS

PORT(
TMP:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
DIS:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
COMPONENT KEY_SCAN IS
PORT(
CLK_200:IN STD_LOGIC;
KEY_LIE:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT;
SIGNAL keyvalue:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL KEY_CODE:STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL TMP:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL CLK_200,CLK_1K,CLK_40K,INT,temp_pressed:STD_LOGIC;
BEGIN
U1:FENPING PORT MAP(CLK,CLK_200,CLK_1K,CLK_40K);
U2:KEY_SCAN PORT MAP(CLK_200,KEY_LIE);
U3:YIMA PORT MAP(TMP,DIS);
INT<=NOT(KEY_HANG(0)AND KEY_HANG(1)AND KEY_HANG(2)AND KEY_HANG(3));
KEY_CODE<=KEY_HANG&KEY_LIE;
PROCESS(CLK_40K)IS
 BEGIN
 IF(INT='1')THEN
IF(CLK_40K'EVENT AND CLK_40K='1')THEN
 IF(INT='1')THEN
  CASE KEY_CODE IS
  WHEN"11101110"=>keyvalue<=CONV_STD_LOGIC_VECTOR(0,4);
                                   temp_pressed<='1';
                             
               WHEN"11101101" =>keyvalue<=CONV_STD_LOGIC_VECTOR(1,4);
                                  temp_pressed<='1';        
                              
               WHEN"11101011" =>keyvalue<=CONV_STD_LOGIC_VECTOR(2,4);
                                   temp_pressed<='1';
                             
               WHEN"11100111" =>keyvalue<=CONV_STD_LOGIC_VECTOR(3,4);
                                   temp_pressed<='1';
                               
               WHEN"11011110" =>keyvalue<=CONV_STD_LOGIC_VECTOR(4,4);
                                   temp_pressed<='1';
                                  
               WHEN"11011101" =>keyvalue<=CONV_STD_LOGIC_VECTOR(5,4);
                                     temp_pressed<='1';
                               
               WHEN"11011011" =>keyvalue<=CONV_STD_LOGIC_VECTOR(6,4);
                                   temp_pressed<='1';
                               
               WHEN"11010111" =>keyvalue<=CONV_STD_LOGIC_VECTOR(7,4);
                                   temp_pressed<='1';
                               
               WHEN"10111110" =>keyvalue<=CONV_STD_LOGIC_VECTOR(8,4);
                                   temp_pressed<='1';
                              
               WHEN"10111101" =>keyvalue<=CONV_STD_LOGIC_VECTOR(9,4);
                                temp_pressed<='1';
                                       
               WHEN"10111011" =>keyvalue<=CONV_STD_LOGIC_VECTOR(10,4);
                                  temp_pressed<='1';
                              
               WHEN"10110111" =>keyvalue<=CONV_STD_LOGIC_VECTOR(11,4);
                             temp_pressed<='1';
                        
               WHEN"01111110" =>keyvalue<=CONV_STD_LOGIC_VECTOR(12,4);
                                    temp_pressed<='1';
                          
               WHEN"01111101" =>keyvalue<=CONV_STD_LOGIC_VECTOR(13,4);
                                  temp_pressed<='1';
                            
               WHEN"01111011" =>keyvalue<=CONV_STD_LOGIC_VECTOR(14,4);
                                   temp_pressed<='1';
                             
               WHEN"01110111" =>keyvalue<=CONV_STD_LOGIC_VECTOR(15,4);
                                    temp_pressed<='1';
                             
              WHEN OTHERS  =>
                                 temp_pressed<='0';
           END CASE;
           END IF;
           END IF;
           END IF;
 END PROCESS;
 
 PROCESS(CLK_1K)IS
BEGIN
IF(temp_pressed='1')THEN
 IF(CLK_1K'EVENT AND CLK_1K='1')THEN
   TMP<=keyvalue;
   END IF;
 END IF;
 END PROCESS;
 END ARCHITECTURE;

在动态输入列信号,扫描行信号,得到键值。

本实验的关键在于键盘检测的思想,对行赋值,检测列值,关于消抖程序,不太明白,好像也没涉及到。

此帖出自FPGA/CPLD论坛

最新回复

干货 支持一下   详情 回复 发表于 2021-5-5 17:39
点赞 关注
 

回复
举报

6892

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

支持楼主。如果楼主能对程序进行理解和评价,那就更好了

此帖出自FPGA/CPLD论坛
个人签名一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
 
 

回复

13

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

干货

支持一下

此帖出自FPGA/CPLD论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表