8段数码管显示.两位数码管显示00--99依次循环(动态扫描方式).p1做LED显示数据输出口.p3.2;p3.3分别控制数码管个位数和十位数显示.
8段数码管从内部接线上分共阳和共阴两种。在电路设计时应根据情况决定采用共阳或共阴,其基本原则是:若单片机IO口直接驱动数码管个段,最好采用共阳数码管,因为51单片机IO口输出高电平时输出的电流很小,数码管不会太亮;若数码管是通过驱动芯片与单片机相连的,就要看驱动芯片对数码管极性的要求啦。下面的实验采用共阳数码管。
;======================================= ;constant define ;常数定义 csp equ 60h ;堆栈开始使用的位置. ;======================================= ;variable define ;变量定义 vadigit equ 30h ;数码管个位数存放内存位置 vbdigit equ 31h ;数码管十位数存放内存位置 vcnt1 equ 32h ;计数器数值存放内存位置
;======================================= ;Func: 程序开始. ;======================================= org 0000h ajmp main
org 0030h ;到0030h处避开00-30h的敏感地址 ;======================================= ;Func: 程序初始化. ;======================================= main: ;初始化特殊寄存器及变量 mov sp,#csp ;指定堆栈开始使用的位置. star: mov vcnt1,#0 ;初始化计数器,从0开始 lop1: acall display ;调用显示子程序 inc vcnt1 ;对计数器加1 mov a,vcnt1 cjne a,#100,lop1 ;判断计数器是否满100? mov vcnt1,#0 ;满100就清零重新开始 ljmp lop1 ;不满就循环执行
;======================================= ;Func: 8.字型LED显示子程序 ;Input: vcnt1 ;======================================= display: mov a,vcnt1 ;将temp中的十六进制数转换成10进制 mov b,#10 ;10进制/10=10进制 div ab ;a除以b,商在a,余数在b. mov vbdigit,a ;十位在a mov vadigit,b ;个位在b mov dptr,#digittab ;指定查表起始地址 mov r0,#4 dpl1: mov r1,#250 ; dplop: mov a,vadigit ;取个位数 movc a,@a+dptr ;查个位数的7段代码 mov p1,a ;送出个位的7段代码 clr p3.2 ;开个位显示 acall delayus ;显示162微秒 setb p3.2 ;关闭个位显示,防止鬼影 mov a,vbdigit ;取十位数 movc a,@a+dptr ;查十位数的7段代码 mov p1,a ;送出十位的7段代码 clr p3.3 ;开十位显示 acall delayus ;显示162微秒 setb p3.3 ;关闭十位显示,防止鬼影 djnz r1,dplop ;循环执行250次 djnz r0,dpl1 ;循环执行250X4=1000次 ret
;======================================= ;Func: 162us延时子程序 ;======================================= delayus: mov r7,#80 ;///2+2X80=162微秒,延时按11.0592MHZ计算 djnz r7,$ ret
org 0600h ;======================================= digittab: ;实验板上的7段数码管0~9数字的共阳显示代码 db 0c0h;0 db 0f9h;1 db 0a4h;2 db 0b0h;3 db 099h;4 db 092h;5 db 082h;6 db 0f8h;7 db 080h;8 db 090h;9 end |