为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

基于单片机双字节简易计算器程序设计

2017-09-30 28页 doc 56KB 42阅读

用户头像

is_180829

暂无简介

举报
基于单片机双字节简易计算器程序设计基于单片机双字节简易计算器程序设计 ;================= Const =============================== SysStack Equ 07h ;08H...1FH Dark Equ 10H ;----------------- Hardware ---------------------------- DisSegPort Equ 0000H ;0:Light up DisCSPort Equ 2000H ;1:Select KeyOutPort Equ DisCSPort;...
基于单片机双字节简易计算器程序设计
基于单片机双字节简易计算器程序设计 ;================= Const =============================== SysStack Equ 07h ;08H...1FH Dark Equ 10H ;----------------- Hardware ---------------------------- DisSegPort Equ 0000H ;0:Light up DisCSPort Equ 2000H ;1:Select KeyOutPort Equ DisCSPort;Key Output Port ;KeyInout:p1.0,P.1..P1.3 ;0:Pressed ;------------------ Byte Units ------------------------- KeyGetF Bit 20H ;1:Get A New Key KeyPress Bit 21H ;1:Key Released SumPress Bit 22H ;1 + SumPress1 Bit 23H EqualPress Bit 24H ;1 = DivPress Bit 25H ;1 / DivPress1 Bit 26H MulPress Bit 27H ;1 * MulPress1 Bit 28H SubbPress Bit 29H ;1 - SubbPress1 Bit 31H NegPress Bit 32H NegPress1 Bit 33H ;+/- NegPress2 Bit 34H DataPress Bit 35H ;数字键 FuncPress Bit 36H ;运算功能键 Sign Bit 37H KeyCode Equ 60H DisBuf Equ 70H;..75H DeciPos Equ 76H ;Bit=1:Show DeciPoint SumVa Equ 77H ;press func KEY,Memory the DATA ON dis DivVa Equ 78H ;the same UP MulVa Equ 79H ;the same UP SubbVa Equ 85H ;the same UP ;======================================================= Org 0000H AJmp Main ;======================================================= Display: Mov R1,#00000001B ;R1=DisCS Mov R0,#DisBuf ;DisBuf Pointer DisLoop: Mov B,#0FFH Mov A,DeciPos ;小数点? Anl A,R1 Jz DisNext ;0没小数点 Clr B.7 ;1小数点 DisNext: Mov Dptr,#DisCSPort;Do Display CS Mov A,R1 Movx @Dptr,A Mov A,@R0 ;Get Dis Char Mov Dptr,#DisTab Movc A,@A+Dptr Anl A,B Mov Dptr,#DisSegPort;Use Table Movx @Dptr,A ;Send to DisSeg Port ACall Delay Inc R0 Mov A,R1 RL A Mov R1,A Cjne R0,#DisBuf+6,DisLoop Ret ;------------------------------------------------------- ; Char: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ; Code: 00H, 01H, 02H, 03H, 04H, 05H, 06H, 07H, 08H, 09H DisTab: DB 0C0H,0F9H,0A4H,0B0H, 99H, 92H, 82H,0F8H, 80H, 90H ; Char: 'A', 'B', 'C', 'D', 'E', 'F', '10H' ; Code: + , - , * , / , = , ON/C ,Dark DB 088H,0BFH,0c6H,0a1H, 86H, 8eH ,0FFH ;-------------------------------------------------------- Delay: Mov R2,#04h Delay1: Mov R3,#0 Djnz R3,$ Djnz R2,Delay1 Ret ;------------------------------------------------------- InitDis: Mov DisBuf+0,#0 Mov DisBuf+1,#Dark Mov DisBuf+2,#Dark Mov DisBuf+3,#Dark Mov DisBuf+4,#Dark Mov DisBuf+5,#Dark Mov DeciPos,#00000000B Ret ;------------------------------------------------------ NegDis: Mov DisBuf+5,#0BH Ret ;------------------------------------------------------- ScanKey: Mov Dptr,#KeyOutPort Mov A,#0 Movx @Dptr,A Mov A,P1 Cpl A ;取反处理,以便用A进行是否全0判断.指令只可判断全0不可判断全1 ANl A,#0FH ;屏蔽掉无关位 Ret ;----------------------------------------------------------------------- ReadKey: ACall ScanKey Jnz ReadKey1 ;A为0时无按键,只要有一位为1即有按键 Clr KeyPress ReadKeyQ: Ret ReadKey1: Jb KeyPress,ReadKeyQ ; 键压着可以准确定位是哪个键压着,故返回 Mov R2,#11111110B ; Mov R3,#0 ;准备扫描第一列 ReadKeyLp: Mov Dptr,#KeyOutPort Mov A,R2 ;列扫描值,选则列输出,检测 Movx @Dptr,A Mov A,#0 Jnb P1.0,ReadKeyOk Mov A,#6 Jnb P1.1,ReadKeyOk Mov A,#12 Jnb P1.2,ReadKeyOk Mov A,#18 Jnb P1.3,ReadKeyOk Inc R3 Mov A,R2 RL A Mov R2,A AJmp ReadKeyLp ReadKeyOk: Add A,R3 ;加上列扫描值 Setb KeyGetF Setb KeyPress Mov Dptr,#KeyChgTab Movc A,@A+Dptr Mov KeyCode,A Ret ;---------------------------------------------------------------- ; KeyCode 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H,0AH,0BH,0CH,0DH,0EH,0FH,10H,11H,12H,13 H,14H,15H,16H,17H ; OldKey Spc, 0 ,Dot,Equ,+ ,M+ ,% , 1 , 2 ,3 ,? ,M- ,+/-, 4 , 5 ,6 , - ,MRC, C , 7 ,8 , 9 , X , / KeyChgTab: DB 10, 0 ,11 ,12 ,13 ,14 ,15 , 1 , 2 ,3 ,16 ,17, 18 , 4 , 5 ,6 , 19,20 ,21 , 7 ,8 , 9 , 22,23 ;------------------------------------------------------- InitKey: Clr KeyGetF Ret ;-------------------------------------------------------- InitFunck: Clr SumPress Clr EqualPress Clr DivPress Clr MulPress Clr SubbPress InitNeg: Clr NegPress1 Clr NegPress2 Ret ;-------------------------------------------------------- ;================================================================= ;执行运算 Final: Jb SumPress1,AddA ;是否按下过加法键加法 Jb DivPress1,DivD Jb MulPress1,MulM Jb SubbPress1,SubbS Ajmp MainLoop ;--------------------------------------------------------- AddA: Clr SumPress1 ;执行加法运算 ACall FromLED Jnb NegPress,AddC1 Clr NegPress Mov A,R6 Orl A,#10000000B Mov R6,A AddC1: ACall InitDis ACall AddF ;调用加法子程序 ACall ToLED Ret ;---------------------------------------------------------- DivD: Clr DivPress1 ;执行除法运算 ACall FromLED Jnb NegPress,DivC1 Clr NegPress Mov A,R6 Orl A,#10000000B Mov R6,A DivC1: ACall InitDis ACall DivF ACall ToLED Ret ;-------------------------------------------------------------- ; R6R7*R4R5=R2R3R6R7 MulM: Clr MulPress1 ACall FromLED Jnb NegPress,MulC1 Clr NegPress Mov A,R6 Orl A,#10000000B Mov R6,A MulC1: ACall InitDis ACall MulF ;调用乖法子程序 Acall ToLED Ret ;----------------------------------------------------------------- ; R4R5-R6R7=R6R7 SubbS: Clr SubbPress1 ACall FromLED Jnb NegPress,SubbC1 Clr NegPress Mov A,R6 Orl A,#10000000B Mov R6,A SubbC1: ACall InitDiS ACall SubbF ACall ToLED Ret ;------------------------ ;R4R5*R6R7=R6R7 MulF: Mov A,R4 ;判断两数符号同或异 Xrl A,R6 Mov C,ACC.7 Mov Sign,C Mov A,R4 Clr ACC.7 Mov R4,A Mov A,R6 Clr ACC.7 Mov R6,A Mov A,R7 Mov B,R5 MUL AB XCH A,R7 Mov R2,B Mov B,R4 MUL AB Add A,R2 Mov R2,A Clr A Addc A,B Mov R3,A Mov A,R6 Mov B,R5 MUL AB Add A,R2 Mov R2,A Mov A,B Addc A,R3 Mov R3,A Clr A Addc A,#00H XCH A,R6 Mov B,R4 MUL AB Add A,R3 Mov R3,A Mov A,B Addc A,R6 XCH A,R2 Mov R6,A Clr OV Mov A,R6 Mov C,Sign Mov ACC.7,C Mov R6,A BackMul: Ret ;------------------------ ;R4R5/R6R7=R6R7 先R0R1 余R2R3 DivF: MOV A,R4 XRL A,R6 MOV C,ACC.7 MOV Sign,C MOV A,R4 CLR ACC.7 MOV R4,A MOV A,R6 CLR ACC.7 MOV R6,A Mov R0,#0 Mov R1,#0 ;商赋初值零 Div2Byte_1:Mov A,R5 Clr c Subb A,R7 ;低字节相减 Mov R5,A Mov A,R4 Subb A,R6 ;高位相减 Mov R4,A Jc Div2Byte_3 ;如果高字节都需要借位则退出循环 Clr c Mov A,R1 ;R1自增 AddC A,#1 Mov R1,A Jnc Div2Byte_2 Inc R0 ;商加一 Div2Byte_2:Sjmp Div2Byte_1 Div2Byte_3:Mov A,R0 Mov R6,A Mov A,R1 Mov R7,A MOV A,R6 JB ACC.7,IDIVE JB OV,IDIVE MOV C,Sign MOV ACC.7,C MOV R6,A RET IDIVE: SETB OV BackDiv: Ret ;----------------------------------------------------------------------------- AddF: MOV A,R4 MOV C,ACC.7 MOV Sign,C XRL A,R6 ; 判断R3R6是否同号 MOV C,ACC.7 MOV A,R4 Clr ACC.7 MOV R4,A MOV A,R6 CLR ACC.7 MOV R6,A JC DAB2 ACall Add1 MOV A,R6 JB ACC.7,DABE DAB1 : MOV C,Sign MOv ACC.7,C MOV R6,A CLR OV RET DABE : SETB OV RET DAB2 : LCALL Subb1 MOV A,R6 JNB ACC.7,DAB1 ACALL Cmpt CPL Sign SJMP DAB1 BackA: Ret ;----------------------------------------------------------------------------- SubbF: MOV A,R6 CPL ACC.7 MOV R6,A MOV A,R4 MOV C,ACC.7 MOV Sign,C XRL A,R6 ; 判断R3R6是否同号 MOV C,ACC.7 MOV A,R4 Clr ACC.7 MOV R4,A MOV A,R6 CLR ACC.7 MOV R6,A JC DAB2 ACall Add1 MOV A,R6 JB ACC.7,SDABE SDAB1: MOV C,Sign MOv ACC.7,C MOV R6,A CLR OV RET SDABE: SETB OV RET SDAB2: ACall Subb1 MOV A,R6 JNB ACC.7,SDAB1 ACALL CMPT CPL Sign SJMP SDAB1 ;------------------------ Cmpt : MOV A,R7 CPL A ADD A,#01H MOV R7,A MOV A,R6 CPL A ADDC A,#00H MOV R4,6 Ret ;----------------------------- ;R4R5+R6R7=R6R7 Add1: Clr C Mov A,R5 Add A,R7 Mov R7,A Mov A,R4 Addc A,R6 Mov R6,A Ret ;------------------------ ;R4R5-R6R7=R6R7 Subb1: Mov A,R5 Clr C Subb A,R7 Mov R7,A Mov A,R4 Subb A,R6 Mov R6,A Ret ;------------------------ ;===================================================================== == ;从显示屏读出数 FromLED: Mov r0,#DisBuf+4 ReadLED1: Cjne @r0,#Dark,ReadLED2 Dec r0 cjne r0,#DisBuf+0,READLED1 ReadLED2: Mov R6,#0 Mov A,@r0 Mov R7,A Cjne r0,#DisBuf+0,ReadLed3 Sjmp BackFLED ReadLED3: ACall R6R7Mul10 Dec r0 Mov A,@r0 Acall AddDis Cjne r0,#DisBuf+0,ReadLED3 BackFLED: Ret ;==================================================================== AddDis: Clr C Addc A,R7 Mov R7,A Jnc BackAD INC R6 BackAD: Ret ;----------------------------------------------------------------------- ;R6R7:=R6R7*10 R6R7Mul10: Mov A,R7 Mov B,#10 Mul AB Mov R7,A ;R7*10 高 Mov A,#10 Xch A,B ;B:=10, A:=B R7低 Xch A,R6 ;A:=R6 Mul AB Add A,R6 Mov R6,A Ret ;------------------------------------------------------- ;将数送显示 ;============================ Display Number =============================== ;change R67 into @r0.DisBuf(5) ;By: Linjuan, improved by: Wu ChuiHong ;Improvements: ; 1. Much Faster, 2. Fewer Codes, 3. r6,r7,r5,r6,r7,Dptr Not used ;Every Exec Time=275 us for num=1 to 65535, Test on 25/9/1998 ;Change: a,b,r0,R0,r2 if more than 1 byte ;--------------------------------------------------------------------------- ;If R6.7=1(Negtive!) then R6R7:=0-R6R7, DisBuf+5:'-' ToLED: Mov A,R6 Jnb ACC.7,Correct Clr ACC.7 Mov R6,A ACall NegDis Correct: Mov R0,#DisBuf LCall FilDisBuf Word2DR01: Mov r2,#4 ;1 word needs only 4 loops W2DLoop: Mov a,r6 jz W2DByte ; need only do low byte Mov b,#10 ; else divided by 10 div ab Mov r6,a Mov a,r7 anl a,#0f0h orl a,b swap a Mov b,#10 div ab swap a Xch a,r7 anl a,#0fh xch a,b swap a orl a,b Mov b,#10 div ab Mov @R0,b Inc R0 Orl a,r7 Mov r7,a djnz r2,W2DLoop jnz W2DOut0 Ret ;------------------------------ W2DByteClr:Mov r2,#2 ACall ClrDisLp SJmp W2DByteA ;------------------------------ W2DByte: Mov a,r7 W2DByteA: Mov b,#10 div ab Mov @R0,b jz W2DOut Mov b,#10 div ab Inc R0 Mov @R0,b jz W2DOut Inc R0 W2DOut0: Mov @R0,a W2DOut: Ret ;--------------------------------------------------------------------------- ClrDisBuf0:Mov r0,#DisBuf ClrDisBufA:Mov r2,#15 ClrDisLp: Mov @r0,#' ' Inc r0 Djnz r2,ClrDisLp Ret ;--------------------------------------------------------------------------- FilDisBuf: Mov a,#'0' FilDisBufA:Mov r2,#5 FilDisBufr:Mov b,r0 ClrDisBufL:Mov @r0,a Dec r0 Djnz r2,ClrDisBufL Mov r0,b Ret ;--------------------------------------------------------------- IndectNeg1: ;检测是否负数,是则置1标志位 Mov A,DisBuf+5 Cjne A,#Dark,SNeg1 Sjmp BackIN1 SNeg1: Setb NegPress1 BackIN1: Ret ;------------------------------------------------------------ IndectNeg2: Mov A,DisBuf+5 Cjne A,#Dark,SNeg2 Sjmp BackIN2 SNeg2: Setb NegPress2 BackIN2: Ret ;--------------------------------------------------------- IndectF: Jnb SumPress,KeyData1 ;未按过+,则继续输入数据 ACall InitDis ;按过键,则先清屏 Clr SumPress ;+复位 Sjmp BackIF KeyData1: Jnb MulPress,KeyData2 ;未按过*,则继续输入数据 ACall InitDis ;按过键,则先清屏 Clr MulPress Sjmp BackIF KeyData2: Jnb SubbPress,KeyData3 ;未按过*,则继续输入数据 ACall InitDis ;按过键,则先清屏 Clr SubbPress Sjmp BackIF KeyData3: Jnb DivPress,KeyData4 ;未按过/,则继续输入数据 ACall InitDis ;按过键,则先清屏 Clr DivPress Sjmp BackIF KeyData4: Jnb EqualPress,BackIF ;等号键位为0,则继续输入数据 Clr EqualPress ;为1这先复位为0并清屏 ACall InitDis BackIF: Ret ;======================================================= Main: Mov Sp,#SysStack ACall InitDis ACall InitKey ACall InitFunck MainLoop: ACall Display ACall ReadKey Jbc KeyGetF,DoKey AJmp MainLoop DoKey: Mov A,KeyCode Clr C Subb A,#10 Jnc DoFuncKey ;字模大于等于10,跳到功能键 Setb DataPress Acall IndectF ;检测功能键 Mov A,DisBuf+4 ;If Top DisNum=Dark? Cjne A,#Dark,KeyNumQ Mov A,DisBuf+1 Cjne A,#Dark,RLDIS Mov A,DisBuf+0 Jz KeyNum1 RLDIS: Mov A,DeciPos ;Left shift DeciP RL A Mov DeciPos,A Mov DisBuf+4,DisBuf+3 ;Key=Number Key Mov DisBuf+3,DisBuf+2 Mov DisBuf+2,DisBuf+1 Mov DisBuf+1,DisBuf+0 KeyNum1: Mov DisBuf+0,KeyCode KeyNumQ: AJmp MainLoop ;------------------------------------------------------- DoFuncKey: Mov Dptr,#JmpTab Rl A ;叠加指令字节,防止跳到指令之间的空白区 Jmp @A+Dptr ; ? JmpTab: AJmp Func0 ;A=0,Key=Clear AJmp Func1 ;A=1,Key=Decimal Point AJmp Func2 ;A=2,Key= = AJmp Func3 ;A=3,Key=+ AJmp Func4 ;A=4,Key= AJmp Func5 ;A=5,Key= AJmp Func6 ;A=6,Key= AJmp Func7 ;A=7,Key= AJmp Func8 ;A=8,Key= AJmp Func9 ;A=9,Key= AJmp Func10 ;A=10,Key= AJmp Func11 ;A=11,Key= AJmp Func12 ;A=12,Key= AJmp Func13 ;A=13,Key= AJmp MainLoop ;------------------------------------------------------- Func0: ACall InitDis ;Clear AJmp MainLoop ;------------------------------------------------------- Func1: Mov A,DeciPos Jnz Func1Q ;DeciP Exist, Quit Mov DeciPos,#00000001B ;Show DeciPoint Func1Q: AJmp MainLoop ;------------------------------------------------------- Func2: ACall IndectNeg2 ;= ACall Final ACall InitNeg Setb EqualPress Func2Q: AJmp MainLoop ;------------------------------------------------------- Func3: ACall FromLED ;+ Mov A,R6 Mov R4,A Mov A,R7 Mov R5,A Jnb NegPress,Func31 Clr NegPress Mov A,R4 Orl A,#10000000B Mov R4,A Func31: ACall IndectNeg1 Setb SumPress Setb SumPress1 Func3Q: AJmp MainLoop ;------------------------------------------------------- Func4: AJmp MainLoop Func5: AJmp MainLoop Func6: AJmp MainLoop Func7: AJmp MainLoop ;-------------------------------------------------------------- Func8: Jnb DataPress,Func8Q ;检测没按下数字键 +/- ACall NegDis ; +/- Setb NegPress Func8Q: AJmp MainLoop ;-------------------------------------------------------------- Func9: ACall FromLED ;- Mov A,R6 Mov R4,A Mov A,R7 Mov R5,A Jnb NegPress,Func91 Clr NegPress Mov A,R4 Orl A,#10000000B Mov R4,A Func91: ACall IndectNeg1 Setb SubbPress Setb SubbPress1 Func9Q: AJmp MainLoop ;----------------------------------------------------------- Func10: AJmp MainLoop Func11: AJmp MainLoop ;--------------------------------------------------------- Func12: ACall FromLED ; * Mov A,R6 Mov R4,A Mov A,R7 Mov R5,A Jnb NegPress,Func121 Clr NegPress Mov A,R4 Orl A,#10000000B Mov R4,A Func121: ACall IndectNeg1 Setb MulPress Setb MulPress1 Func12Q: AJmp MainLoop ;------------------------------------------------------------- Func13: ACall FromLED ; / Mov A,R6 Mov R4,A Mov A,R7 Mov R5,A Jnb NegPress,Func131 Clr NegPress Mov A,R4 Orl A,#10000000B Mov R4,A Func131: ACall IndectNeg1 Setb DivPress Setb DivPress1 Func13Q: AJmp MainLoop ;======================================================= ;--------------------------------------------------------------------------- End
/
本文档为【基于单片机双字节简易计算器程序设计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索