源程序:
;*************************************************************
;*me300b单片机开发系统演示程序*
;**
;*红外遥控式简单计算器演示程序*
;*用红外遥控器做输入(适用新式遥控器)*
;**
;*lcd1602显示方式:*
;*lcd第一行显示:calculator*
;*lcd第二行显示:运算过程*
;**
;*主要功能:*
;*0-99两位数之间的加、减、乘、除整数运算*
;**
;***********************************************************
;k1为清零键
;数字键:0,1,2,3,4,5,6,7,8,9
;功能键:+,-,*,/,=
;-------------------------------
relayequp1.3
beepequp3.7
irinequp3.2
;-------------------------------
lcd_rsequp2.0
lcd_rwequp2.1
lcd_enequp2.2
lcd_xequ3fh;lcd地址变量
;-------------------------------
temp1equ30h;临时暂存器
temp2equ31h
temp3equ32h
temp4equ33h
res_hequ27h;输入被加(减、乘、除)数
res_lequ28h;输入加(减、乘、除)数
out_hequ29h;运算结果高位
out_lequ2ah;运算结果低位
ircomequ22h;22h-25hir使用
;-------------------------------
org0000h
jmpmain
org0030h
;-------------------------------
main:movsp,#60h
movr1,#00h
movtemp1,#00h
movtemp2,#00h
movtemp3,#00h
movres_l,#00h
movres_h,#00h
movout_h,#00h
movout_l,#00h
mov20h,#00h
callset_lcd
main1:callir_in;大于9的数无效
jnb20h.0,main1
subba,#0ah
jncmain1;c=0,无借位
mova,r3;重装键值
jmploop_0
loop:
callir_in;送被(加、减、乘、除)数
jnb20h.0,loop;键标记
loop_0:
incr1
cjner1,#01h,loop_1
movtemp2,a;高位
movlcd_x,#2
callconv0
loop_1:cjner1,#02h,loop
subba,#0ah;判是否是功能键?
jncloop_2;是,转loop_2
movtemp1,temp2
mova,temp1
movlcd_x,#1
callconv0
mova,r3;恢复有效键值
movtemp2,a;低位
movlcd_x,#2
callconv0
mova,temp1
anla,#0fh
swapa
orla,temp2
movres_h,a
jmploop0
loop_2:
movres_h,temp2
ajmploop0a
loop0:callir_in
jnb20h.0,loop0
loop0a:mova,r3;重装键值
cjnea,#0ah,loop1;加运算
callconv1
setb20h.1;加运算标记
ajmploop5
loop1:cjnea,#0bh,loop2;减运算
callconv2
setb20h.2;减运算标记
ajmploop5
loop2:cjnea,#0ch,loop3;乘运算
callconv3
setb20h.3;乘运算标记
ajmploop5
loop3:cjnea,#0dh,loop4;除运算
callconv4
setb20h.4;除运算标记
ajmploop5
loop4:cjnea,#0fh,loop4a
ajmpmain
loop4a:ajmploop0
loop5:movr1,#00h
movtemp1,#00h
movtemp2,#00h
clr20h.0;送(加、减、乘、除)数
loop5a:callir_in
jnb20h.0,loop5a
;callbeep_bl
cjnea,#0fh,loop5b
ajmpmain
loop5b:incr1
cjner1,#01h,loop5c
movtemp2,a
movlcd_x,#6
callconv0
loop5c:cjner1,#02h,loop5a
subba,#0ah;判是否是功能键?
jncloop5d;是,转loop5c
movtemp1,temp2
mova,temp1
movlcd_x,#6
callconv0
mova,r3
movtemp2,a
movlcd_x,#7
callconv0
mova,temp1
anla,#0fh
swapa
orla,temp2
movres_l,a
jmploop6
loop5d:movres_l,temp2
jmploop6a
loop6:callir_in
loop6a:mova,r3;重装键值
cjnea,#0fh,loop6b
ajmpmain
loop6b:cjnea,#0eh,loop6;显示(=)
callconv5;显示运算结果
;callbeep_bl
jnb20h.1,loop6c
callsuadd
loop6c:jnb20h.2,loop6d
callsusub
loop6d:jnb20h.3,loop6e
callsumul
loop6e:jnb20h.4,loop7
callsudiv
loop7:callir_in
cjnea,#0fh,loop7;复位(清零)
ajmpmain
;---------------------------------------------------
;ir译码子程序
;出口:a、r3存键值
;---------------------------------------------------
ir_in:
movr0,#ircom
i1:jnbirin,i2;等待ir信号出现
jmpi1
i2:movr4,#20
i20:calldel
djnzr4,i20
jbirin,i1;确认ir信号出现
i21:jbirin,i3;等ir变为高电平
calldel
jmpi21
i3:movr3,#0;8位数清为0
ll:jnbirin,i4;等ir变为低电平
calldel
jmpll
i4:jbirin,i5;等ir变为高电平
calldel
jmpi4
i5:movr2,#0;0.14ms计数
l1:calldel
jbirin,n1;等ir变为高电平
;ir=0,检查r2中的计数值
mova,#8
clrc
subba,r2;判断高低位
;ifc=0bit=0
mova,@r0
rrca
mov@r0,a;处理完一位
incr3
cjner3,#8,ll;需处理完8位
movr3,#0
incr0
cjner0,#ircom+4,ll;收集到4字节了
;jmpok
jmpir_show
n1:incr2
cjner2,#30,l1;0.14ms计数过长则时间到自动离开
ok:ret
;--------------------------------------------------------------------
ir_show:
mova,ircom+3
cpla;将25h取反后和24h比较
cjnea,ircom+2,ir_show1;如果不等表示接收数据发生错误,放弃。
setb20h.0;解码成功20h.0置1。
mova,ircom+2
movb,a
movdptr,#ir_table_new
movr3,#0ffh
ir_in1:incr3
mova,r3
movca,@a+dptr
cjnea,b,ir_in2
mova,r3;找到,取顺序码
callbeep_bl;蜂鸣器鸣响表示解码成功
ret
ir_in2:cjnea,#0ffh,ir_in1;末完,继续查
ir_show1:ret
;---------------------------------------------------------
;红外遥控器键值码
;---------------------------------------------------------
ir_table_new:
db40h,48h,04h,00h,02h,05h,54h,4dh,0ah,1eh
db09h,1fh,17h,16h,4ch,10h,0ffh
;ir_table:
;db1bh,10h,03h,01h,06h,09h,1dh,1fh,0dh,19h
;db1ch,14h,0fh,0ch,40h,04h,0ffh
;---------------------------------------------------------
;delayr5*0.14ms
del:
movr5,#1;ir解码使用
del0:movr6,#2
del1:movr7,#32
del2:djnzr7,del2
djnzr6,del1
djnzr5,del0
ret
;------------------------
;加法运算子程序
;入口:r0-被加数,r1-加数
;出口:r4(高)、r2(低)为和值
;------------------------
suadd:
movr1,res_l
movr0,res_h
mova,r0
adda,r1
daa
movr2,a
clra
addca,#00h
movr4,a
movout_h,r4
movout_l,r2
callt_conv
ret
;------------------------
;减法运算子程序
;入口:r0-被减数,r1-减数
;出口:r2-差值
;------------------------
susub:
movr1,res_l
movr0,res_h
clrc
mova,#9ah
subba,r1;减数十进制求补
adda,r0
daa
movr2,a;差值送r2
jcposi;c=1,表示差值为正
nega:mova,#9ah;差值为负,求补后得差值的绝对值
subba,r2
movr2,a
setb20h.5;显示负号标记
posi:movout_h,#00h
movout_l,r2
callt_conv
ret
;-------------------------
;乘法运算子程序
;单字节bcd码乘法子程序
;入口:r0(被乘数)、r1(乘数)
;出口:r3(高)、r2(低),积为双字节,bcd码形式的积
;从乘数高位开始进行bcd码移位乘法
;-------------------------
sumul:
movr1,res_l
movr0,res_h
bcdmul:
clra;积单元清零
movr2,a
movr3,a
mova,r1
jzreturn
anla,#0f0h;取乘数高位
jzlbcd;乘数高位是否为0?
swapa
movr4,a
acallddbcdm
swapa;bcd码左移一位
movr3,a
mova,r2
swapa
movr2,a
anla,#0fh
orla,r3
movr3,a
mova,r2
anla,#0f0h
movr2,a
lbcd:mova,r1;取乘数低位
anla,#0fh
jzreturn;乘数低位是否为0?
movr4,a
acallddbcdm
return:movout_h,r3
movout_l,r2
callt_conv
ret
ddbcdm:;一位bcd码乘法
mova,r2
adda,r0
daa
movr2,a
mova,r3
addca,#00h
daa
movr3,a
djnzr4,ddbcdm
ret
;------------------------------------------------
;除法运算子程序
;单字节bcd码除法
;入口:r0(被除数)、r1(非零除数)
;出口:r2(商)、r3(余数)
;《mcs-51系列单片机实用子程序集锦》page73
;-----------------------------------------------
sudiv:
movr1,res_l
movr0,res_h
bcddiv:
movr2,#00h;商单元清零
mova,r1;除数求补
cpla
adda,#9bh
movr1,a
mova,r0;被除数高位移入
anla,#0f0h;部分余单元
swapa
lp0:movr3,a;做除法
adda,r1
daa
jnclp1;部分余数>=除数?
incr2;商加1
sjmplp0
lp1:mova,r3;
swapa
movr3,a
mova,r2;商左移一位
swapa
movr2,a
mova,r0;移位
anla,#0fh
orla,r3
lp2:movr3,a;做除法
adda,r1
daa
jnclp3
incr2;商加1
sjmplp2
lp3:mova,r3;四舍五人
adda,r3
daa
jclp4
adda,r1
daa
jncreturn1
lp4:mova,r2
addca,#00h
daa
movr2,a
return1:movout_h,#00h
movout_l,r2
callt_conv
ret
;-----------------------------------------------------
;lcd初始化设置
;-----------------------------------------------------
set_lcd:
clrlcd_en
callinit_lcd;初始化lcd
calldelay1
movdptr,#info1;指针指到显示信息1
mova,#1;显示在第一行
calllcd_show
movdptr,#info2;指针指到显示信息2
mova,#2;显示在第二行
calllcd_show
ret
;-----------------------------------------------------
info1:dbcalculator,0;lcd第一行显示信息
info2:db,0;lcd第二行显示信息
;----------------------------------------------------
init_lcd:;8位i/o控制lcd接口初始化
mova,#38h;双列显示,字形5*7点阵
callwcom
calldelay1
mova,#38h;双列显示,字形5*7点阵
callwcom
calldelay1
mova,#38h;双列显示,字形5*7点阵
callwcom
calldelay1
mova,#0ch;开显示,关光标,
callwcom
calldelay1
mova,#01h;清除lcd显示屏
callwcom
calldelay1
ret
;----------------------------------------------------
lcd_show:;在lcd的第一行或第二行显示信息字符
cjnea,#1,line2;判断是否为第一行
line1:mova,#80h;设置lcd的第一行地址
callwcom;写入命令
callclr_line;清除该行字符数据
mova,#80h;设置lcd的第一行地址
callwcom;写入命令
jmpfill
line2:mova,#0c0h;设置lcd的第二行地址
callwcom;写入命令
callclr_line;清除该行字符数据
mova,#0c0h;设置lcd的第二行地址
callwcom
fill:clra;填入字符
movca,@a+dptr;由信息区取出字符
cjnea,#0,lc1;判断是否为结束码
ret
lc1:callwdata;写入数据
incdptr;指针加1
jmpfill;继续填入字符
ret
;---------------------------------------------------
clr_line:;清除该行lcd的字符
movr0,#24
cl1:mova,#''
callwdata
djnzr0,cl1
ret
;-----------------------------------------------------
;写指令子程序
;rs=l,rw=l,d0-d7=指令码,e=高脉冲
;-----------------------------------------------------
wcom:
movp0,a
clrlcd_rs
clrlcd_rw
setblcd_en
calldelay0
clrlcd_en
ret
;-----------------------------------------------------
;写数据子程序
;rs=h,rw=l,d0-d7=数据,e=高脉冲
;-----------------------------------------------------
wdata:
movp0,a
setblcd_rs
clrlcd_rw
setblcd_en
calldelay0
clrlcd_en
ret
;-----------------------------------------------------
;延时250微秒
;-----------------------------------------------------
delay0:
movr7,#125
djnzr7,$
ret
;---------------------------------------------------
;在lcd第二行显示字符
;a=ascdata,b=linexpos
;---------------------------------------------------
lcdp2:
pushacc;
mova,b;设置显示地址
adda,#0c0h;设置lcd的第二行地址
callwcom;写入命令
popacc;由堆栈取出a
callwdata;写入数据
ret
;------------------------
;在指定位置显示运算数字与符号子程序
;------------------------
conv0:
adda,#30h
movb,lcd_x
calllcdp2
ret
conv1:
movlcd_x,#4
mova,#2bh;+
movb,lcd_x
calllcdp2
ret
conv2:
movlcd_x,#4
mova,#2dh;-
movb,lcd_x
calllcdp2
ret
conv3:
movlcd_x,#4
mova,#2ah;*
movb,lcd_x
calllcdp2
ret
conv4:
movlcd_x,#4
mova,#2fh;/
movb,lcd_x
calllcdp2
ret
conv5:
movlcd_x,#09h
mova,#3dh;=
movb,lcd_x
calllcdp2
ret
;--------------------------
;
;--------------------------
conv:
movlcd_x,#3;设置显示起始位置
mova,r3
anla,#0fh;取出低四位二进制数
pushacc;压入堆栈
clrc;c=0
subba,#0ah;减10
popacc;弹出堆栈
jcascii0;该数小于10,转ascii0
;jmpascii1
adda,#07h;大于10的数加上37h
ascii0:adda,#30h;小于10的数加上30h
movb,lcd_x
calllcdp2
ascii1:;mova,r3
ret
;-------------------------------------------------------
t_conv:
mova,out_h;取高位数
movlcd_x,#11
cjnea,#00h,t_conv1;判高位数是否为0?
setb20h.6;为0,20h.6置1
jmpt_conv3;转取低位数
;高位数不为0,则
t_conv1:anla,#0f0h;判高位数的高四位是否为0?
cjnea,#00h,t_conv2;不为0,2位数都显示
setb20h.6;为0,20h.6置1,只显示低四位
t_conv2:mova,out_h
callshow_dig2
inclcd_x
clr20h.6;清显示标记位
t_conv3:mova,out_l;取低位数
jnb20h.6,t_conv5;高位数有显示,则不判低位数。
anla,#0f0h;高位数无显示,则判低位数。
cjnea,#00h,t_conv4;判低位数的高四位是否为0?
setb20h.6;为0,20h.6置1,只显示低四位
mova,out_l
jmpt_conv5
t_conv4:clr20h.6;低位数不为0,2位数都显示
mova,out_l
t_conv5:callshow_dig2
clr20h.6;清显示标记位
ret
;----------------------------
;在lcd的第二行显示数字与符号
;----------------------------
show_dig2:
jnb20h.5,dig2;符号标记
movtemp3,a
mova,#2dh;显示负号
movb,lcd_x
calllcdp2
mova,temp3
inclcd_x
dig2:movb,#16;设置被除数
divab;结果a存商数,b存余数
jnb20h.6,dig3;显示位标记
mova,#20h
jmpdig4
dig3:adda,#30h;a为十位数,转换为字符
dig4:pushb;b放入堆栈暂存
movb,lcd_x;设置lcd显示的位置
calllcdp2;由lcd显示出来
popb;
mova,b;b为个位数
adda,#30h;转换为字符
inclcd_x;lcd显示位置加1
movb,lcd_x;设置lcd显示的位置
calllcdp2;由lcd显示出来
ret
;--------------------------------------------------------
;蜂鸣器响一声子程序
;--------------------------------------------------------
beep_bl:
movr6,#100
bl1:calldex1
cplbeep
djnzr6,bl1
movr5,#10
calldelay
ret
dex1:movr7,#180
dex2:nop
djnzr7,dex2
ret
;-----------------------------------------------------
;延时r5×10ms
;-----------------------------------------------------
delay:
movr6,#50
d1:movr7,#100
djnzr7,$
djnzr6,d1
djnzr5,delay
ret
;-----------------------------------------------------
;延时5ms
;-----------------------------------------------------
delay1:
movr6,#25
d2:movr7,#100
djnzr7,$
djnzr6,d2
ret
;-----------------------------------------------------
end
锂盐电解质:为高能量密度电池保驾护航
开关电源设计常用公式
RS232通信时怎么处理错误?RS232通信中的错误处理方法
大数据:疫情发生倒逼产业发展提速
基于ADAS系统中77/79GHz汽车防撞雷达的潜在增长
ME300实例-1602LCD显示红外遥控计算器
区块链技术在溯源系统中到底有什么用
【技术科普】四大主流芯片架构及其主要优势!
一种温控开关寿命测试仪的设计方案
iphone8最新消息,屏幕下指纹传感器制造遇阻,发布日期或再次后延?
跑步蓝牙耳机牌子的好,最适合跑步用的蓝牙耳机
差压传感器MS5534C的应用优势
魅蓝S6参数配置详解,3+32GB只需999元
微软win10开始菜单大变样
求推荐一款打游戏的无线耳机?2020游戏无线耳机推荐
一文详解CAN数据帧格式
双极步进电机和单极步进电机之间差异
QD0325-C导尿管强度测试仪
代码覆盖率工具的重要性
高耐久低成本的NRAM是如何铸就的?