;微电脑带倍率6位数显计数器源程序
;计数脉冲从Int0端输入,
org 0000H
ajmp main
org 0003h
ajmp into
org 0013h
ajmp int01
org 001bh
ajmp tt0
org 0020H
tt0: mov th1,#26h
mov tl1,#0fch
inc 3ah
mov a,#05h
cjne a,3ah,ttk
cpl f0
mov 3ah,#00h
ttk: reti
int01: clr ex0
mov slaw,#0a0h ;将计数值、设定值、倍率值共15个数据写入AT24C04以
;20H单元开始的15个单元中
mov subadr,#20h
mov numbyt,#15
lcall wrnbyt
return: ajmp $
reti
into: clr ex0 ;关int0中断
push psw
push acc
com: clr c
mov a,55h
subb a,50h
jz km1 ;设定值与计数值最高位相等,转KM1比较下一位
jnc kk ;设定值最高位大于计数值最高位,转KK计数值累加
sjmp km3 ;设定值最高位小于计数值最高位,转KM3计数停止,输出位P0。0有效
km1: mov a,56h
subb a,51h
jz km2
jnc kk
ajmp km3
km2: mov a,57h
subb a,52h
jz km3
jnc kk
km3: clr p0.0 ;使输出位有效
clr 20h ;使计数到标志位为零
pop acc
pop psw
reti ;中断返回
ajmp main1
kk: mov r7,#5h
mov r0,#50h
mov r1,#5ah
BCDA: MOV A,R7 ;多字节BCD码加法,计数值与倍率值相加
MOV R2,A
ADD A,R0
MOV R0,A
MOV A,R2
ADD A,R1
MOV R1,A
CLR C
BCD1: DEC R0
DEC R1
MOV A,@R0
ADDC A,@R1
DA A
MOV @R0,A
DJNZ R2,BCD1
pop acc
pop psw
setb ex0 ;开int0中断
reti ;中断返回
org 0090h
vsda equ p0.7
vscl equ p0.6
mtd equ 50h
mrd equ 50h
slaw equ 3fh
slar equ 4fh
numbyt equ 3eh
subadr equ 4eh
main: mov slaw,#0a0h ;将AT24C04中20H单元开始的计数值、设定值、倍率值共15个字节数据读出,
; 放在单片机以50H为首址的15个单元中
mov slar,#0a1h
mov subadr,#20h
mov numbyt,#15
lcall wrnbyt
mov sp,#60H ;设置堆栈指针
mov tmod,#10H ;初始化T1为定时器,工作于方式1
mov th1,#26h
mov tl1,#0fch
setb it0 ;it0=1 ,INT0为边沿触发方式
SETB IT1 ;it1=1 ,INT1为边沿触发方式
mov ip,#01h ;px0=1 INT0定义为高优先级
SETB F0
setb 20h
mov ie,#8dh ;Ex0=1,ex1=1,et1=1,ea=1
mov 3ah,#00h ;T1定时倍数清零
mov 3bh,#00h ;键码清零
mov 3ch,#00h ;AN4键序清零
mov 3dh,#00h ;AN3键序清零
mov 39h,#0ffh ;第二位小数点灭
main1: mov 30h,50h ;计数值显示程序
mov 31h,51h
mov 32h,52h ;装载计数值
mov 3dh,#00h
acall chanf
acall disp ;调用显示子程序,显示计数值
mov a,#04h
cjne a,3bh,an1 ;AN4键未被按下
lcall keyw
inc 3ch ;AN4键序加1
ajmp main2
an1: mov a,#01h
cjne a,3bh,main1 ;AN1键未被按下,继续显示计数值
lcall keyw ;AN1键被按下,计数值清零
mov 50h,#0h
mov 51h,#0h
mov 52h,#0h
mov 53h,#0h
mov 54h,#0h
jb 20h,an11
setb ex0 ;开中断
setb p0.0 ;置P0。0为高电平
setb 20h
an11: ajmp main1
main2: SETB TR1 ;开启定时器1
mov 30h,55h ;显示设定值
mov 31h,56h
mov 32h,57h
mov 3dh,#01h
acall chanf ;调用BCD码地址分配程序
main2a: acall disp ;调用显示子程序
mov a,#04h
cjne a,3bh,dx0 ;AN4键第二次被按下吗?没有,转DX0
lcall keyw
inc 3ch
ajmp main3 ;AN4键第二次被按下,转倍率设定程序
dx0: mov a,#03h
cjne a,3bh,set1
lcall keyw ;AN3键被按下
inc 3dh ;AN3键序加1
mov a,#07h
cjne a,3dh,set1
mov 3dh,#01h
set1: acall dset
ajmp main2a
main3: mov a,48h ;把设定值以BCD码形式存入55H、56H、57H
swap a
orl a,47h
mov 57h,a
mov a,4ah
swap a
orl a,49h
mov 56h,a
mov a,4ch
swap a
orl a,4bh
mov 55h,a
mov 30h,5ch ;倍率设定程序
mov 31h,5dh ;装载倍率值
mov 32h,5eh
mov 3dh,#02h ;AN3键序初始化为02
mov 39h,#7fh ;第二位小数点亮
acall chanf
main3a: acall disp
mov a,#04h
cjne a,3bh,dxx0 ;AN4键第三次被按下吗?没有,转DXX0
lcall keyw
inc 3ch
ajmp main4 ;AN4键第三次被按下,转数据存贮程序
dxx0:
mov a,#03h
cjne a,3bh,set2
lcall keyw ;AN3键被按下
inc 3dh ;AN3键序加1
mov a,#07h
cjne a,3dh,set2
mov 3dh,#02h
set2: acall dset
ajmp main3a
main4: mov 39h,#0ffh ;第二位小数点灭
clr tr1 ;关定时器1
setb f0 ;置F0为1
mov a,48h ;把倍率值以BCD码形式存入5aH--5EH
swap a
orl a,47h
mov 5eh,a
mov a,4ah
swap a
orl a,49h
mov 5dh,a
mov a,4bh
mov 5ch,a
mov 5bh,#0h
mov 5ah,#0h
mov slaw,#0a0h ;将50H-5EH共15个数据写入AT24C04以20H单元开始的15个单元中
mov subadr,#20h
mov numbyt,#15
lcall wrnbyt
ajmp main1
chanf: mov a,32h ;BCD码显示用地址分配程序
anl a,#0FH
mov 47h,a
mov a,32h
swap a
anl a,#0FH
mov 48h,a
mov a,31h
anl a,#0FH
mov 49h,a
mov a,31h
swap a
anl a,#0FH
mov 4ah,a
mov a,30h
anl a,#0FH
mov 4bh,a
mov a,30h
swap a
anl a,#0Fh
mov 4ch,a
ret
disp: ;显示子程序
mov dptr,#tab
mov a,47h ;显示左起第6位(个位)
mov r3,3dh
cjne r3,#06h,dd1 ;AN3键序不为6,直接显示该位值
dk1: jb F0,DD1 ;F0为1,显示该位值
mov a,#0ffh ;F0为0,该位不显示,以达到该位闪烁效果
sjmp dd2
dd1: movc a,@a+dptr
dd2: mov p1,a ;送段码
clr p2.0 ;开个位
jb p2.7,dsp1 ;未按键转下一位(十位)
acall del1
jb p2.7,dsp1
ajmp key1 ;按键转置AN1键码
dsp1: acall dll
d1: setb p2.0
mov a,48h ;显示左起第5位(十位)
mov r3,3dh
cjne r3,#05h,dd3
dk2: jb F0,DD3
mov a,#0ffh
sjmp dd4
dd3: movc a,@a+dptr
dd4: mov p1,a
clr p2.1
jb p2.7,dsp2
acall del1
jb p2.7,dsp2
ajmp key2
dsp2: acall dll
d2: setb p2.1
mov a,49h
mov r3,3dh
cjne r3,#04h,dd5
dk3: jb F0,DD5
mov a,#0ffh
sjmp dd6
dd5: movc a,@a+dptr
dd6: mov p1,a
clr p2.2
jb p2.7,dsp3
acall del1
jb p2.7,dsp3
ajmp key3
dsp3: acall dll
d3: setb p2.2
mov a,4ah
mov r3,3dh
Cjne r3,#03h,dd7
dk4: jb F0,DD7
mov a,#0ffh
sjmp dd8
dd7: movc a,@a+dptr
dd8: mov p1,a
clr p2.3
jb p2.7,dsp4
acall del1
jnb p2.7,key4
dsp4: acall dll
d4: setb p2.3
mov a,4bh
mov r3,3dh
cjne r3,#02h,dd9
dk5: jb F0,DD9
mov a,#0ffh
sjmp dd10
dd9: movc a,@a+dptr
dd10: anl a,39h
mov p1,a
clr p2.4
acall dll
setb p2.4
mov a,4ch
mov r3,3dh
cjne r3,#01h,dd11
dk6: jb F0,DD11
mov a,#0ffh
sjmp dd12
dd11: movc a,@a+dptr
dd12: mov p1,a
clr p2.5
acall dll
setb p2.5
ret
key1: mov 3bh,#01h ;保存AN1键码
ajmp d1
key2: mov 3bh,#02h
ajmp d2
key3: mov 3bh,#03h
ajmp d3
key4: mov 3bh,#04h
ajmp d4
keyw: mov 3bh,#00h ;键等待释放程序
lcall disp
mov a,3bh
jnz keyw
lcall disp
mov a,3bh
jnz keyw
ret
dset: mov r3,3dh ;设定子程序
cjne r3,#01h,dx2 ;AN3键序不为1,转DX2
mov r4,3bh
cjne r4,#02h,dx11 ;AN3键序为1,但AN2键未被按下
lcall keyw ;AN2键被按下,等待键释放
inc 4ch ;第一位的数值被更改(加1)
mov r5,4ch
cjne r5,#0ah,dx11 ;使该位的数值可在0--9之间随意设定
mov 4ch,#00h
dx11: ajmp dx
dx2: mov r3,3dh
cjne r3,#02h,dx3
mov r4,3bh
cjne r4,#02h,dx12
lcall keyw
inc 4bh
mov r5,4bh
cjne r5,#0ah,dx12
mov 4bh,#00h
dx12: ajmp dx
dx3: cjne r3,#03h,dx4
mov r4,3bh
cjne r4,#02h,dx13
lcall keyw
inc 4ah
mov r5,4ah
cjne r5,#0ah,dx13
mov 4ah,#00h
dx13: ajmp dx
dx4: cjne r3,#04h,dx5
mov r4,3bh
cjne r4,#02h,dx14
lcall keyw
inc 49h
mov r5,49h
cjne r5,#0ah,dx14
mov 49h,#00h
dx14: ajmp dx
dx5: cjne r3,#05h,dx6
mov r4,3bh
cjne r4,#02h,dx15
lcall keyw
inc 48h
mov r5,48h
cjne r5,#0ah,dx15
mov 48h,#00h
dx15: ajmp dx
dx6: cjne r3,#06h,dx
mov r4,3bh
cjne r4,#02h,dx16
lcall keyw
inc 47h
mov r5,47h
cjne r5,#0ah,dx16
mov 47h,#00h
dx16: ajmp dx
dx: acall disp ;调用显示子程序
ret
dll: MOV R7,#01fH
DL1: MOV R6,#1fH
DL2: DJNZ R6,DL2
DJNZ R7,DL1
RET
DEL1: MOV R7,#0aH
DEL1A: MOV R6,#2eH
DEL1B: DJNZ R6,DEL1B
DJNZ R7,DEL1A
RET
DEL2: MOV R7,#0AH
DEL2A: MOV R6,#2DH
DEL2B: DJNZ R6,DEL2B
DJNZ R7,DEL2A
RET
tab: DB 0C0H,0F9H,0A4H,0B0H
DB 99H,92H,82H,0F8H
DB 80H,90H
StA: setb vsda ;I2C读写程序模块,启动I2C总线
SETB VSCL
NOP
NOP
CLR VSDA
NOP
NOP
CLR VSCL
RET
STOP: CLR VSDA ;停止I2C总线
SETB VSCL
NOP
NOP
SETB VSDA
NOP
NOP
CLR VSCL
RET
MACK: CLR VSDA ;快速应答位
SETB VSCL
NOP
NOP
CLR VSDA
SETB VSCL
RET
MNACK: SETB VSDA ;发送非应答位
SETB VSCL
NOP
NOP
CLR VSCL
CLR VSDA
RET
CACK: SETB VSDA ;应答位检查
SETB VSCL
CLR F0
MOV C,VSDA
JNC CEND
SETB F0
CEND: CLR VSCL ;子程序结束,使VSCL=0
NOP
RET
WRBYT: MOV R0,#08H ;发送一个数据字节
WLP: RLC A
JC WR1
AJMP WR00
WLP1: DJNZ R0,WLP
RET
WR1: SETB VSDA
SETB VSCL
NOP
NOP
CLR VSCL
CLR VSDA
AJMP WLP1
WR00: CLR vsda ;发送“0”程序段
SETB VSCL
NOP
NOP
CLR VSCL
AJMP WLP1
RDBYT: MOV R0,#08H ;从SDA线上读取一个数据字节,8位数据长度入R0
RLP: SETB vsda ; 置 VSDA为输入方式
SETB VSCL ; 使VSDA上数据有效
MOV C,vsda
RLC A
CLR VSCL ;使VSCL=0,可继续接受数据位
MOV R2,#10H
DJNZ R2,$
DJNZ R0,RLP ;8位读完否?未完转RLP
RET
WRNBYT: MOV R3,NUMBYT ;发送几个字节数据
LCALL STA
END