⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 计数器源程序.asm

📁 用单片机制作的高精度计数器
💻 ASM
字号:
;微电脑带倍率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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -