计算机科学与技术学院硬件课程设计报告姓名:学号:专业:计算机科学与技术班级:计科班设计题目:电子计算器成员:指导教师:职称:年月课程设计指导教师评阅书指导教师评语:成绩:指导教师签字:年月摘要电子计算器的设计主要分为键盘扫描与读取编码、七段LED数码管显示和四则运算的编写。
这次设计中我们采用可编程接口芯片8255链接4*4键盘和LED显示屏,从键盘扫描读入数字,在显示屏上面显示出来,并通过cpu运算出结果显示在屏幕上。
由于对汇编语言也不甚了解,只是进行一些简单的自然数的四则运算。
由于本次实验中,实验箱是TPC-ZK综合微机开放式实验系统,微机接口实验仪采用模块化、积木式的结构,各实块互不影响。
但可通过连线将各实验模块有机组合起来,进行微机外围接口实验。
这个实验选择的是4*4键盘连接上8255A然后控制LED显示。
关键词:8255A ;七段LED数码管;键盘;汇编语言;四则运算目录1 设计任务与要求 (3)1.1选题 (3)1.2需求分析 (3)1.3设计任务 (3)2硬件方案 (3)2.1微处理器8086芯片 (3)2.2 可编程并行接口8255A芯片 (4)2.3 4*4矩阵键盘 (6)2.4 七段LED数码管 (7)2.5 电路及其功能模块图 (8)3软件方案 (10)3.1流程图 (10)3.2源程序代码 (11)4 问题与解决方案 (26)5 成果展示 (26)6 总结 (27)7 心得体会与收获 (27)8参考文献 (27)1 设计任务与设计要求1.1选题我选的题目是电子计算器,电子计算器的设计主要分为键盘编码、七段数码管显示、和四则运算法则这三部分。
设计时用可编程接口芯片8255A链接4*4键盘和七段LED数码管,8255扫描键盘并通过数码管显示相应的数字,这其中需要一定的汇编程序作为核心支撑,才能正确的使各种功能运行正常。
1.2需求分析通过对选题的深入了解,电子计算器基本功能可以概括为:1.可以进行简单的加、减、乘、除四则运算;2.为了显示的人性化,按下每个数字都要进行反馈显示;3.数码管只有四位显示,运算数和结果应尽量小于四位数,不然显示不全;4.计算器能判断个别简单的错误,如除数为零,显示报错;5.计算器要有清零功能,可以在按键失误后重新按键。
在显示屏上可以及时反馈按下数字,这需要扫描程序模块一直运行着,并能够及时调用显示程序模块,当有运算符号按下时还要及时给之前按下的数字进行组装成一个数值,组装键值模块也是程序的重要所在。
等等这些都是在主程序下合理安排、运用流畅的,才能带来较完美的计算器体验。
1.3设计任务本次实验我分为电路设计和编码设计这两个任务模块来设计的。
电路设计主要研究键盘按键位置设计和各个芯片器件之间的连线。
编码设计主要分为键盘扫描读取编码、七段数码管显示编码和四则运算编码。
2 硬件方案2.1微处理器8086芯片当引脚接高电平时,CPU工作于最小模式。
此时,引脚信号24~31的含义及其功能如下:(1)IO/M:存储器、I/O端口选择控制信号。
信号指明当前CPU是选择访问存储器还是访问I/O端口。
为高电平时访问存储器,表示当前要进行CPU与存储器之间的数据传送。
为低电平时,访问I/O端口,表示当前要进行CPU与I/O端口之间的数据传送。
(2)WR:写信号,输出,低电平有效。
信号有效时,表明CPU正在执行写总线周期,同时由信号决定是对存储器还是对I/O端口执行写操作。
(3)INTA:可屏蔽中断响应信号,输出,低电平有效。
CPU通过信号对外设提出的可屏蔽中断请求做出响应。
为低电平时,表示CPU已经响应外设的中断请求,即将执行中断服务程序。
(4)ALE:地址锁存允许信号,输出,高电平有效。
CPU利用ALE信号可以把AD15 ~AD0地址/数据、A19/S6~A16/S3地址/状态线上的地址信息锁存在地址锁存器中。
(5)DT:数据发送/接收信号,输出,三态。
DT/信号用来控制数据传送的方向。
DT/为高电平时,CPU发送数据到存储器或I/O端口;DT/为低电平时,CPU接收来自存储器或I/O端口的数据。
(6)DEN:数据允许控制信号,输出,三态,低电平有效。
信号用作总线收发器的选通控制信号。
当为低电平时,表明CPU进行数据的读/写操作。
(7)HOLD:总线保持请求信号,输入,高电平有效。
在DMA数据传送方式中,由总线控制器8237A发出一个高电平有效的总线请求信号,通过HOLD引脚输入到CPU,请求CPU让出总线控制权。
(8)HLDA:总线保持响应信号,输出,高电平有效。
HLDA是与HOLD配合使用的联络信号。
在HLDA有效期间,HLDA引脚输出一个高电平有效的响应信号,同时总线将处于浮空状态,CPU让出对总线的控制权,将其交付给申请使用总线的8237A控制器使用,总线使用完后,会使HOLD信号变为低电平,CPU又重新获得对总线的控制权。
2.2 可编程并行接口8255A芯片8255A可为8086微处理器与外部设备之间提供并行输入/输出的通道。
通过编程可以设置芯片的工作方式,因此,用8255A连接外部设备时,通常不用再附加外部电路。
并行接口是在多根数据线上,以数据字节/字与I/O设备交换信息。
在输入过程中,输入设备把数据送给接口,并且使状态线“输入准备好”有效。
接口把数据存放在“输入缓冲寄存器”中,同时使“输入回答”线有效,作为对外设的响应。
外设在收到这个回答信号后,就撤消数据和“输入准备好”信号。
数据到达接口中后,接口会在“状态寄存器”中设置输入准备好标志,或者向CPU 发一个中断请求。
CPU可用查询方式或中断方式从接口中读取数据。
接口中的数据被读取后,接口会自动清除状态寄存器中的标志,且撤消对CPU的中断请求。
在输出过程中,每当输出寄存器可以接收数据,接口就会将状态寄存器中“输出准备好”状态置1或向CPU发一个中断请求,CPU可用查询或中断方式向接口输出数据。
当CPU输出的数据到达接口后,接口会清除“输出准备好”状态,把数据送往外设,并向外设发一个“数据输出准备好”信号。
外设受到驱动后,便接收数据,并向接口电路发一个“输出回答”信号,接口收到该回答信号后,又将状态寄存器中“输出准备好”置位,以便CPU输出下一个数据。
(1)8255A的一些引脚RESET:复位输入线,当该输入端外于高电平时,所有内部寄存器(包括控制寄存器)均被清除,所有I/O 口均被置成输入方式。
PA0~PA7:端口A 输入输出线,一个8 位的数据输出锁存器/缓冲器,一个 8 位的数据输入锁存器。
PB0~PB7:端口B 输入输出线,一个8 位的I/O 锁存器,一个 8 位的输入输出缓冲器。
PC0~PC7:端口C 输入输出线,一个8 位的数据输出锁存器/缓冲器,一个 8 位的数据输入缓冲器。
端口C 可以通过工作方式设定而分成2 个4 位的端口,每个 4 位的端口包含一个4 位的锁存器,分别与端口A 和端口B 配合使用,可作为控制信号输出或状态信号输入端口。
CS:片选信号线,当这个输入引脚为低电平时,表示芯片被选中,允许8255 与CPU 进行通讯。
图2-1 8255A管脚图RD:读信号线,当这个输入引脚为低电平时,允许8255 通过数据总线向CPU 发送数据或状态信息,即CPU 从8255 读取信息或数据。
WR:写入信号,当这个输入引脚为低电平时,允许CPU 将数据或控制字写8255。
D0~D7:三态双向数据总线,8255 与CPU 数据传送的通道,当CPU 执行输入输出指令时,通过它实现8 位数据的读/写操作,控制字和状态信息也通过数据总线传送。
(2)8255A的读写控制:8255A的读/写控制逻辑电路接受CPU 发来的控制口号RD、WR、RESET 和地址信号A1~A0。
然后根据命令端口,控制信号的要求,将端口的数据读出选信CPU 或者将CPU送来的数据写入端口,各端口的工作状态。
通过用输出指令对8255A 的控制字寄存器编程,写入设定工作方式的控制字,可以让3个数据口以不同的方式工作,端口A 可工作于3 种方式的任一种,端口B 只能工作于方式0 和方式1,端口C 除了用于输入输出端口外,还能配合A 口和B 口工作,为这两个端口的输入输出操作提供联系信号。
图2-2 8255A控制字本次设计实验采用的控制字是10010000,A口输入、B口输出、C口输出。
2.3 4*4矩阵键盘键盘是信息输入元件,由一个个按钮组成,如果是独立按钮的话必须要需要一个I/O口对它进行检测。
因为4×4矩阵键盘有8个管脚,为了扫描键盘判断键值的方便将八个管脚中的列接PA和行接PC。
因为进行键盘扫描一般要求有一部分的I/O口的工作方式是输入,另一部分I/O是输出,具体到4×4键盘则要求4个I/O 口输入,另外4个输出,这一点PC口刚好符合,低四位接行作为键盘I/O输入,PA低四位接列作为键盘I/O输出。
键盘有16个按键,我们设计为0~9为数字键,ABCD分别为+、-、*、/,E为=号,F为清零键CL。
识别键盘上哪个键被压下的过程的扫描步骤:1.检测是否所有键都都松开了,若没有则反复检测。
2.但所有键都松开了,再检测是否有键压下,若无键按下则反复检测。
3.如有键压下,要消除键抖动,确认有键压下。
4.对压下的键位置进行判断,先判断是第几行有键按下,再判断第几列有键按下,键值=行号*4+列号。
至此确定了哪个键按下,再接着进行后面的操作。
0 1 2 34 5 6 78 9 + -* / = CL图2-3 4*4矩阵键盘表2-1 键盘设计2.4 七段LED数码管LED由7个字符段和一个小数点段组成,每段对应一个发光二极管,当发光二极管点亮时,相应的字符段点亮。
LED有共阴极和共阳极两种供应状态。
共阴极显示时,将LED显示的COM接地,将八个字符段端a、b、c、d、e、f、g、dp依次与一个8位I/O口的最低到最高位连接,当I/O给LED的哪个字符段送入一个高电平时,该段就被点亮,从而可从这7个字符段中被点亮的构成相应的字符显示出来。
同理,COM阳极即将COM端接Vcc,其显示原理与COM阴极的基本相同,但I/O口送入低电平是相应的段才被点亮。
图2-4七段数码管实物图图2-5 数码管管脚图表2-2 数码管显示数字对应表2.5 电路及其主要功能2.5.1 电路连接实物图图2-6 电路实物图2.5.2实验电路图图2-7 电路实验模拟图2.5.3 功能模块图图2-8 功能模块图3 软件方案3.1 流程图3.1.1键盘扫描流程图图3-9 扫描流程图3.1.2 计算器运算流程图图3-10 运算流程图3.2 程序源代码port_a equ 280Hport_b equ 281Hport_c equ 282Hport_ctl equ 283Hdata segmentx db 0,0,0,0; 存放数据的每一位x1 dw ?; 存放第一个数据值x2 dw ?; 存放第二个数据值y dw ?; 存放结果s db ?; 存放运算符号e db ?; 按下等号键标记cc db ?; 存放运算数据位数h db 0; 存放行号l db 0; 存放列号discode db 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H,40H,;段码表,最后一个是负号data endscode segmentassume cs:code,ds:datastart: mov ax,datamov ds,axmov al,90h ;A口输入 B口输出 C口输出 10010000B即mov dx,port_ctlout dx,almov di,offset x+3; di指向X[3]kkk:call key; 扫描按键jmp kkk;key proc ;按键扫描子程序,程序返回后,在变量H和L中存放当前按键的行列号check:call disp; ;等待按键,按下的同时进行显示mov al,10h; ;PC0-PC3对应行号,输出低电平mov dx,port_cout dx,almov dx,port_ain al,dx ;读列值,即PA0-PA3的值and al,0fhcmp al,0fh;jz check ;ZF=1,即运算结果为0,相等,都为高电平则无键按下,等待mov cx,50loop $; ;消除键抖动in al,dx; ;重复读列值and al,0fhcmp al,0fhjz check; ;若无键按下则一直等待mov h,0; ;有键按下,先把行列号清0mov l,0mov bl,01hmov bh,0feh; ;扫描键值,从第一行开始检测,PC0输出低电平next:mov al,bhmov dx,port_cout dx,alnextl:mov dx,port_ain al,dx; 读列值,判断第几列有键按下test al,bl; 判断是否是第1列jz waito ;是则跳转rol bl,1 ;左移一位cmp bl,10h; 当前行状态下没有任何列有键按下,则转为对下一行的测试jz nexthinc l; ;每判断一列,列号加1jmp nextl; 再对下一列进行判断nexth:mov l,0mov bl,01hrol bh,1;cmp bh,0efhjz exitinc hjmp nextwaito:mov dx,port_a ;若有键按下,则等该键松开后再计算键值in al,dx;and al,0fhcmp al,0fhjnz waitocall keyvalue; 调计算键值子程序exit:retkey endp;keyvalue proc ;计算键值子程序,通过行列号计算键值(键值=行号*4+列号)mov dl,h ;键值存放在DL寄存器中mov dh,lxor ax,axmov al,4mul dlmov dl,aladd dl,dhcmp dl,9jng num_call ;小于等于,则转移即按下的是数字键cmp dl,14jl cont_call; ;大于9小于14,即加减乘除的时候,运算键cmp dl,14 ;等于15,即等于键jz outp_call;cmp dl,15jz clr_call; ;按下清零键num_call:call number;调用数字键处理子程序jmp exit1cont_call:mov s,dl; 存放运算键的键值mov e,0call count; 调用运算键处理子程序,计算jmp exit1outp_call:call outp; 调用等号键处理子程序jmp exit1clr_call:call clear; 调用清除键处理子程序exit1:retkeyvalue endp;clear proc ;一下为清除键处理子程序,按下清除键后,X变量全部清0mov x[3],0mov x[2],0mov x[1],0mov x[0],0call bitpcall dispcall dely ;分析数据位数retclear endp;outp proc ;等号键处理子程序,该子程序负责将第二个运算数据的数值计算出来存入X2变量push ax ;并根据运算符号,调用相应的运算子程序push dxpush bxinc ecall count ;调用运算键处理子程序,计算第二个运算数据cmp s,10jz add_call; ;加号cmp s,11jz sub_call ;减号cmp s,12jz mul_call; ;乘号cmp s,13jz divp_call ;除号add_call:call addpjmp store1sub_call:call subpjmp store1mul_call:call mulpjmp store1divp_call:cmp x2,0 ;判断除数是否为零,为零跳入报错子程序jz disp1call divpjmp store1disp1 proc ;报错显示子程序push bxpush axmov bh,0lea si,discode ;si指向段码表头mov ah,00010000bmov al,ahmov dx,port_cout dx,almov bh,00hmov bl,14mov al,[si+bx]mov dx,port_bout dx,alpop axpop bxkkk1:mov dx,port_ain al,dx ;报错后扫描键盘等待按键跳出and al,0fhcmp al,0fh;jz kkk1jmp kkkretdisp1 endp;store1:call clearmov ax,y ;将各运算子程序返回的运算结果,按位分解,送入X变量cmp ax,0 ;判断是否小于0,是跳转jl ccccmp ax,1000jnz ddd1mov x[0],1mov x[1],0mov x[2],0mov x[3],0jmp jieshuddd1:cmp ax,1000jl ddd2mov bx,1000mov dx,00hdiv bxmov x[0],almov ax,dxmov ah,00hjmp dddccc:mov x[0],10hmov ax,yneg ax ;取反ddd2:cmp ax,100jnz dddmov x[0],0mov x[1],1mov x[2],0中国矿业大学计算机科学与技术学院硬件课程设计报告mov x[3],0jmp jieshuddd:cmp ax,100jl gggmov bl,100div blmov x[1],almov al,ahmov ah,00hcmp ax,10jnz gggmov x[0],0mov x[1],0mov x[2],1mov x[3],0jmp jieshuggg:cmp ax,10jl jjjmov bl,10div blmov x[2],almov al,ahmov ah,00hjjj:mov x[3],aljieshu:pop bxpop dxpop axretoutp endp;count proc ;运算键处理子程序,该程序将第一个运算数据的数值计算出来,并存入X1变量push ax ;或将第二个运算数据计算出来存入X2变量中国矿业大学计算机科学与技术学院硬件课程设计报告push bx ;将预算符存入S变量push dxmov dx,0call bitp ;测试有多少位cmp cc,4jz c4cmp cc,3jz c3cmp cc,2jz c2jmp c1c4:mov ax,0mov al,x[0]mov bx,1000mul bxmov dx,axc3:mov al,x[1]mov bl,100mul bladd dx,axc2:mov al,x[2]mov bl,10mul bladd dx,axc1:mov al,x[3]mov ah,0add dx,axcmp e,1 ;判断是否为等号jnz x1_s ;不是mov x2,dx ;是等于号,则将第二个运算数据的值存入X2变量jmp exit3x1_s:mov x1,dx ;按下的是运算符号,则将第一个运算符的值存入X1变量mov x[3],0 ;清空X变量mov x[2],0mov x[1],0mov x[0],0exit3:pop dxpop bxpop axretcount endpnumber proc ;数字键处理子程序cmp e,1 ;将输入的数据按位存放在X变量中,并由CC记录数据的位数jnz continuemov e,0call clearcontinue:cmp cc,0 ;目前数据为0位,没有数据则转到SSSjz ssspush ax ;若已有数据,程序将X左移8位,例如先输入1,再输入2,先要将1从各位移到十位,再将2存放到个位push dxmov al,x[3]mov ah,x[2]mov dl,x[1]mov dh,x[0]mov x[3],00hmov x[2],almov x[1],ahmov x[0],dlpop dxpop axsss:mov [di],dl; 将当前键入的数据存放到X的最低位inc cc; 数据位数加1cmp cc,4; 判断数据位数jng exit2mov cc,0 ;超过4位,重新从最低位开始存mov x[2],0mov x[1],0mov x[0],0exit2:call disp; 调用显示子程序,显示输入的数据retnumber endp;addp proc ;加法子程序push ax;mov ax,x1;add ax,x2;mov y,axpop axretaddp endp;subp proc ;减法子程序push axmov ax,x1sub ax,x2mov y,axpop axretsubp endp;mulp proc ;乘法子程序push axpush dxmov ax,x1mov dx,x2mul dxmov y,axpop dxpop axretmulp endp;divp proc ;除法子程序push axpush bxpush dxmov dx,0mov ax,x1mov bx,x2div bxmov y,axpop dxpop bxpop axretdivp endpdisp proc ;显示子程序,将X中的数值按位显示出来push bxpush axmov bh,0lea si,discode ;si指向段码表头begin:call bitp ;测试X的位数cmp cc,4jz qian ;cc等于4跳转cmp cc,3jz bai ;cc等于3跳转cmp cc,2jz shi ;cc等于2跳转cmp cc,1jz g ;cc等于1跳转jmp none ;否则跳转到没有数字qian:mov ah,10000000b;mov al,ahmov dx,port_cout dx,almov bh,00hmov bl,x[0] ;x[0]即千位数字mov al,[si+bx] ;默认是DS数据段首地址,中括号内位段码表的偏移量,将数字所对应的段码送到锁存器mov dx,port_bout dx,almov al,0out dx,albai:mov ah,01000000bmov al,ahmov dx,port_cout dx,almov bh,00hmov bl,x[1]mov al,[si+bx]mov dx,port_bout dx,almov al,0out dx,alshi:mov ah,00100000bmov al,ahmov dx,port_cout dx,almov bh,00hmov bl,x[2]mov al,[si+bx]mov dx,port_bout dx,almov al,0out dx,alg:mov ah,00010000bmov al,ahmov dx,port_cout dx,almov bh,00hmov bl,x[3]mov al,[si+bx]mov dx,port_bout dx,almov al,0out dx,almov al,00hmov dx,port_cout dx,alout dx,almov dx,port_ain al,dx ;读列值,即PA0-PA3的值and al,0fhcmp al,0fh;jnz exit4jmp beginnone:mov ah,00010000bmov al,ahmov dx,port_cout dx,almov al,3fh ;X中没有数据则显示0mov dx,port_bout dx,alexit4:pop axpop bxretdisp endp;bitp proc ;分析数据位数的子程序,判断有多少个位cmp x[0],0jnz fourbit ;如果x[0]不为0,则数据为4位数cmp x[1],0jnz threebit ;如果x[1]不为0,则数据为3位数cmp x[2],0jnz towbit ;如果x[2]不为0,则数据为2位数cmp x[3],0jnz onebit ;如果x[3]不为0,则数据为1位数jmp zerobit ;如果x[3]为0,则没有数据fourbit:mov cc,4jmp exit5threebit:mov cc,3jmp exit5towbit:mov cc,2jmp exit5onebit:mov cc,1jmp exit5zerobit:mov cc,0 ;将数据位数存入cc存放数据位数的地方exit5:retbitp endp; 结束dely proc ;延时子程序push cxmov cx,100loop $ ;$表示当前地址即原地循环pop cx ;入栈目的是保存cx的值防止多次调用的时候cx的值变化!!!!retdely endpcode endsend start4 问题与解决方案1.此次课程设计显示器件本想采用ST7920,结果纠结于显示屏的启动程序和电泳程序,每次显示都控制不好在屏幕的位置,最终采用了LED七段数码管,这个启用很方便只要给S0~S3高电平就能点亮相应的数码管,再通过da~dp给入相应数据显示数字。