北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx

上传人:b****6 文档编号:17474865 上传时间:2022-12-01 格式:DOCX 页数:23 大小:132.95KB
下载 相关 举报
北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx_第1页
第1页 / 共23页
北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx_第2页
第2页 / 共23页
北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx_第3页
第3页 / 共23页
北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx_第4页
第4页 / 共23页
北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx

《北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx(23页珍藏版)》请在冰豆网上搜索。

北邮 数电综合实验报告 简易计算器讲诉Word文档下载推荐.docx

2.输入译码模块。

对于4×

4键盘,其具体对应关系如下图。

行输出以1KHZ的频率在“1110”、“1101”、“1011”、“0111”四个状态中变化来对键盘进行扫描,再根据列输入来唯一确定所按下的键。

比如:

当按下2时,只有当行输出为1011时,对应的列输入为0111,其他情况下,列输入均为1111。

将行列合并到一起为10110111,以此来确定输入值为数值2;

防抖部分:

使用计数防抖的方式来实现,起到一个延时的作用。

缓存部分:

多位数输入时,用data0、data1、data2、data3来缓存高位值;

数值计算:

根据输入的单个数值计算出输入的数值的大小。

第一个输入为1,第二个输入为3,第三个输入为4,所得的num为134;

该模块是使用状态转移来完成的,状态转移图如下:

3.计算模块

根据当前运算符以及前一个运算符或前两个运算符来实现运算优先级的计算。

具体实现方法见源代码。

4.显示模块

利用状态机来实现各个数码管分别显示不同的数值。

三、仿真波形及波形分析

1.分频部分

为了使仿真结果清晰可见,将1KHZ的分频结果,改成了10KHZ。

所得结果见下图。

由图可见,仿真结果正确无误。

2.计算部分仿真

为了可以进行仿真,将行输出改为行输入,跳过键盘扫描部分,直接通过行列的输入来确定所输入的值。

为了方便观察,将所得的结果直接赋值给一个数值变量,在仿真中显示该数值变量的值,仿真结果中不显示cat与digital的值。

根据行列与键盘的对应关系可知,仿真进行的计算为12+45×

7=,所得结果为327,然后清除,与预期相吻合。

四、源程序

-----------------主程序-----------------

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_ARITH.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITYjsqIS

PORT(

clk:

INSTD_LOGIC;

--时钟输入

KEY_LIE:

INSTD_LOGIC_VECTOR(3DOWNTO0);

--列输入

beep:

outstd_logic;

--蜂鸣器报警

KEY_HANG:

OUTSTD_LOGIC_VECTOR(3DOWNTO0);

--行输出

digital:

OUTSTD_LOGIC_VECTOR(6DOWNTO0);

--数码管显示译码输出

cat:

OUTSTD_LOGIC_VECTOR(5downto0));

--数码管显示扫描输出

END;

ARCHITECTUREbeOFjsqIS

signalCLK_1K1,CLK_40K1:

STD_LOGIC;

COMPONENTfenpin

PORT(clk:

INSTD_LOGIC;

CLK_40K:

OUTSTD_LOGIC;

CLK_1K:

OUTSTD_LOGIC);

ENDCOMPONENT;

COMPONENTjs

PORT(

CLK_1K:

CLK_40K:

beep:

digital:

begin

u1:

fenpinPORTMAP(clk,CLK_40K1,CLK_1K1);

u2:

jsPORTMAP(CLK_1K1,CLK_40K1,KEY_LIE,KEY_HANG,beep,digital,cat);

ENDbe;

----------------------分频部分-----------------------

ENTITYfenpinIS

OUTSTD_LOGIC

);

ARCHITECTUREbeOFfenpinIS

signalCLK_1K1,CLK_40K1:

STD_LOGIC;

signalcnt1k:

naturalrange0to25000;

signalcnt40k:

naturalrange0to625;

process(clk)

begin

if(clk'

eventandclk='

1'

)then

----以下为50K分频,得到频率为1KHZ的频率------

ifcnt1k=24999then

cnt1k<

=0;

CLK_1K1<

=notCLK_1K1;

else

=cnt1k+1;

endif;

CLK_1K<

=CLK_1K1;

----以下经分频得到40KHZ的频率----------

ifcnt40k=624then

cnt40k<

CLK_40K1<

=notCLK_40K1;

=cnt40k+1;

CLK_40K<

=CLK_40K1;

ENDPROCESS;

-----------------------输入译码,计算,显示模块--------------------

ENTITYjsIS

--列输入,输入与输出都是对主体而言,经过键盘以后键盘输出的值,然后输入到cpu中。

--行输出,由cpu输出,来对键盘进行扫描。

--蜂鸣器输出;

ARCHITECTUREbeOFjsIS

SIGNALINT:

--列与非信号

SIGNALCLK_SEL:

--键值控制1khz的时钟信号

SIGNALdata_0,data_1,data_2,data_3:

integerrange0to9;

--二-十进制低位、高位信号

SIGNALKEY_HANG_TMP:

STD_LOGIC_VECTOR(3DOWNTO0);

--行输出信号

SIGNALKEY_CODE:

STD_LOGIC_VECTOR(7DOWNTO0);

--行列相并信号

typefuhao_typeis(f0,f1,f2,f3);

--记录具体进行那种计算的状态

signalfuhao_tmp:

fuhao_type;

signalnum:

integerrange0to9999;

signalff:

integerrange0to2;

--用来实现运算的优先级控制

typetime_typeis(t1,t2,t3,t4,t5,t6);

signaltime1:

time_type;

signalcat0:

integerrange0to10;

signalcat1:

signalcat2:

signalcat3:

signalcat4:

KEY_CODE<

=KEY_HANG_TMP&

KEY_LIE;

--行、列相并

KEY_HANG<

=KEY_HANG_TMP;

CLK_SEL<

=CLK_1KAND(NOTINT);

--无键按下时有CLK-SEL时钟信号输出,有键按下时,持续低电平。

PROCESS(CLK_SEL,CLK_40K,INT)

VARIABLESTATE:

INTEGERRANGE0TO3;

BEGIN

IFRISING_EDGE(CLK_40K)THEN--一个40K的脉冲上升沿到来输入一次列状态以判断是否有按键按下

INT<

=NOT(KEY_LIE(3)ANDKEY_LIE

(2)ANDKEY_LIE

(1)ANDKEY_LIE(0));

--有按键被按下时int为高电平

ENDIF;

IFRISING_EDGE(CLK_SEL)THEN--一个1K的脉冲的上升沿到来输出一个带表行的状态

CASESTATEIS--变量表示状态机,4循环

WHEN0=>

KEY_HANG_TMP<

="

1110"

;

STATE:

=1;

WHEN1=>

1101"

=2;

WHEN2=>

1011"

=3;

WHEN3=>

0111"

ENDCASE;

ENDPROCESS;

PROCESS(CLK_40K,INT)--进程是并行的

INTEGERRANGE0TO3;

--用变量表示不同状态

VARIABLECOUNTER:

INTEGERRANGE0TO31;

--用于计数延时去抖

variablefuhao:

fuhao_type:

=f0;

BEGIN

IFINT='

0'

THEN

STATE:

COUNTER:

ELSIFRISING_EDGE(CLK_40K)THEN

CASESTATEIS

WHEN0=>

data_3<

=data_2;

data_2<

=data_1;

data_1<

=data_0;

STATE:

WHEN1=>

--再嵌套一个CASE语句

CASEKEY_CODEIS--实现把输入数据译码十六进制的1到F

WHEN"

01110111"

=>

--1

data_0<

ff<

STATE:

=2;

--跳出内嵌套CASE语句,转向外CASE语句的状态2

10110111"

--2

11010111"

--3

11100111"

--4

=4;

01111011"

--5

=5;

10111011"

--6

=6;

11011011"

--7

=7;

11101011"

--8

=8;

01111101"

--9键

=9;

10111101"

--0键

11011101"

--=

fuhao_tmp<

=fuhao;

fuhao:

WHEN"

11101101"

--清除

data_3<

01111110"

--+

fuhao_tmp<

=f1;

STATE:

10111110"

=>

--减

=f2;

11011110"

--*

=f3;

WHENOTHERS=>

--不可缺少

WHEN2=>

--状态2实现去抖动功能

IFCOUNTER=31THEN--计数延时去抖

COUNTER:

STATE:

ELSE

COUNTER:

=COUNTER+1;

STATE:

ENDIF;

WHEN3=>

--将所得的数值赋值给num

if(ff=1orff=2)then

data_2<

data_1<

data_0<

else

num<

=data_3*1000+data_2*100+data_1*10+data_0;

ENDCASE;

process(CLK_SEL)

variabley:

integerrange0to1:

variableresult:

integerrange-9999999to9999999:

variablenum4:

variablenum3:

integerrange0to999;

variablenum2:

integerrange0to99;

variablefuhao_t:

variableresult_tmp:

integerrange-99999to99999;

variableresult1:

variableresult2:

if(CLK_SEL'

eventandCLK_SEL='

if(ff=0)then--未进行计算时的数值显示

result2:

cat4<

cat3<

=data_3;

cat2<

cat1<

cat0<

beep<

='

y:

else

if(y=1)then--带优先级的具体计算

if(ff=1)then--当前符号不为×

时,

casefuhao_tmpis

whenf0=>

result:

=num;

fuhao_t:

result_tmp:

whenf1=>

=result+num;

whenf2=>

=result-num;

whenf3=>

casefuhao_tis

=result*num;

=result*num+result_tmp;

=result_tmp-result*num;

endcase;

else--当前符号为×

whenf0=>

whenothers=>

fuhao_t:

=fuhao_tmp;

result_tmp:

=result;

elsey:

------显示部分-----

if(result>

99999orresult<

-99999)then--数字超出范围时报错。

CASEtime1IS

WHENt1=>

cat<

="

101111"

digital<

1001111"

-----E

time1<

=t2;

WHENt2=>

110111"

1110111"

-----R

=t3;

WHENt3=>

111011"

=t4;

WHENt4=>

111101"

1111110"

-----O

=t5;

WHENt5=>

111110"

=t1;

WHENOTHERS=>

beep<

else--所得结果正常时,计算进行显示时各个数码管的值

if(result2<

0)thenresult1:

=abs(result2);

--当数字小于0时取绝对值,再进行下面的操作

elseresult1:

=result2;

endif;

if(result1>

=90000)thencat4<

--得到所得结果万位的值

elsif(result1>

=80000andresult1<

90000)thencat4<

=70000andresult1<

80000)thencat4<

=60000andresult1<

70000)thencat4<

=50000andresult1<

60000)thencat4<

=40000andresult1<

50000)thencat4<

=30000andresult1<

40000)thencat4<

=20000andresult1<

30000)thencat4<

=10000andresult1<

20000)thencat4<

elsif(result1<

10000)thencat4<

num4:

=result1-cat4*10000;

if(num4>

=9000andnum4<

10000)thencat3<

--得到所得结果千位的值

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 理化生

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1