《微机原理加法计算器设计与显示.doc》由会员分享,可在线阅读,更多相关《微机原理加法计算器设计与显示.doc(10页珍藏版)》请在课桌文档上搜索。
1、实验报告课程名称: 微机原理实验 一、 实验目的和要求1. 掌握基于状态机的编程方法2. 实现数字运算、键盘输入、LED显示的多任务协调编程二、 实验容和原理1. 编写程序,输入两个两位十进制数并显示,按确认键后显示运算结果2. 基本功能:能够输入输入数字(非数字无效)并显示结果3. 附加功能:光标指示功能(通过LED闪烁实现)以与退格功能三、 程序代码ORG 0000HSTART: MOV 78H,#0 ;初始化:78H放0的段码,其余放熄灭码MOV 79H,#10MOV 7AH,#10MOV 7BH,#10MOV 7CH,#10MOV R5,#0 ;R5是按键次数,初始置0MOV R6,#
2、0 ;将0置入R6中MOV R7,#0 ;将0置入R7中MOV 30H,#0 ;30H是功能键存放单元,置为0MOV 31H,#0 ;31H单元初始置为0MOV 40H,#0 ;40H单元初始置为0MOV 41H,#0 ;41H单元初始置为0LOOP: LCALL DIR ;调用显示子程序LCALL KEY ;调用键盘检测程序INC R5 ;按键次数加1S1: CJNE A,#10,S2 ;不是+键,跳到S2LJMP FUN ;是+键,跳到FUNS2: CJNE A,#11,S3 ;不是-键,跳到S3LJMP FUN ;是-键,跳到FUNS3: CJNE A,#12,S4 ; 不是*键,跳到S
3、4LJMP FUN ; 是*键,跳到FUNS4: CJNE A,#13,S5 ; 不是/键,跳到S5LJMP FUN ; 是/键,跳到FUNS5: CJNE A,#14,S6 ; 不是=键,跳到S6LJMP FUN ;是=键,跳到FUNS6: CJNE A,#15,N1 ; 不是CL键,跳到N1LJMP START ; 是CL键,跳到STARTN1: CJNE R5,#1,N2 ;若按键次数不等于1,跳到N2LJMP D11 ;跳到D11N2: CJNE R5,#2,START;若按键次数不等于2,跳到STARTLJMP T1 ;跳到T1D11: MOV R4,A ;将A写入R4MOV 78H
4、,A ;输入值送显示个位缓存MOV 79H,#10 ;将10送到79H单元LJMP LOOP ;跳转到循环T1: MOV 53H,A ;将A写入53HMOV B,#10 ;将10置入BMOV A,R4 ;将上一次输入的R4写进AMUL AB ;A乘以10ADD A,53H ;53H里面的值与A相加MOV R4,A ;将新的值置入到R4MOV 79H,78H ;个位到十位MOV 78H,53H ;新数为个位LJMP LOOP ;跳转到循环FUN:MOV 78H,#10 ;将10置入到78HMOV 79H,#10 ;将10置入到79HMOV R0,30H ;与上次功能键交换MOV 30H,A MO
5、V A,R0CJNE A,#10,FUN1 ;判断功能键LJMP ADDY ;FUN1: CJNE A,#11,FUN2LJMP SUBT ;FUN2: CJNE A,#12,FUN3LJMP MULT ;*FUN3: CJNE A,#13,FUN4LJMP DIVI ;/FUN4: CJNE A,#14,FUN5 ;首次按功能键,即A=#0LJMP EQUA ;=FUN5: MOV 40H,R4 ;保存第一个数MOV R5,#0 ;按键次数清零LJMP BCD ;将其拆为BCD码,以便后来将其显示OF: LJMP START ;跳转回开始ADDY: MOV A,40H ;加法,第一个数送累加
6、器ADD A,R4 ;第一个数加第二个数MOV 40H,A ;存本次结果MOV R5,#0 ;按键次数清零LJMP BCD ;跳转到BCD程序SUBT: MOV A,40H ;减法,第一个数送累加器CLR C ;借位清零SUBB A,R4 ;带借位的减法,第一个数减第二个数 CY,BCD2 ;借位为1,跳转到BCD2MOV 40H,A ;将减的结果送40HMOV R5,#0 ;按键次数清零LJMP BCD ;跳转到BCDMULT: MOV A,40H ;乘法,第一个数送累加器MOV B,A ;将A送BMOV A,R4 ;将第二个数送累加器MUL AB ;第一个数乘以第二个数MOV R5,#0
7、;按键次数清零 OV,BCD1 ;若乘法结果溢出,则跳转到BCD1MOV 40H,A ;将A送40HLJMP BCD ;跳转到BCDDIVI: MOV A,R4 ;除法,第二个数送累加器MOV B,A ;将第二个数送BMOV A,40H ;将第一个数送ADIV AB ;A除以B OV,OF ;当B为0时跳到OFMOV 40H,A ;将A送40HMOV R5,#0 ;按键次数清零LJMP BCD ;跳转到BCDEQUA: MOV R5,#0 ;按键次数清零MOV 31H,A ;将A送31HLJMP BCD ;跳转到BCD;-乘法溢出时的处理程序BCD1: ;乘法溢出时的处理程序MOV 78H,
8、B ;将高8位送78HMOV 79H, A ;将低8位送79HLCALL HEX2BCD ;调用子程序把78H、79H中的数字,转换成BCD码,送到7AH 7BH 7CH MOV A, 7CH ;下面,把万千百十个位,分别存入7CH 7BH 7AH 79H 78HMOV B, #16 DIV AB ;除以16,目的是分离出高、低四位MOV 79H, A ;存放十位MOV 78H, B ;存放个位MOV A, 7AHMOV 7CH, A ;存放万位MOV A, 7BHMOV B, #16DIV ABMOV 7BH, AMOV 7AH, BLJMP LOOPHEX2BCD: ;子程序:把78H、7
9、9H中的数字,转换成BCD码,送到7AH 7BH 7CH CLR AMOV 7AH, A ;先清零MOV 7BH, AMOV 7CH, AMOV R6, #16 ;共转换十六位数 LOOPP:CLR CMOV A, 79H ;从待转换数的高端移出一位到CyRLC AMOV 79H, AMOV A, 78HRLC AMOV 78H, AMOV A, 7CH ;送到BCD码的低端ADDC A, 7CH ;带进位加。自身相加,相当于左移一位DA A ;十进制调整,变成BCD码MOV 7CH, AMOV A, 7BHADDC A, 7BHDA AMOV 7BH, AMOV A, 7AHADDC A,
10、7AHMOV 7AH, ADJNZ R6,LOOPP ;共转换十六位数RETBCD2:MOV A,#100 ;减法第七位有借位时的处理程序CLR C ;借位清零SUBB A,R4 ;100-被减数MOV R4,A ;将结果存在R4中MOV A,40H ;将减数给AADD A,R4 ;减数+(100-被减数)MOV R4,A ;将结果给R4MOV A,#100 ;将100给ACLR C ;将CY清零SUBB A,R4 ;100-(减数+(100-被减数)MOV B,#10 ;将10给BDIV AB ;A除以10MOV 7AH,#11 ;将11给7AH,以便显示符号MOV 79H,A ;将A给79
11、HMOV 78H,B ;将B给78HLJMP LOOP ;跳转到LOOP;-拆为BCD码的程序BCD: MOV B,#10 ;将10给BMOV A,40H ;结果送累加器DIV AB ;结果除10MOV 41H,A ;41H暂存商MOV A,B ;取余数MOV 78H,A ;余数送78HMOV B,#10 ;将10送BMOV A,41H ;将商送ADIV AB ;A除以10CJNE A,#0,PANDUAN1 ;若A不等于0,则跳转到PANDUAN1MOV 79H,B ;若A等于0,则将B送79HLJMP RETURN ;跳转到RETURNPANDUAN1:MOV 7AH,A ;A送7AHMO
12、V 79H,B ;B送79HRETURN:LJMP LOOP ;跳转到LOOP;-动态显示子程序DIR: MOV DPTR,#TAB ;数码管译码表首址MOV R0,#78H ;待显缓冲区个位地址CJNE R5,#1,ANJIAN2 ;判断按键次数是否为1,不是则跳转到ANJIAN2ANJIAN1: MOV A,R0 ;将显示区的个位地址给AMOVC A,A+DPTR ;查表CLR P2.3 ;点亮P2.3MOV P3,A ;字段码送P3口LCALL DELAY1ms ;调延时1ms 子程序SETB P2.3 ;关闭P2.3MOV P3,#0FFH ;将P3口熄灭LCALL DELAY1ms
13、;调用延时1ms子程序;-按键1次时光标闪烁功能INC R6 ;将R6加1CJNE R6,#70,SHANSHUO1 ;若R6不等于70,则跳转到SHANSHUO1SETB P2.2 ;将P2.2关闭MOV P3,#0FFH ;将P2口熄灭LCALL DELAY1ms ;调用延时1ms子程序DEC R6 ;R6就减1INC R7 ;R7加1CJNE R7,#70,FANHUI ;判断R7是否等于70,若不等于70,则跳转到FANHUIMOV R6,#0 ;将R6置0MOV R7,#0 ;将R7置0FANHUI:RET ;子程序返回SHANSHUO1:CLR P2.2 ;打开P2.2MOV P3
14、,#0EFH ;显示“-”LCALL DELAY1ms ;调用延时1ms子程序SETB P2.2 ;关闭P2.2MOV P3,#0FFH ;熄灭P3RET ;返回;-按键次数为2显示ANJIAN2:CJNE R5,#2,ANJIANDENG;如果R5不等于0,则跳转到ANJIANDENGMOV A,R0 ;将显示区的个位地址给AMOVC A,A+DPTR ;查表CLR P2.3 ;点亮P2.3MOV P3,A ;将个位显示LCALL DELAY1ms ;调用延时1msSETB P2.3 ;关闭P2.3MOV P3,#0FFH ;关闭显示INC R0 ;R0加1MOV A,R0 ;将显示区的十位
15、地址给AMOVC A,A+DPTR ;查表CLR P2.2 ;打开P2.2MOV P3,A ;将十位送P3显示LCALL DELAY1ms ;调用延时1ms子程序SETB P2.2 ;关闭P2.2MOV P3,#0FFH ;关闭显示;-按键两次时光标闪烁功能INC R6 ;R6加1CJNE R6,#70,SHANSHUO2 ;判断R6是否为70,若否跳转到SHANSHUO2SETB P2.1 ;将P2.1关闭MOV P3,#0FFH ;关闭显示LCALL DELAY1ms ;调用延时1ms子程序DEC R6 ;R6减1INC R7 ;R7加1CJNE R7,#70,FANHUI2 ;若R7不等
16、于70,则跳转到FANHUI2MOV R6,#0 ;将0送R6MOV R7,#0 ;将R7置0FANHUI2:RET ;子程序返回SHANSHUO2:CLR P2.1 ;打开P2.1MOV P3,#0EFH ;显示“-”LCALL DELAY1ms ;调用延时1ms子程序SETB P2.1 ;关闭P2.1MOV P3,#0FFH ;关闭显示RET ;返回;-按“=”键后的显示ANJIANDENG:MOV A,31H ;将31H送ACJNE A,#0,ANJIAN0 ;A不等于0时跳转到ANJIAN0MOV A,R0 ;将个位的地址送AMOVC A,A+DPTR ;查表CLR P2.3 ;打开P
17、2.3MOV P3,A ;显示个位LCALL DELAY1ms ;调用延时1ms子程序SETB P2.3 ;关闭P2.3MOV P3,#0FFH ;关闭显示INC R0 ;R0加1MOV A,R0 ;将十位的地址送AMOVC A,A+DPTR ;查表CLR P2.2 ;打开P2.2MOV P3,A ;显示十位LCALL DELAY1ms ;调用延时1ms子程序SETB P2.2 ;关闭P2.2MOV P3,#0FFH ;关闭显示INC R0 ;R0加1MOV A,R0 ;将百位地址送AMOVC A,A+DPTR ;查表CLR P2.1 ;打开P2.1MOV P3,A ;显示百位LCALL DE
18、LAY1ms ;调用延时1ms子程序SETB P2.1 ;关闭P2.1MOV P3,#0FFH ;关闭显示INC R0 ;R0加1MOV A,R0 ;将千位的地址送AMOVC A,A+DPTR ;查表CLR P2.0 ;打开P2.0MOV P3,A ;显示千位LCALL DELAY1ms ;调用延时1ms子程序SETB P2.0 ;关闭P2.0MOV P3,#0FFH ;关闭显示RET ;返回;-没按键时的显示ANJIAN0: MOV A,R0 ;将R0的地址送AMOVC A,A+DPTR ;查表CLR P2.3 ;打开P2.3MOV P3,A ;显示LCALL DELAY1ms ;调用延时1
19、ms子程序SETB P2.3 ;关闭P2.3MOV P3,#0FFH ;关闭显示RET ;返回TAB: DB 28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60H,0FFH,0F7H ;共阳极译码表DELAY1ms: MOV 50H,#2 ;延时1ms子程序LOOP1: MOV 53H,#248NOPLOOP2:DJNZ 53H,LOOP2DJNZ 50H,LOOP1RETDELAY1:MOV 51H,#5 ;延时子程序DELAY1DELAY3:DJNZ 51H,DELAY3RET;-键盘子程序KEY: LCALL KS ;调用检测按键子程序JNZ K1 ;有键按下
20、继续LCALL DELAY2 ;无键按调用延时去抖ACALL DIR ;调用动态显示AJMP KEY ;返回继续检测按键K1: LCALL DELAY2 ;有键按下延时去抖动LCALL KS ;再调用检测按腱子程序JNZ K2 ;确认有按键进行下一步ACALL DIR ;调用动态显示AJMP KEY ;无键按下返回继续检测K2: MOV R2,#0EFH ;将扫描值送入R2暂存MOV R3,#00H ;将第一列值送入R3暂存K3: MOV P1,R2 ;将R2值送入P1口L0: P1.0,L1 ;P1.0等于1跳转到L1MOV A,#00H ;将第一行值送入ACCAJMP LK ;跳转到键值处
21、理程序L1: P1.1,L2 ;P1.1等于1跳转到L2MOV A,#04H ;将第二行的行值送入ACCAJMP LK ;跳转到键值处理程序L2: P1.2,L3 ;P1.2等于1跳转到L3MOV A,#08H ;将第三行行值送入ACCAJMP LK ;跳转到键值处理程序L3: P1.3,NEXT ;P1.3等于1跳转到NEXT处MOV A,#0CH ;将第四行行值送入ACCLK: ADD A,R3 ;行值与列值相加后的键值送入APUSH ACC ;将A中的值送入堆栈暂存K4: LCALL DELAY2 ;调用延时去抖程序LCALL KS ;调用按键检测程序JNZ K4 ;按键没有松开继续返回
22、检测POP ACC ;将堆栈值送入ACCMOV DPTR,#KEYTABMOVC A,A+DPTRRETNEXT: INC R3 ;列值加一MOV A,R2 ;R2值送入AJNB ACC.7,KEY ;扫描完至KEY处进行下一扫描RL A ;扫描未完将值左移一位进行下一列扫描MOV R2,A ;将ACC值送入R2暂存AJMP K3 ;跳转到K3继续KS: MOV P1, #0FH ;将P1口高四位置0低四位置1MOV A,P1 ;读P1口XRL A,#0FH ;将A中的值与A中的值相异或RET ;子程序返回KEYTAB:DB 1,2,3,10,4,5,6,11,7,8,9,12,15,0,14,13 ;键值表DELAY2:MOV 52H,#2H ;延时去抖动子程序LP1: MOV 53H,#0FAHLP2: DJNZ 53H,LP2DJNZ 52H,LP1RETEND四、 讨论、心得本次计算器的实验是一次综合性比较强的实验,对前面所学的知识是一个很好的考察。里面很多细小的地方在用汇编编程的时候都很有挑战性。比如开始该如何在数码管上一直显示就困扰了我很长时间;乘法溢出时如何处理也让我考虑了很久。总之,这次的实验让我对汇编语言的熟悉程度进一步加深,并且对我结构化模块化编程的能力有一定的提高作用。10 / 10