永发信息网

急求!!!哪位朋友指点下单片机程序题~~

答案:3  悬赏:70  手机版
解决时间 2021-03-31 06:36
急求!!!哪位朋友指点下单片机程序题~~
最佳答案
采用LCD1602两位显示的简单计算器程序,能够加减乘除,
;-------------------------------
;简单的计算器演示程序
;0-99之间的加、减、乘、除运算
;-------------------------------
;矩阵键盘定义:
;P1.0-P1.3为列线,P1.4-P1.7为行线
;出口:A、R3存键值
;-------------------------------
RELAY EQU P1.3
BEEP EQU P3.7
;-------------------------------
RS EQU P2.0
RW EQU P2.1
EN EQU P2.2
X EQU 3fH ;LCD 地址变量
;-------------------------------
TEMP1 EQU 30H ;临时暂存器
TEMP2 EQU 31H
TEMP3 EQU 32H
TEMP4 EQU 33H

RES_H EQU 24H ;输入被加(减、乘、除)数
RES_L EQU 25H ;输入加(减、乘、除)数

OUT_H EQU 26H ;运算结果高位
OUT_L EQU 27H ;运算结果低位

;-------------------------------
ORG 0000H
JMP MAIN
;-------------------------------
MAIN: MOV SP,#60H
CLR EN
CALL SET_LCD
MOV 20H,#00H
CALL BEEP_BL ;起延时作用
MOV R1,#00H
MOV TEMP1,#00H
MOV TEMP2,#00H
MOV TEMP3,#00H
MOV RES_L,#00H
MOV RES_H,#00H
MOV OUT_H,#00H
MOV OUT_L,#00H
LOOP:
CALL KEY_IN ;送被(加、减、乘、除)数
JNB 20H.0,LOOP ;键标记
CALL BEEP_BL

INC R1
CJNE R1,#01H,LOOP_1
MOV TEMP2,A ;高位
MOV X,#2
CALL CONV0

LOOP_1: CJNE R1,#02H,LOOP
SUBB A,#0AH ;判是否是功能键?
JNC LOOP_2 ;是,转LOOP_2
MOV TEMP1,TEMP2
MOV A,TEMP1
MOV X,#1
CALL CONV0
MOV A,R3 ;恢复有效键值
MOV TEMP2,A ;低位
MOV X,#2
CALL CONV0
MOV A,TEMP1
ANL A,#0FH
SWAP A
ORL A,TEMP2
MOV RES_H,A
JMP LOOP0
LOOP_2:
MOV RES_H,TEMP2
AJMP LOOP0A

LOOP0: CALL KEY_IN
JNB 20H.0,LOOP0
CALL BEEP_BL

LOOP0A: MOV A,R3 ;重装键值
CJNE A,#0AH,LOOP1 ;加运算
CALL CONV1
SETB 20H.1 ;加运算标记

AJMP LOOP5
LOOP1: CJNE A,#0BH,LOOP2 ;减运算
CALL CONV2
SETB 20H.2 ;减运算标记
AJMP LOOP5
LOOP2: CJNE A,#0CH,LOOP3 ;乘运算
CALL CONV3
SETB 20H.3 ;乘运算标记
AJMP LOOP5
LOOP3: CJNE A,#0DH,LOOP4 ;除运算
CALL CONV4
SETB 20H.4 ;除运算标记
AJMP LOOP5
LOOP4: CJNE A,#0FH,LOOP4A
AJMP MAIN

LOOP4A: AJMP LOOP0

LOOP5: MOV R1,#00H
MOV TEMP1,#00H
MOV TEMP2,#00H
CLR 20H.0 ;送(加、减、乘、除)数

LOOP5A: CALL KEY_IN
JNB 20H.0,LOOP5A
CALL BEEP_BL

CJNE A,#0FH,LOOP5B
AJMP MAIN

LOOP5B: INC R1
CJNE R1,#01H,LOOP5C
MOV TEMP2,A
MOV X,#6
CALL CONV0

LOOP5C: CJNE R1,#02H,LOOP5A
SUBB A,#0AH ;判是否是功能键?
JNC LOOP5D ;是,转LOOP5C
MOV TEMP1,TEMP2
MOV A,TEMP1
MOV X,#6
CALL CONV0
MOV A,R3
MOV TEMP2,A
MOV X,#7
CALL CONV0
MOV A,TEMP1
ANL A,#0FH
SWAP A
ORL A,TEMP2
MOV RES_L,A
JMP LOOP6

LOOP5D: MOV RES_L,TEMP2
JMP LOOP6A

