1、2. 输入译码模块。对于44键盘,其具体对应关系如下图。行输出以1KHZ的频率在“1110”、“1101”、“1011”、“0111”四个状态中变化来对键盘进行扫描,再根据列输入来唯一确定所按下的键。比如:当按下2时,只有当行输出为1011时,对应的列输入为0111,其他情况下,列输入均为1111。将行列合并到一起为10110111,以此来确定输入值为数值2;防抖部分:使用计数防抖的方式来实现,起到一个延时的作用。缓存部分:多位数输入时,用data0、data1、data2 、data3来缓存高位值;数值计算:根据输入的单个数值计算出输入的数值的大小。第一个输入为1,第二个输入为3,第三个输入
2、为4,所得的num为134;该模块是使用状态转移来完成的,状态转移图如下:3. 计算模块根据当前运算符以及前一个运算符或前两个运算符来实现运算优先级的计算。具体实现方法见源代码。4. 显示模块利用状态机来实现各个数码管分别显示不同的数值。三、 仿真波形及波形分析1. 分频部分为了使仿真结果清晰可见,将1KHZ的分频结果,改成了10KHZ。所得结果见下图。由图可见,仿真结果正确无误。2. 计算部分仿真为了可以进行仿真,将行输出改为行输入,跳过键盘扫描部分,直接通过行列的输入来确定所输入的值。为了方便观察,将所得的结果直接赋值给一个数值变量,在仿真中显示该数值变量的值,仿真结果中不显示cat与di
3、gital的值。根据行列与键盘的对应关系可知,仿真进行的计算为12+457=,所得结果为327,然后清除,与预期相吻合。四、 源程序-主程序-LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY jsq ISPORT( clk : IN STD_LOGIC; -时钟输入 KEY_LIE : IN STD_LOGIC_VECTOR(3 DOWNTO 0);- 列输入 beep:out std_logic; -蜂鸣器报警 KEY_HAN
4、G :OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -行输出 digital : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);-数码管显示译码输出 cat : OUT STD_LOGIC_VECTOR(5 downto 0);-数码管显示扫描输出 END ; ARCHITECTURE be OF jsq IS signal CLK_1K1,CLK_40K1: STD_LOGIC; COMPONENT fenpin PORT(clk:IN STD_LOGIC; CLK_40K: OUT STD_LOGIC; CLK_1K: OUT STD_LOGIC)
5、; END COMPONENT; COMPONENT js PORT( CLK_1K : CLK_40K : beep: digital :begin u1:fenpin PORT MAP(clk,CLK_40K1,CLK_1K1); u2:js PORT MAP(CLK_1K1,CLK_40K1,KEY_LIE,KEY_HANG,beep,digital,cat); END be;-分频部分-ENTITY fenpin IS OUT STD_LOGIC );ARCHITECTURE be OF fenpin ISsignal CLK_1K1,CLK_40K1:STD_LOGIC; signa
6、l cnt1k :natural range 0 to 25000;signal cnt40k :natural range 0 to 625;process(clk) begin if (clkevent and clk=1) then-以下为50K分频,得到频率为1KHZ的频率- if cnt1k = 24999 then cnt1k=0; CLK_1K1=not CLK_1K1;else=cnt1k+1; end if; CLK_1K=CLK_1K1; -以下经分频得到40KHZ的频率- if cnt40k = 624 then cnt40k CLK_40K1=not CLK_40K1;
7、=cnt40k+1; CLK_40K=CLK_40K1; END PROCESS;-输入译码,计算,显示模块-ENTITY js IS- 列输入,输入与输出都是对主体而言,经过键盘以后键盘输出的值,然后输入到cpu中。 -行输出,由cpu输出,来对键盘进行扫描。-蜂鸣器输出; ARCHITECTURE be OF js IS SIGNAL INT : -列与非 信号SIGNAL CLK_SEL :-键值控制1khz的时钟信号SIGNAL data_0,data_1,data_2,data_3:integer range 0 to 9;-二-十进制 低位、高位信号SIGNAL KEY_HANG_
8、TMP:STD_LOGIC_VECTOR(3 DOWNTO 0);-行输出信号SIGNAL KEY_CODE:STD_LOGIC_VECTOR(7 DOWNTO 0);-行列 相并信号type fuhao_type is(f0,f1,f2,f3);-记录具体进行那种计算的状态signal fuhao_tmp:fuhao_type;signal num:integer range 0 to 9999;signal ff:integer range 0 to 2;-用来实现运算的优先级控制type time_type is (t1,t2,t3,t4,t5,t6);signal time1:time
9、_type;signal cat0:integer range 0 to 10;signal cat1:signal cat2:signal cat3:signal cat4:KEY_CODE=KEY_HANG_TMP&KEY_LIE;-行、列相并KEY_HANG=KEY_HANG_TMP;CLK_SEL=CLK_1K AND ( NOT INT);-无键按下时有CLK-SEL时钟信号输出,有键按下时,持续低电平。PROCESS (CLK_SEL,CLK_40K , INT) VARIABLE STATE : INTEGER RANGE 0 TO 3 ; BEGINIF RISING_EDGE
10、(CLK_40K) THEN -一个40K的脉冲上升沿到来输入一次列状态以判断是否有按键按下INT KEY_HANG_TMP1101=2 ; WHEN 2 =1011=3; WHEN 3 =0111 END CASE;END PROCESS;PROCESS (CLK_40K , INT)-进程是并行的INTEGER RANGE 0 TO 3;-用变量表示不同状态 VARIABLE COUNTER : INTEGER RANGE 0 TO 31;-用于计数延时去抖 variable fuhao:fuhao_type:=f0;BEGIN IF INT=0 THEN STATE: COUNTER:
11、ELSIF RISING_EDGE(CLK_40K) THEN CASE STATE IS WHEN 0 = data_3=data_2; data_2=data_1; data_1-再嵌套一个CASE语句 CASE KEY_CODE IS-实现把输入数据译码 十六进制的1到F WHEN 01110111 =-1 data_0 ff STATE:=2;-跳出内嵌套CASE语句,转向外CASE语句的状态2 10110111-211010111-311100111-4=4;01111011-5=5;10111011-6=6;11011011-7=7;11101011-8=8;01111101-9键
12、=9;10111101-0键11011101-= fuhao_tmp=fuhao; fuhao: WHEN 11101101-清除 data_301111110-+ fuhao_tmp-减=f2;11011110-*=f3; WHEN OTHERS =-不可缺少 WHEN 2 =-状态2实现去抖动功能 IF COUNTER=31 THEN -计数延时去抖 COUNTER: STATE: ELSE COUNTER:=COUNTER+1; STATE: END IF; WHEN 3=-将所得的数值赋值给num if(ff=1 or ff=2)then data_2data_1data_0 else
13、 num=data_3*1000+data_2*100+data_1*10+data_0; END CASE;process(CLK_SEL) variable y:integer range 0 to 1: variable result:integer range -9999999 to 9999999: variable num4: variable num3:integer range 0 to 999; variable num2:integer range 0 to 99; variable fuhao_t: variable result_tmp:integer range -9
14、9999 to 99999; variable result1: variable result2:if (CLK_SELevent and CLK_SEL= if(ff=0) then-未进行计算时的数值显示 result2:cat4cat3=data_3;cat2cat1cat0 beep result:=num;fuhao_t:result_tmp: when f1=result+num; when f2=result-num; when f3= case fuhao_t is=result*num;=result*num+result_tmp;=r esult_tmp-result*n
15、um; end case; else-当前符号为 when f0 = when others= fuhao_t:=fuhao_tmp; result_tmp:=result; else y: -显示部分- if(result99999 or result cat = 101111 digital1001111-E time1 1101111110111-R= t3; WHEN t3 =111011= t4; WHEN t4 =1111011111110-O= t5; WHEN t5 =111110= t1; WHEN OTHERS = beep else -所得结果正常时,计算进行显示时各个数
16、码管的值 if(result2=90000)then cat4=80000 and result190000)then cat4=70000 and result180000)then cat4=60000 and result170000)then cat4=50000 and result160000)then cat4=40000 and result150000)then cat4=30000 and result140000)then cat4=20000 and result130000)then cat4=10000 and result120000)then cat4 elsif(result110000)then cat4=9000 and num410000)then cat3 -得到所得结果千位的值
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1