• 方案介绍
  • 相关推荐
申请入驻 产业图谱

基于PS2键盘的LCD计算器VHDL设计DE2-115 FPGA开发板

09/28 08:52
623
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

基于PS2键盘的LCD计算器VHDL设计DE2-115 FPGA开发板

项目概述

名称: PS2键盘LCD计算器VHDL QuartusII
软件: Quartus II
语言: VHDL
目标平台: DE2-115 FPGA开发板

代码功能

本项目实现了一个基于FPGA的数字计算器系统,支持通过PS2键盘输入数字和运算符,并在LCD1602显示屏上显示计算过程和结果。系统支持四则运算(加、减、乘、除),能够处理单位数运算,除法运算还能显示余数。整个系统采用状态机设计,具有良好的用户交互体验和错误处理机制。

代码实现思路

整体架构设计

系统采用模块化设计思想,将功能分解为多个独立的功能模块:

  • 输入处理模块:负责PS2键盘信号的接收、解码和按键识别
  • 状态控制模块:实现计算器的状态机逻辑,控制整个运算流程
  • 数值处理模块:处理数字输入、存储操作数并执行四则运算
  • 显示控制模块:控制LCD1602显示屏,实现运算过程和结果的可视化

核心算法流程

  1. 初始化状态:系统复位,等待第一个操作数输入
  2. 操作数A输入:接收并存储第一个操作数
  3. 运算符识别:检测加减乘除运算符,确定运算类型
  4. 操作数B输入:接收并存储第二个操作数
  5. 运算执行:根据运算符执行相应的算术运算
  6. 结果显示:在LCD上显示完整的运算表达式和结果

关键技术特点

  • 采用同步时序逻辑设计,确保系统稳定性
  • 实现PS2协议解析,支持标准键盘输入
  • 集成BCD码转换,便于数字显示处理
  • 状态机控制确保运算流程的正确性

演示视频

代码结构

顶层模块 (top.vhd)

系统的顶层模块,负责连接各个子模块并定义外部接口,包括时钟、复位、PS2键盘接口和LCD显示接口。

计算器核心模块 (calculator.vhd)

计算器的主控制模块,集成输入处理、状态控制和数值处理三个子模块,协调整个计算流程。

数据输入模块 (data_input.vhd)

处理PS2键盘输入,包含扫描码接收、ASCII转换和按键识别功能,输出数字和运算符的按键信号。

状态控制模块 (state_ctrl.vhd)

实现计算器的有限状态机,管理输入第一操作数、运算符、第二操作数、计算和显示结果等状态转换。

数值输入模块 (num_in.vhd)

负责数字的输入处理和四则运算的执行,包括操作数存储、运算类型判断和结果计算功能。

LCD显示模块 (lcd1602.vhd)

控制LCD1602显示屏,实现计算过程和结果的实时显示,包括LCD初始化、字符显示和格式控制。

BCD转换模块 (BCD.vhd)

将二进制数转换为BCD码,便于在LCD上以十进制形式显示数字结果。

PS2接口模块 (data_scanC.vhd & convert.vhd)

实现PS2键盘协议的硬件接口,包括扫描码接收和ASCII码转换功能。


工程文件图片
请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

部分代码展示

LIBRARY ieee;
   USE ieee.std_logic_1164.all;
--计算器
ENTITY calculator IS
   PORT (
      clk        : IN STD_LOGIC;--时钟500K
--sys_clk : in  STD_LOGIC; -- 系统时钟
reset       : IN STD_LOGIC;--低电平复位---rst_n
--      L_row       : IN STD_LOGIC_VECTOR(3 DOWNTO 0);----矩阵键盘行 
--      H_col       : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);----矩阵键盘列 
       k_data  : in  STD_LOGIC; -- PS2键盘数据线
       k_clock : in  STD_LOGIC; -- PS2键盘时钟线
      OP_current_state   :OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
OP_calcul  : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);--计算方式,--00表示加--01表示减--10表示乘--11表示除
      OP_A       : OUT integer;--输入的操作数A
      OP_B       : OUT integer;--输入的操作数B
      OP_Result  : OUT integer;--结果
OP_reminder : OUT integer; --余数
error       : OUT STD_LOGIC--错误提示
   );
END calculator;
ARCHITECTURE trans OF calculator IS
   
--输入模块
COMPONENT data_input IS
   PORT (
      clk  : IN STD_LOGIC;--500KHz
      reset       : IN STD_LOGIC;
--      L_row       : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--行
--      H_col       : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);--列
       k_data  : in  STD_LOGIC; -- PS2键盘数据线
       k_clock : in  STD_LOGIC; -- PS2键盘时钟线
      key_0_rise  : OUT STD_LOGIC;
      key_1_rise  : OUT STD_LOGIC;
      key_2_rise  : OUT STD_LOGIC;
      key_3_rise  : OUT STD_LOGIC;
      key_4_rise  : OUT STD_LOGIC;
      key_5_rise  : OUT STD_LOGIC;
      key_6_rise  : OUT STD_LOGIC;
      key_7_rise  : OUT STD_LOGIC;
      key_8_rise  : OUT STD_LOGIC;
      key_9_rise  : OUT STD_LOGIC;
      key_add_rise  : OUT STD_LOGIC;
      key_sub_rise  : OUT STD_LOGIC;
      key_mul_rise  : OUT STD_LOGIC;
      key_esc_rise  : OUT STD_LOGIC;
      key_enter_rise  : OUT STD_LOGIC;
      key_div_rise  : OUT STD_LOGIC
   );