LOOP6: CALL KEY_IN
LOOP6A: MOV A,R3 ;重装键值
CJNE A,#0FH,LOOP6B
AJMP MAIN
LOOP6B: CJNE A,#0EH,LOOP6 ;显示(=)
CALL CONV5
CALL BEEP_BL ;显示运算结果
JNB 20H.1,LOOP6C
CALL SUADD
LOOP6C: JNB 20H.2,LOOP6D
CALL SUSUB
LOOP6D: JNB 20H.3,LOOP6E
CALL SUMUL
LOOP6E: JNB 20H.4,LOOP7
CALL SUDIV

LOOP7: CALL KEY_IN
CJNE A,#0FH,LOOP7 ;复位(清零)
AJMP MAIN

;------------------------
;加法运算子程序
;入口:R0-被加数,R1-加数
;出口:R4(高)、R2(低)为和值
;------------------------
SUADD:
MOV R1,RES_L
MOV R0,RES_H

MOV A,R0
ADD A,R1
DA A
MOV R2,A
CLR A
ADDC A,#00H
MOV R4,A
MOV OUT_H,R4
MOV OUT_L,R2
CALL T_CONV
RET
;------------------------
;减法运算子程序
;入口:R0-被减数,R1-减数
;出口:R2-差值
;------------------------
SUSUB:
MOV R1,RES_L
MOV R0,RES_H
CLR C
MOV A,#9AH
SUBB A,R1 ;减数十进制求补
ADD A,R0
DA A
MOV R2,A ;差值送R2
JC POSI ;C=1,表示差值为正
NEGA: MOV A,#9AH ;差值为负,求补后得差值的绝对值
SUBB A,R2
MOV R2,A
SETB 20H.5 ;显示负号标记
POSI: MOV OUT_H,#00H
MOV OUT_L,R2
CALL T_CONV
RET
;-------------------------
;乘法运算子程序
; 单字节BCD码乘法子程序
;入口: R0(被乘数)、R1(乘数)
;出口: R3(高)、R2(低),积为双字节,BCD码形式的积
;从乘数高位开始进行BCD码移位乘法
;-------------------------
SUMUL:
MOV R1,RES_L
MOV R0,RES_H
BCDMUL:
CLR A ;积单元清零
MOV R2,A
MOV R3,A
MOV A,R1
JZ RETURN
ANL A,#0F0H ;取乘数高位
JZ LBCD ;乘数高位是否为0?
SWAP A
MOV R4,A
ACALL DDBCDM
SWAP A ;BCD码左移一位
MOV R3,A
MOV A,R2
SWAP A
MOV R2,A
ANL A,#0FH
ORL A,R3
MOV R3,A
MOV A,R2
ANL A,#0F0H
MOV R2,A
LBCD: MOV A,R1 ;取乘数低位
ANL A,#0FH
JZ RETURN ;乘数低位是否为0?
MOV R4,A
ACALL DDBCDM
RETURN: MOV OUT_H,R3
MOV OUT_L,R2
CALL T_CONV
RET

DDBCDM: ;一位BCD码乘法
MOV A,R2
ADD A,R0
DA A
MOV R2,A
MOV A,R3
ADDC A,#00H
DA A
MOV R3,A
DJNZ R4,DDBCDM
RET
;------------------------------------------------
;除法运算子程序

;单字节BCD码除法
;入口:R0(被除数)、R1(非零除数)
;出口:R2(商)、R3(余数)
;《MCS-51系列单片机实用子程序集锦》Page 73
;-----------------------------------------------
SUDIV:
MOV R1,RES_L
MOV R0,RES_H
BCDDIV:
MOV R2,#00H ;商单元清零
MOV A,R1 ;除数求补
CPL A
ADD A,#9BH
MOV R1,A
MOV A,R0 ;被除数高位移入
ANL A,#0F0H ;部分余单元
SWAP A
LP0: MOV R3,A ;做除法
ADD A,R1
DA A
JNC LP1 ;部分余数>=除数?
INC R2 ;商加1
SJMP LP0
LP1: MOV A,R3 ;
SWAP A
MOV R3,A
MOV A,R2 ;商左移一位
SWAP A
MOV R2,A
MOV A,R0 ;移位
ANL A,#0FH
ORL A,R3
LP2: MOV R3,A ;做除法
ADD A,R1
DA A
JNC LP3
INC R2 ;商加1
SJMP LP2
LP3: MOV A,R3 ;四舍五人
ADD A,R3
DA A
JC LP4
ADD A,R1
DA A
JNC RETURN1
LP4: MOV A,R2
ADDC A,#00H
DA A
MOV R2,A
RETURN1: MOV OUT_H,#00H
MOV OUT_L,R2
CALL T_CONV
RET
;-----------------------------------------------------
; LCD 初始化设置
;-----------------------------------------------------
SET_LCD:
CLR EN
CALL INIT_LCD ;初始化 LCD
CALL DELAY1
MOV DPTR,#INFO1 ;指针指到显示信息1
MOV A,#1 ;显示在第一行
CALL LCD_SHOW
MOV DPTR,#INFO2 ;指针指到显示信息2
MOV A,#2 ;显示在第二行
CALL LCD_SHOW
RET
;-----------------------------------------------------
INFO1: DB " CALCULATOR ",0 ;LCD 第一行显示信息
INFO2: DB " ",0 ;LCD 第二行显示信息
;----------------------------------------------------
INIT_LCD: ;8位I/O控制 LCD 接口初始化
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
CALL DELAY1
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
CALL DELAY1
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
CALL DELAY1
MOV A,#0CH ;开显示,关光标,
CALL WCOM
CALL DELAY1
MOV A,#01H ;清除 LCD 显示屏
CALL WCOM
CALL DELAY1
RET
;----------------------------------------------------
LCD_SHOW: ;在LCD的第一行或第二行显示信息字符

CJNE A,#1,LINE2 ;判断是否为第一行
LINE1: MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
JMP FILL

LINE2: MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM
FILL: CLR A ;填入字符
MOVC A,@A+DPTR ;由信息区取出字符
CJNE A,#0,LC1 ;判断是否为结束码
RET
LC1: CALL WDATA ;写入数据
INC DPTR ;指针加1
JMP FILL ;继续填入字符
RET
;---------------------------------------------------
CLR_LINE: ;清除该行 LCD 的字符
MOV R0,#24
CL1: MOV A,#' '
CALL WDATA
DJNZ R0,CL1
RET
;-----------------------------------------------------
; 写指令、数据使能子程序
;-----------------------------------------------------
WCOM: ;写指令使能
MOV P0,A
CLR RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲
CLR RW
SETB EN
CALL DELAY0
CLR EN
RET
WDATA: ;写数据使能
MOV P0,A
SETB RS ;RS=H,RW=L,D0-D7=数据,E=高脉冲
CLR RW
SETB EN
CALL DELAY0
CLR EN
RET

DELAY0: MOV R7,#250 ;延时500微秒
DJNZ R7,$
RET
;---------------------------------------------------
;在 LCD 第二行显示字符
;A=ASC DATA, B=LINE X POS
;---------------------------------------------------
LCDP2: ;在LCD的第二行显示字符
PUSH ACC ;
MOV A,B ;设置显示地址
ADD A,#0C0H ;设置LCD的第二行地址
CALL WCOM ;写入命令
POP ACC ;由堆栈取出A
CALL WDATA ;写入数据
RET
;-----------------------------------------------------
;矩阵键盘键值读取子程序
;-----------------------------------------------------
KEY_IN: MOV P1,#0F0H ;置列线为0,行线为1
MOV A,P1
ANL A,#0F0H
MOV B,A
MOV P1,#0FH ;置列线为1,行线为0
MOV A,P1
ANL A,#0FH
ORL A,B ;高四位与低四位重新组合
CJNE A,#0FFH,KEY_IN1 ;0FFH为末按键
CLR 20H.0
RET
KEY_IN1: MOV B,A
MOV DPTR,#KEYTABLE
MOV R3,#0FFH
KEY_IN2: INC R3
MOV A,R3
MOVC A,@A+DPTR
CJNE A,B,KEY_IN3
MOV A,R3 ;找到,取顺序码
MOV R5,#08H ;延时
CALL DELAY
SETB 20H.0
RET
KEY_IN3: CJNE A,#0FFH,KEY_IN2 ;末完,继续查
RET ;0FFH为结束码
;------------------------
;在指定位置显示符合子程序
;------------------------
CONV0:
add A,#30h
MOV B,X
CALL LCDP2
ret
CONV1:
MOV X,#4
MOV A,#2BH ;+
MOV B,X
CALL LCDP2
RET

CONV2:
MOV X,#4
MOV A,#2DH ;-
MOV B,X
CALL LCDP2
RET
CONV3:
MOV X,#4
MOV A,#2AH ;*
MOV B,X
CALL LCDP2
RET
CONV4:
MOV X,#4
MOV A,#2FH ;/
MOV B,X
CALL LCDP2
RET
CONV5:
MOV X,#09H
MOV A,#3DH ;=
MOV B,X
CALL LCDP2
RET
;--------------------------
;
;--------------------------
CONV:
;MOV X,#3 ;设置显示起始位置
MOV A,R3
ANL A,#0FH ;取出低四位二进制数
PUSH ACC ;压入堆栈
CLR C ;C=0
SUBB A,#0AH ;减10
POP ACC ;弹出堆栈
JC ASCII0 ;该数小于10,转ASCII0
JMP ASCII1
;ADD A,#07H ;大于10的数加上37H
ASCII0: ADD A,#30H ;小于10的数加上30H
MOV B,X
CALL LCDP2
ASCII1: ;MOV A,R3
RET

