利用键盘控制点阵进行十进制加法计算显示
- 格式:doc
- 大小:2.88 MB
- 文档页数:25
摘要本设计是基于51系列的单片机进行的十进制计算器系统设计,可以完成计算器的键盘输入,进行加、减、乘、除3位无符号数字的简单四则运算,并在LED上相应的显示结果。
设计过程在硬件与软件方面进行同步设计。
硬件方面从功能考虑,首先选择内部存储资源丰富的AT89C51单片机,输入采用4×4矩阵键盘。
显示采用3位7段共阴极LED动态显示。
软件方面从分析计算器功能、流程图设计,再到程序的编写进行系统设计。
编程语言方面从程序总体设计以及高效性和功能性对C 语言和汇编语言进行比较分析,针对计算器四则运算算法特别是乘法和除法运算的实现,最终选用全球编译效率最高的KEIL公司的μVision3软件,采用汇编语言进行编程,并用proteus仿真。
引言十进制加法计算器的原理与设计是单片机课程设计课题中的一个。
在完成理论学习和必要的实验后,我们掌握了单片机的基本原理以及编程和各种基本功能的应用,但对单片机的硬件实际应用设计和单片机完整的用户程序设计还不清楚,实际动手能力不够,因此对该课程进行一次课程设计是有必要的。
单片机课程设计既要让学生巩固课本学到的理论,还要让学生学习单片机硬件电路设计和用户程序设计,使所学的知识更深一层的理解,十进制加法计算器原理与硬软件的课程设计主要是通过学生独立设计方案并自己动手用计算机电路设计软件,编写和调试,最后仿真用户程序,来加深对单片机的认识,充分发挥学生的个人创新能力,并提高学生对单片机的兴趣,同时学习查阅资料、参考资料的方法。
关键词:单片机、计算器、AT89C51芯片、汇编语言、数码管、加减乘除目录摘要 (01)引言 (01)一、设计任务和要求.............................1、1 设计要求1、2 性能指标1、3 设计方案的确定二、单片机简要原理.............................2、1 AT89C51的介绍2、2 单片机最小系统2、3 七段共阳极数码管三、硬件设计...................................3、1 键盘电路的设计3、2 显示电路的设计四、软件设计...................................4、1 系统设计4、2 显示电路的设计五、调试与仿真.................................5、1 Keil C51单片机软件开发系统5、2 proteus的操作六、心得体会....................................参考文献......................................... 附录1 系统硬件电路图............................ 附录2 程序清单..................................一、设计任务和要求1.1 设计要求本次课程设计,我选择的课题是单片机十进制加法计算器软硬件设计,设计任务为:设计一键盘显示装置,键盘上除需定义10个十进制数字键外还要相应的功能键,其它键不定义无响应。
十进制数加减计算器的设计1 问题描述用汇编语言设计一个十进制数加减计算器,能够实现两个二位十进制数的加减运算,并具有友好的界面。
2 设计说明该程序数据流程图:3 详细的算法描述定义两个数据段,通过键盘输入,存储于AX ,BX 中,选择运算符号“+或-”,自动运算AX ,BX 中的数据,然后将结果转化为十进制输出。
(详细解释见源程序)4 源程序与执行结果4.1 源程序:CURS MACRO A,BMOV AH,2 ;置光标位置MOV BH,0 ;页号为0MOV DH,A ;设置光标的坐标为(A.B)MOV DL,BINT 10H ;BIOS调用ENDM;-------------------------------DISPMSG MACRO MESSAGELEA DX,MESSAGE ;传递MESSAGE的偏移地址MOV AH,9 ;显示字符串INT 21H ;DOS调用ENDM;----------------------------------CLEAR MACRO COLOR ;清屏MOV AH,6 ;屏幕初始化MOV AL,0 ;页号MOV CH,0 ;设置左上角的坐标为(0,0)MOV CL,0MOV DL,100 ;设置右上角的坐标为(100,100)MOV DH,100MOV BH,COLOR ;卷入行属性INT 10H ;BIOS调用ENDM.MODEL SMALL.STACK.DATA ;数据段定义MSG0 DB '* * * * * * * * * * * * * * * * * * * *',0DH,0AH ;,0dh,0ah,0dh,0ahDB ' * *',0DH,0AH;db '* *',0dh,0ah;db '* *',0dh,0ahDB ' * --------COUNTER-------- *',0DH,0AH ;,0dh,0ah,0dh,0ahDB ' * *',0DH,0AHDB ' * *',0DH,0AHDB ' * *',0DH,0AHDB ' * DATA1:'DB '_______________ *',0DH,0AH ;,0dh,0ah,0dh,0ah,0dhDB ' * *',0DH,0AHDB ' * *',0DH,0AHDB ' * *',0DHDB ' * DATA2:'DB '_______________ *',0DH,0AH ;,0dh,0ah,0dh,0ah,0dhDB ' * *',0DH,0AHDB ' * *',0DH,0AHDB ' * *',0DHDB ' * RESULT:'DB '_______________ *',0DH,0AH,0DH ;,0ah,0dh,0ah,0dh,0ah,0dh,0ah,0dh,0ah,0dh DB ' * *',0DH,0AHDB ' * *',0DH,0AHDB ' * *',0DH,0AHDB ' * *',0DH,0AHDB ' * *',0DH,0AHDB ' * * * * * * * * * * * * * * * * * * * *','$'MSG1 DB 'choose +,-','$'MSG2 DB 'you choose wrong','$',0AH,0DHMSG3 DB 'Press ESC to Exit!',0DH,0AH,'$'MSG4 DB 'Press any key to continue!',0DH,0AH,'$'MSG5 DB '-','$'MSG6 DB '.','$'MSG7 DB 'error input!','$'MSG8 DB 'data2 is wrong!','$'DATA1 DW ?DATA2 DW ?.CODE ;代码段从这里开始;--------------------------------------------DEC_DIV PROC NEARCWD ;将字转换为双字,AX内容符号扩展到DXDIV CXPUSH DXMOV DL,ALADD DL,30H ;将不是数字的字符转换为数字MOV AH,2 ;显示输出INT 21H ;DOS调用POP DXMOV AX,DXRETDEC_DIV ENDP;------------------------------------------CHANGE PROC NEAR ;该子程序的功能:将AX中存储的十六进制数转换为十进制数CMP AX,1000JAE C1 ;AX≥1000则转移CMP AX,100JAE C2 ;AX≥100则转移CMP AX,10JAE C3 ;AX≥10则转移JMP C4 ;AX<10C1: MOV CX,1000DCALL DEC_DIVC2: MOV CX,100DCALL DEC_DIVC3: MOV CX,10DCALL DEC_DIVC4: MOV CX,1DCALL DEC_DIVRETCHANGE ENDP;-------------------------------BEGIN PROC NEARBACK: CLEAR 1EHCURS 2,20 ;设置光标为(2.20)DISPMSG MSG0 ;显示用户界面CURS 8,41 ;设置光标为(8,41),第一行MOV BX,0MOV CX,2NEWCHAR1:MOV AH,1 ;键盘输入并回显INT 21H ;DOS调用CMP AL,30H ;检查输入的字符是不是数字JAE J1 ;如果不是,则转移至J1JMP D2 ;是,转移到D2执行J1: CMP AL,39H ; 与9的ASCII侣氡JBE J2 ;如果输入的字符是0-9,则转移至J2 JMP D2 ;如果不是数字,则转移至D2J2: SUB AL,30HCBW ;AL的内容符号扩展到AHXCHG AX,BXMOV DI,10MUL DIXCHG AX,BXADD BX,AXLOOP NEWCHAR1MOV DATA1,BXCURS 11,41 ;设置光标位为(11,40),第二行MOV BX,0MOV CX,2NEWCHAR2:MOV AH,1 ;键盘输入并回显INT 21H ;DOS调用CMP AL,30H ;与0的ASCII码比较JAE J3 ;如果输入数字大于等于0则跳转至J3 JMP D2J3: CMP AL,39H ;与9比较JBE J4 ;如果小于或等于9则跳转JMP D2 ;如果输入不是数字则跳转J4: SUB AL,30H ;如果输入不是0-9,则转化成相应的字符CBW ;将AL符号扩展到AHXCHG AX,BXMOV DI,10MUL DIXCHG AX,BXADD BX,AXLOOP NEWCHAR2MOV DATA2,BXMOV AX,DATA1MOV BX,DATA2PUSH AXPUSH BXCURS 15,33 ;设置光标的位置为(15.33),第三行DISPMSG MSG1 ;显示提示信息MOV AH,1 ;接受键盘输入并回显INT 21H ;DOS调用CMP AL,'+'JE ADDI ;如果运算符为+,则计算两数之和CMP AL,'-'JE SUBT ;如果运算符为-,则计算两数之差CURS 16,25 ;设置光标为(16,25)DISPMSG MSG2 ;在屏幕上输出提示信息JMP D1;----------------------------------------;ADD THE TWO DATASADDI: POP BXPOP AXADD AX,BX ;计算两数字之和PUSH AXCURS 14,41 ;设置光标位置为(14,41)POP AXCALL CHANGE ;将结果转换为十进制数JMP D1;---------------------------------------;SUBTRACT THE TWO DATASSUBT: POP BXPOP AXCMP AX,BX ;比较两数大小JAE D0 ;如果AX>=BX则跳转XCHG AX,BXPUSH AXPUSH BXCURS 14,40 ;设置光标位置为(14,40)DISPMSG MSG5 ;在屏幕上显示负号POP BXPOP AXD0: SUB AX,BX ;计算两数之差PUSH AXCURS 14,41 ;设置光标位置为(14,41)POP AXCALL CHANGE ;将结果转换为十进制数JMP D1;---------------------------------------D1: RETD2: PUSH AXPUSH BXCURS 15,33 ;设置光标位置为(15,33)DISPMSG MSG7 ;提示输入出错POP BXPOP AXRETBEGIN ENDP;----------------------------------------MAIN PROC NEARMOV AX,@DATAMOV DS,AXMOV ES,AXPUSH DSXOR AX,AXPUSH AXMOV DATA2,0 ;将缓冲区清空MOV DATA1,0AGAIN:CALL BEGINCURS 16,23 ;设置光标位置为(16.23)DISPMSG MSG3 ;在屏幕上输出提示信息,提示退出的方法CURS 17,23 ;设置光标位置为(17.23)DISPMSG MSG4 ;在屏幕上输出提示信息,提示继续的方法MOV AH,7 ;键盘输入,无回显INT 21H ;DOS调用CMP AL,27 ;判断输入的是否为ESCJNE AGAIN ;如果不是就继续执行以上运算EXIT: MOV AX,4C00H ;如果是就退出系统INT 21H ;DOS调用MAIN ENDPEND MAIN4.2 对源程序汇编生成目标文件4.3 链接目标文件生成可执行文件“12.EXE”,并用DEBUG命令调试程序4.4 运行最终可执行程序“12.EXE”,执行结果:5 使用说明打开可执行文件“十进制加减计算器.exe”,键盘输入需要运算的两个十进制数,然后小键盘选择运算符号,则程序自动运算两个数并输出结果,并提供选择“ESC退出”、“任意键继续”。
单片机用矩阵按键实现进制转换摘要十进制的加减乘除带符号和小数需要:0~9十个按键+加减乘除四个按键+加小数点符号两个按键=共16个按键。
不同进制之间转换需要:0~F十六个按键+2、8、10、16进制四个按键=共20个按键。
进制之间加减乘需要:0~F十六个按键+2、8、10、16进制四个按键+加减乘三个按键=共23个按键。
这些还不算上回撤键和模式选择等按键。
所以设计的时候必须考虑好按键。
我就得出来如下方案:
用独立按键做为模式选择:三个按键,选择模式之后不能返回,如果要返回可以用复位键。
这样几个功能之间相互不联系,没有影响,按键就够用了。
十进制的加减乘除带符号和小数:用4x4按键做出来键盘既7、8、9、+、4、5、6、-、1、2、3、*、退格、0、=、/、用两个独立按键做小数点和符号按键。
不同进制之间转换:4x4按键做0~F既0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F,独立按键四个做进制选择既2、8、10、16进制。
进制之间加减乘:4x4按键做0~F既0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F,独立按键四个做进制选择既2、8、10、16进制,独立按键四个做加减乘。
单片机十进制加法计算器设计设计概述:1.输入部分设计为了实现数字输入功能,可以采用4x4矩阵键盘作为输入设备。
通过扫描键盘矩阵,可以检测用户按下的按键,并将相应的按键字符存储在单片机内部的缓冲区中。
键盘扫描需要使用外部中断或定时器中断,在按键被按下时触发中断程序进行扫描和存储。
2.计算部分设计为了进行数字加法运算,需要在单片机中定义变量来存储输入的数字,并使用适当的算法进行加法运算。
加法运算可以通过逐位相加的方式实现,先对个位数进行加法运算,再对十位数进行加法运算,以此类推,直到最高位数。
3.显示部分设计为了显示运算结果,可以使用数码管来显示数字。
数码管的选型可以选择共阳极或共阴极的数码管,具体选择要根据实际的需求和电路设计来确定。
单片机需要通过IO口控制数码管的显示,将运算结果转化为相应的数码管段码,并通过IO口输出给数码管进行显示。
4.输出部分设计为了实现结果的输出,可以选择将结果通过串口发送给上位机,或者通过并行接口输出给其他设备。
具体的接口选择要根据实际的需求和电路设计来确定。
设计步骤:1.确定硬件平台和单片机型号,根据单片机的外设资源选择合适的输入、输出和显示设备。
2.进行电路设计,包括键盘输入电路、按键检测电路、数码管显示电路和外部接口电路。
3.编写单片机的初始化程序,包括IO口初始化、定时器中断初始化和中断服务程序编写。
4.编写键盘扫描程序,实现对键盘输入的检测和字符存储。
5.编写数字加法运算程序,实现输入数字的加法运算和结果的存储。
6.编写数码管显示程序,将加法运算结果转化为数码管的段码并进行显示。
7.编写输出程序,将结果通过串口或并行接口输出给上位机或其他设备。
8.进行调试和测试,优化程序和电路设计,确保计算器的稳定性和准确性。
9.编写用户界面程序,实现菜单、输入和输出操作的交互。
设计思路:利用单片机的运算和控制能力来实现数字加法的功能,以实现单片机十进制加法计算器的设计。
通过键盘输入,将数字存储在单片机内部的变量中,并采用逐位相加的算法实现数字加法运算。
十进制加法器引言十进制加法器是一种用于实现十进制数字相加的电路或程序。
在计算机科学和数字电路设计中,十进制加法器是一项重要的基础技术。
本文将介绍十进制加法器的原理、实现方法以及应用领域。
原理十进制加法器的原理是根据十进制加法规则,将两个十进制数的各位依次相加,并将进位传递到下一位上。
具体步骤如下:1.从个位开始,将两个加数的个位相加,得到个位的和以及进位;2.将两个加数的十位和上一步的进位相加,得到十位的和以及进位;3.重复上述步骤,直到所有位上的数字相加完成。
实现方法1. 数字电路实现十进制加法器可以通过数字电路来实现。
常用的实现方法有传统的加法器和带有进位预测(Carry Look Ahead)的加法器。
传统的十进制加法器由10个全加器(Full Adder)组成,其中每个全加器用于相加两位数的一个位以及传递进位。
全加器的输入包括两个加数和上一位的进位,输出包括该位的和以及进位。
带有进位预测的十进制加法器通过预测进位的方式,减少了计算过程中需要的级数和门延时,从而提高了运算速度。
这种加法器通过先计算进位的状态,然后再求和,实现了进位和求和两个部分的并行计算。
2. 数字模拟实现除了数字电路外,十进制加法器还可以通过计算机程序来实现。
使用编程语言如C、C++、Python等编写程序,可以模拟实现十进制加法器的功能。
在程序中,加数和被加数通常被表示为数组形式,每个元素代表一位数字。
通过循环迭代相加各位,并考虑进位的情况,可以得到相加的结果。
3. 软硬件结合实现在实际应用中,十进制加法器常常通过软硬件结合的方式来实现。
利用FPGA(Field Programmable Gate Array)等可编程硬件,可以灵活地设计和实现十进制加法器的功能。
通过编写硬件描述语言(HDL)如Verilog或VHDL来描述加法器的原理和功能,然后通过FPGA编程工具进行编译和实现。
这种方法可以同时发挥硬件的并行计算能力和软件的灵活性。
十进制的加法在数学运算中,加法是我们最常见的一种算术运算。
而在我们日常生活中所使用的数字系统,多数都是采用了十进制(即基数为10)的数字系统。
因此,对于十进制的加法来说,我们需要掌握相应的规则和方法。
1. 加法的基本原理十进制的加法是指将两个或多个十进制数相加得到一个结果的过程。
我们将加法分为两个步骤:竖式加法和进位处理。
2. 竖式加法竖式加法是我们最常见的计算方式,它以十进制的方式对齐数字,并逐位相加。
下面是一个例子:45+ 28------73在这个例子中,我们先从个位开始,4加8得到12。
由于12大于10,我们需要进行进位操作,将2留在个位上,将1进到十位上。
然后我们继续将十位上的数相加,得到5加2再加1等于8。
最后,我们得到的结果是73。
3. 进位处理在十进制加法中,当两个数的对应位上的和大于等于10时,我们需要进行进位处理。
进位处理是指将进位的数加到更高一位上的操作。
例如,在前面的例子中,我们在个位上的加法中得到的结果是12,超过了10。
因此,我们需要将十位上的1进位到百位上。
4. 零的运用在进行竖式加法运算时,我们经常会遇到一位数加上零的情况。
这种情况下,结果就等于该位上的数本身。
例如,在下面的例子中: 43+ 60------103我们可以看到,个位上的3加上零等于3,十位和百位上的数字保持不变。
这种情况下,我们可以直接将零省略,不需要写出来。
5. 进位的扩展在较长的十进制加法中,进位的扩展是必不可少的。
当我们计算一个多位数的加法时,需要把位数对齐,并且将进位一直传递到最高位。
下面是一个例子:789+ 516------1305在这个例子中,我们从个位开始相加,得到5加9等于14。
我们将4留在个位上,1进位到十位上。
然后,我们将十位上的数相加,得到1加8再加1等于10。
同样地,我们将零留在十位上,将1进位到百位上。
最后,我们得到的结果是1305。
6. 超过十进制的进位当我们进行十进制加法时,也会遇到超过十进制的进位情况。
十进制数的加减法在数学中,十进制数是使用10个数字(0-9)来表示数值的一种方法。
而加法和减法是数学中最基本的运算之一。
本文将详细介绍十进制数的加减法运算。
一、十进制数的加法1. 加法的基本原理十进制数的加法是将两个或多个数值相加,得到它们的和。
加法的基本原理是将对应位上的数字相加,并将结果从右往左逐位写出。
如果相加的两个数的对应位上的数字之和大于等于10,就需要进位。
2. 加法的步骤(1)将加数垂直地写在被加数下面,保持各个位对齐。
(2)从最右边一位开始逐位相加。
(3)如果某一位的和大于等于10,则将进位写在上一位的左边,并在当前位上写下本位的和减去10的结果。
(4)重复以上步骤,直到所有位数相加完毕。
例如,计算1234 + 5678的和:```1234+ 56786912```二、十进制数的减法1. 减法的基本原理十进制数的减法是从一个数中减去另一个数,得到它们的差。
减法的基本原理是从左到右逐位相减,并将结果从右往左逐位写出。
如果被减数的某一位小于减数的对应位,则需要向上一位借位。
2. 减法的步骤(1)将减数写在被减数的上面,保持各个位对齐。
(2)从最右边一位开始逐位相减。
(3)如果被减数的某一位小于减数的对应位,则需要向上一位借位。
(4)在当前位上写下被减数的数字加上10,再减去对应位上减数的数字。
(5)重复以上步骤,直到所有位数相减完毕。
例如,计算9876 - 5432的差:```9876--------4444```三、小结十进制数的加减法是数学中最基本的运算之一。
通过将对应位上的数字相加或相减,我们可以计算出数值的和或差。
在进行加减法运算时,需要注意进位和借位的问题。
通过练习和熟练掌握加减法的步骤和原理,我们可以更加准确地计算出十进制数的加减结果。
本文简要介绍了十进制数的加减法运算的基本原理和步骤,希望对您有所帮助。
通过不断练习和实践,您将能够更加熟练地进行十进制数的加减运算,提升您的数学能力。
利用键盘控制点阵进行十进制加法计算显示1、课程设计目的:(1)学习操作数字电路设计实验开发系统,掌握点阵显示模块的工作原理及应用。
(2)掌握组合逻辑电路、时序逻辑电路的设计方法。
(3)学习掌握可编程器件设计的全过程。
2、课程设计容和要求:2.1、设计容:用VHDL语言编写程序,编写键盘控制模块的控制逻辑,仿真所编写的程序,模拟验证所编写的模块功能,下载程序到芯片中,实现键盘控制点阵进行十进制加法计算显示。
2.2、设计要求:(1)学习掌握键盘控制模块、点阵显示模块的工作原理及应用;(2)熟练掌握VHDL编程语言,编写键盘控制模块的控制逻辑;(3)仿真所编写的程序,模拟验证所编写的模块功能;(4)下载程序到芯片中,硬件验证所设置的功能,能够实现十进制数字的显示;(5)整理设计容,编写设计说明书。
3、设计方案及实现情况:3.1、设计思路:分三个模块编写程序,首先实现键盘对点阵的控制,然后设计加法计算功能模块,由于点阵显示的局限性,当有进位时设置CO为高电平在数码管上显示出来,在最后一个模块编写显示的1到9以及加号的列字符扫描信号,从而实现键盘控制点阵十进制加法计算的显示。
3.2、工作原理及框图:系统的输入信号有:开关(允许输入及显示)信号RST,系统时钟信号CLK,按键信号(KEYIN[3..0])。
系统的输出信号有:点阵行驱动输出信号(LEDOUT[0..15]),点阵列选信号(SEL[3..0]),进位输出信号CO。
系统的工作过程为:在开关信号RST(低电平有效)为低电平时,矩阵键盘不工作,16×16点阵没有显示;当开关信号RST为高电平时,整个系统工作,当在矩阵键盘上按下按键后,16×16点阵会显示出一个1位十进制数,在进行功能操作时,当按下NEXT键时,点阵上显示“+”号,然后再按下一个十进制数在点阵上显示,最后按下ENTER键进行加法计算,如果结果大于9,则进位输出CO输出高电平,点亮发光二极管,点阵显示个位,否则直接输出结果。
LED点阵显示原理:LED点阵式显示器不仅可以显示数字,也可显示所有西文字母和符号,与由单个发光二极管连成的显示器相比,具有焊点少、连线少,所有点在同平面、亮度均匀、外形美观以及具有显示信息丰富、功耗低、体积小、重量轻、超薄等许多其他显示器无法比拟的优点,可以代替数码管、符号管和米字管。
如果将多块组合可以构成大屏幕显示屏用于汉字、图形、图表等等的显示,因此被泛用于机场、车站、码头、银行及许多公共场所的指示、说明、广告等场合。
16×16的LED点阵显示器,是由256个LED组成,共阳极的16×16的LED点阵显示器的典型连接方式是:每一行的16个阳极连在一起,由行扫描码锁存器和驱动器的一位控制,总共16行阳极连线由16位分别控制;每一列的16个阴极连在一起,由列扫描码锁存器和驱动器的一位控制,总共16列阴极连线由16位分别控制。
点阵字符的驱动过程:点阵式LED显示器采用逐行扫描式工作。
要使点阵显示出一个字符的编程方法是:首先选通第一行;接着,向行码锁存器写入该行的字型码(即列数据)。
然后,按相同的方式选通第二行,写第二行的字型码……由此类推,直到写完所有行的字型码,完成一个字符的显示。
16×16点阵显示驱动的行选通信号为一4-16译码器的输出,所以我们在设计点阵控制接口时,其行选通信号输出必须经4-16编码。
矩阵式键盘的工作原理:矩阵式键盘又叫行列式键盘,是用I/O口线组成的行、列矩阵结构,在每根行线与列线的交叉处,二线不直接相通而是通过一个按键跨接接通。
采用这种矩阵结构只需M根行输出线和N根列输入线,就可连接M×N个按键。
通过键盘扫描程序的行输出与列输入就可确认按键的状态,再通过键盘处理程序便可识别键值。
矩阵式键盘的按键识别方法为行扫描法又称为逐行扫描查询法,是一种最常用的按键识别方法,介绍过程如下:1)判断键盘中有无键按下:将全部行线置低电平,然后检测列线的状态。
只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与行线相交叉的按键之中。
若所有列线均为高电平,则键盘中无键按下。
2)判断闭合键所在的位置:在确认有键按下后,即可进入确定具体闭合键的过程。
其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。
在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。
若某列为低,则该列线与低电平的行线交叉处的按键就是闭合的按键。
键盘中的按键可分为数字键和功能键。
数字键主要用来输入数字,但从上述容发现,键盘所产生的输出KIN3~KIN0无法拿来直接使用;另外不同的数字按键也担负不同的功能,因此必须由键盘译码电路来规划某个按键的输出形式,以便执行相应的动作。
图1 总体框图3.3 、各模块功能描述:键盘扫描模块:实验箱中4×8矩阵键盘的电路原理图如图2所示图2 矩阵键盘的电路原理图该矩阵键盘的工作原理为:扫描信号为BCOM[8..1],在BCOM[8..1]前已接有一个3-8译码器,3-8译码器的输入为SEL0~SEL2。
当3-8译码器的输入为‘000’时,即BCOM1为‘0’,其他位为‘1’,我们按下第一排第一键,此时KIN0输出‘0’,KIN1~KIN3输出全为‘1’,按下第二排第二键时,KIN1输出‘0’,其他输出‘1’;当3-8译码器输入为‘001’时,即BCOM2为‘0’,我们按下第一排第一键,此时KIN0输出‘0’,KIN1~KIN3输出全为‘1’,同理其他键依此类推。
键盘上的每个按键就是一个开关,当某键被按下时,该按键的接点会呈现‘0’状态,反之为‘1’。
扫描信号为SEL[2..0]进入3-8译码器,再从译码器输出到键盘,所以第一次只能扫描一排,依此周而复始。
若从KIN[3..0]输出的皆为‘1’时,表示没有按键按下,代表该列没有按键被按下,则不进行按键编码的操作,反之,如果有被按下时,则应将KIN[3..0]读出的值送到译码电路进行编码。
按键位置与数码的关系如下表1所示:表1 按键位置与数码关系表的模块中的p3进程依据上表描述了按键位置与数码的关系,实现了键盘输入输出的功能。
KOUT[4..0]为键盘扫描后的对应的译码输出;CP为时钟CLK的四分频后的输出;Q[1..0]对按下的键值进行标志:“00”表示按下‘0’——‘9’之间的键值、“01”表示按下NEXT按键、“10”表示按下ENTER 按键、“11”表示按下其它按键。
键盘控制模块如图3所示。
图3 键盘控制模块图源程序:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity keyboard isport (clk ,rst : in std_logic;kin : in std_logic_vector (3 downto 0);cp : out std_logic;q : out std_logic_vector (1 downto 0);sel : out std_logic_vector (3 downto 0);kout : out std_logic_vector (4 downto 0));end keyboard;architecture keyboard_arc of keyboard issignal counter : std_logic_vector(3 downto 0);signal counter1 : std_logic_vector(1 downto 0); signal counter2 : std_logic_vector(4 downto 0); signal colsel,Y : std_logic_vector(4 downto 0); signal clk1,ktest,kdown: std_logic;signal a : std_logic_vector(3 downto 0); signal b : std_logic_vector(2 downto 0);beginktest<=kin(3) and kin(2) and kin(1) and kin(0);p1: process(rst,clk)beginif(rst='0') thencounter1<="00";elsif(clk'event and clk='1') thencounter1<=counter1+1;end if;end process p1;clk1<='0' when counter1<="01" else'1';cp<=clk1;p2: process(rst,clk1,ktest)beginif(rst='0') thencounter<="0000";elsif(clk1'event and clk1='1') thenif(ktest='0') or (kdown='0') thencounter<=counter;elsecounter<=counter+1;end if;end if;end process p2;sel<=counter;p3:process(clk,ktest)begina<=kin;b<=counter(2) & counter(1) & counter(0);case b iswhen "000"=>case a iswhen "1110"=>Y<="00000"; when "1101"=>Y<="00110";when "1011"=>Y<="11111";when "0111"=>Y<="11111";when others=>null;end case;when "001"=>case a iswhen "1110"=>Y<="00001"; when "1101"=>Y<="00111";when "1011"=>Y<="11111";when "0111"=>Y<="11111";when others=>null;end case;when "010"=>case a iswhen "1110"=>Y<="00010";when "1101"=>Y<="11111";when "1011"=>Y<="11111";when "0111"=>Y<="11111";when others=>null;end case;when "011"=>case a iswhen "1110"=>Y<="00011";when "1101"=>Y<="11111";when "1011"=>Y<="11111";when "0111"=>Y<="11111";when others=>null;end case;when "100"=>case a iswhen "1110"=>Y<="11111";when "1101"=>Y<="01000";when "1011"=>Y<="11111";when "0111"=>Y<="11111";when others=>null;end case;when "101"=>case a iswhen "1110"=>Y<="11111";when "1101"=>Y<="01001";when "1011"=>Y<="11111";when "0111"=>Y<="11111";when others=>null;end case;when "110"=>case a iswhen "1110"=>Y<="00100";when "1101"=>Y<="11111";when "1011"=>Y<="10000";when others=>null;end case;when "111"=>case a iswhen "1110"=>Y<="00101";when "1101"=>Y<="11111";when "1011"=>Y<="10001";when others=>null;end case;when others=>null;end case; end process p3;p4: process(ktest,clk,rst)beginif(rst='0') thencounter2<="00000";kdown<='1';elsif(clk'event and clk='1') thenif(ktest='0') thencounter2<="00000";kdown<='0';elsif(counter2<"11110") thencounter2<=counter2+1;if(counter2="11100") thenkdown<='1';end if;end if;end if;end process p4;p5: process(kdown,rst)beginif(rst='0') thencolsel<="00000";elsif(kdown'event and kdown='1') thenif(Y<"10000")thenq<="00";colsel<=Y;elsif(Y="10000")thenq<="01";elsif(Y="10001")thenq<="10";elsif(Y="11111")thenq<="11";end if;end if;end process p5;kout<=colsel;end keyboard_arc;点阵显示模块:16×16点阵显示,各驱动接口为:第一行到第十六行对应的为L0~L15,第一列到第十六列驱动采用4-16译码,对应的接口为SEL0~SEL3。