END COMPONENT;
   COMPONENT state_ctrl IS
      PORT (
         clk        : IN STD_LOGIC;
         esc        : IN STD_LOGIC;
         add        : IN STD_LOGIC;
         sub        : IN STD_LOGIC;
         mul        : IN STD_LOGIC;
         div        : IN STD_LOGIC;
         enter      : IN STD_LOGIC;
         current_state : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
         calcul     : OUT STD_LOGIC_VECTOR(1 DOWNTO 0)
      );
   END COMPONENT;
   
   COMPONENT num_in IS
      PORT (
         clk        : IN STD_LOGIC;
         esc        : IN STD_LOGIC;
         key_0      : IN STD_LOGIC;
         key_1      : IN STD_LOGIC;
         key_2      : IN STD_LOGIC;
         key_3      : IN STD_LOGIC;
         key_4      : IN STD_LOGIC;
         key_5      : IN STD_LOGIC;
         key_6      : IN STD_LOGIC;
         key_7      : IN STD_LOGIC;
         key_8      : IN STD_LOGIC;
         key_9      : IN STD_LOGIC;
error          : OUT STD_LOGIC;--错误提示
         current_state : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
         calcul     : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
         OP_A       : OUT integer;
         OP_B       : OUT integer;
         OP_Result  : OUT integer;
reminder       : OUT integer ---余数
      );
   END COMPONENT;
   SIGNAL   esc        :  STD_LOGIC;--ESC键
   SIGNAL   add        :  STD_LOGIC;--加
   SIGNAL   sub        :  STD_LOGIC;--减
   SIGNAL   mul        :  STD_LOGIC;--乘
   SIGNAL   div        :  STD_LOGIC;--除
   SIGNAL   enter      :  STD_LOGIC;--Enter键
   
   SIGNAL current_state   : STD_LOGIC_VECTOR(2 DOWNTO 0);
   SIGNAL calcul          : STD_LOGIC_VECTOR(1 DOWNTO 0);
   
   SIGNAL key_0_p         : STD_LOGIC;
   SIGNAL key_1_p         : STD_LOGIC;
   SIGNAL key_2_p         : STD_LOGIC;
   SIGNAL key_3_p         : STD_LOGIC;
   SIGNAL key_4_p         : STD_LOGIC;
   SIGNAL key_5_p         : STD_LOGIC;
   SIGNAL key_6_p         : STD_LOGIC;
   SIGNAL key_7_p         : STD_LOGIC;
   SIGNAL key_8_p         : STD_LOGIC;
   SIGNAL key_9_p         : STD_LOGIC;
   
   -- Declare intermediate signals for referenced outputs
   SIGNAL OP_A_buf      : integer;
   SIGNAL OP_B_buf      : integer;
   SIGNAL OP_Result_buf : integer;
SIGNAL reminder      : integer;
 
BEGIN
   -- Drive referenced outputs
   OP_A <= OP_A_buf;
   OP_B <= OP_B_buf;
   OP_Result <= OP_Result_buf;
   OP_calcul <= calcul;
   OP_current_state <= current_state;
--输入模块
U_data_input: data_input
   PORT MAP(
      clk  => clk,--时钟
      reset =>reset,
--      L_row =>L_row,--行
--      H_col =>H_col,--列
       k_data  =>k_data, -- PS2键盘数据线
       k_clock =>k_clock, -- PS2键盘时钟线
      key_0_rise  =>key_0_p,
      key_1_rise  =>key_1_p,
      key_2_rise  =>key_2_p,
      key_3_rise  =>key_3_p,
      key_4_rise  =>key_4_p,
      key_5_rise  =>key_5_p,
      key_6_rise  =>key_6_p,
      key_7_rise  =>key_7_p,
      key_8_rise  =>key_8_p,
      key_9_rise  =>key_9_p,
      key_esc_rise  =>esc,
      key_add_rise  =>add,
      key_sub_rise  =>sub,
      key_mul_rise  =>mul,
      key_div_rise  =>div,
      key_enter_rise  =>enter
   );
   --状态控制模块
   i_state_ctrl : state_ctrl
      PORT MAP (
         clk            => clk,--时钟
         esc            => esc,--ESC键
         add            => add,--加
         sub            => sub,--减
         mul            => mul,--乘
         div            => div,--除
         enter          => enter,--Enter键
         current_state  => current_state,--当前状态
         calcul         => calcul--计算
      );
   
   
   --数字输入模块
   i_num_in : num_in
      PORT MAP (
         clk            => clk,--时钟
         esc            => esc,
error          => error,
         key_0          => key_0_p,
         key_1          => key_1_p,
         key_2          => key_2_p,
         key_3          => key_3_p,
         key_4          => key_4_p,
         key_5          => key_5_p,
         key_6          => key_6_p,
         key_7          => key_7_p,
         key_8          => key_8_p,
         key_9          => key_9_p,
         current_state  => current_state,--当前状态
         calcul         => calcul,--计算方式,--00表示加--01表示减--10表示乘--11表示除
         OP_A           => OP_A_buf,--输入的操作数A
         OP_B           => OP_B_buf,--输入的操作数B
         OP_Result      => OP_Result_buf,--结果
reminder        => OP_reminder--结果
      );
   
END trans;

相关推荐