;-------------------------------------------------------
T_CONV:

MOV A,OUT_H ;取高位数
mov x,#11
cjne a,#00h,t_conv1 ;判高位数是否为0?
setb 20h.6 ;为0,20h.6置1
jmp t_conv3 ;转取低位数
;高位数不为0,则
t_conv1: anl a,#0f0h ;判高位数的高四位是否为0?
cjne a,#00h,t_conv2 ;不为0,2位数都显示
setb 20h.6 ;为0,20h.6置1,只显示低四位
t_conv2: mov a,out_h
CALL SHOW_DIG2
inc x
clr 20h.6 ;清显示标记位

t_conv3: mov a,out_l ;取低位数
jnb 20h.6,t_conv5 ;高位数有显示,则不判低位数。
anl a,#0f0h ;高位数无显示,则判低位数。
cjne a,#00h,t_conv4 ;判低位数的高四位是否为0?
setb 20h.6 ;为0,20h.6置1,只显示低四位
MOV A,OUT_L
JMP T_CONV5
T_conv4: CLR 20H.6 ;低位数不为0,2位数都显示
mov a,out_l

t_conv5: call show_dig2
clr 20h.6 ;清显示标记位
RET
;----------------------------
;在 LCD 的第二行显示数字与符号
;----------------------------
SHOW_DIG2:
JNB 20H.5,DIG2 ;符号标记
MOV TEMP3,A
MOV A,#2DH ;显示负号
MOV B,X
CALL LCDP2
MOV A,TEMP3
INC X
DIG2: MOV B,#16 ;设置被除数
DIV AB ;结果A存商数,B存余数
jnb 20h.6,dig3 ;显示位标记
mov a,#20h
jmp dig4
dig3: ADD A,#30H ;A为十位数,转换为字符
dig4: PUSH B ;B放入堆栈暂存
MOV B,X ;设置 LCD 显示的位置
CALL LCDP2 ;由 LCD 显示出来
POP B ;
MOV A,B ;B为个位数
ADD A,#30H ;转换为字符
INC X ;LCD 显示位置加1
MOV B,X ;设置 LCD 显示的位置
CALL LCDP2 ;由 LCD 显示出来
RET
;--------------------------------------------------------
;蜂鸣器响一声子程序
;--------------------------------------------------------
BEEP_BL:
MOV R6,#100
BL1: CALL DEX1
CPL BEEP
DJNZ R6,BL1
MOV R5,#50
CALL DELAY
RET
DEX1: MOV R7,#180
DEX2: NOP
DJNZ R7,DEX2
RET
DELAY: ;延时R5×10MS
MOV R6,#50
D1: MOV R7,#100
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,DELAY
RET
;-----------------------------------------------------
DELAY1: ;延时5MS
MOV R6,#25
D2: MOV R7,#100
DJNZ R7,$
DJNZ R6,D2
RET
;-----------------------------------------------------
KEYTABLE:
DB 0EEH,0EDH,0EBH,0E7H,0DEH ;0,1,2,3,4, 顺序码
DB 0DDH,0DBH,0D7H,0BEH,0BDH ;5,6,7,8,9,
DB 0BBH,0B7H,07EH,07DH,07BH ;A,B,C,D,E,
DB 077H,0FFH ;F 0FF为结束码
;-----------------------------------------------------
END
全部回答
加我
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
房事好久,一个多小时以上,老婆嫌弃时间太长
Business Communication 对生活的影响 跨文化
2016途观和2018翼虎怎么选
猪在短时间内快速增肥有什么办法
玩我的世界本来好好的,最近在MC中乱打指令,
杉杉西服为什么没有自己的专卖店?
灾煞的紫微斗数灾煞星曜
徐静蕾近期有没有上过《快乐大本营》?
OPPOA79图案解锁在哪里
html a标签 怎么变成不能点击
那些女星名字带有空字?
青云剑道怎么手机上进不去
在EXCEL里窗口这个工具栏中不小心点到了新建
奶块我入村成为居民了为什么会有你没有修改村
5年的感情分手了她说没爱了只是习惯还在
推荐资讯
大门口为什么放石头狮子不放老虎
财务凭证装订机现在大多数都是铆管装订类型多
碱为什么能去油污
笔记本机身右下角很烫是怎么回事
有含 上帝的誓约 这个意思的 女名字(多一点
公租房拆迁政策有哪些 公租房拆迁补偿方式有
女生的三围85.5 59.6 87.9是什么样的身材
离职三个月了找不到合适工作,旅游管理专业、
腹部胸部背部肌肉刺痛,偶尔肌肉跳动怎么回事
如何发短信到10086查流量?
贷款十万三年利息是一万二千,它的年利率是多
丽人母婴服务地址好找么,我有些事要过去,
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?